Copyright © Cay S. Horstmann 2010, 2012 
This work is licensed under a Creative Commons
Attribution-Noncommercial-Share Alike 3.0 United States License.
hg
init).hgignore, hg add, hg remove)hg commit -m
"...")hg serve, point
browser to http://localhost:8000)hg clone, hg
push, hg pull)hg update, hg merge) and
resolve conflictsEstimated time: Two 40-minute sessions
sudo apt-get install openssh-client mercurial
(or the equivalent for your distro)
Then open a terminal window and run
sudo port install mercurial
This will take a long time—that's ok.
Select it for installation by clicking on the circle next to Skip. A version number will appear.
Don't click Next yet. Locate openssh and select it for installation in the same way.
Click Next and wait for the installation to complete.
To test that your installation was successful, open a terminal window and type
hg --version
If you get a version number and copyright notice, the installation was successful.
~/.hgrc (that is a file with the five-character
name .hgrc in the home directory ~). Be sure to
remember the dot at the start of the file name.
Windows users: Remember that ~ is
c:\cygwin\home\yourname in the Windows file system.
Windows users: Don't type ~ in EmacsW32. It
interprets it as the Emacs home directory.
Add these lines:
[ui] username=Your name <username@mailserver.com> merge=internal:merge
(of course, replacing Your name with your name and
username@mailserver.com with your email address).
ls ~/.ssh
If you get a directory listing showing (among others) a file
id_rsa.pub, then skip to step 5.
Otherwise run
ssh-keygen -t rsa -C "Your name <username@mailserver.com>"
(of course, replacing Your name with your name and
username@mailserver.com with your email address). When
prompted for a passphrase, you can enter a passphrase, which is more
secure, but you have to enter it whenever you use the key. Or just hit
Enter to skip this.
Do not change the name of the key that is being generated. It
should be id_rsa.
cat ~/.ssh/id_rsa.pub
Copy the text (starting with ssh-rsa and ending with
Your name <username@mailserver.com> and paste it into an
email message to your instructor. This key is needed to allow you access to
the Mercurial server (in Step E).
A version control system remembers the changes that you made to the files in a project. This is useful (even essential) for two reasons:
The database that contains the changes to a project is called a repository. When you interact with a version control system, you contribute your changes to a repository, fetch the latest changes that are contributed by others, or occasionally undo some changes.
Many version control systems are in common use. In this lab, you will learn about a modern version control system called Mercurial. Mercurial is particularly well suited for learning about version control systems. It is so easy to use that it is painless to set up a local repository on your hard disk, but it scales to extremely large projects. For example, the source code for the Java development kit is contained in a very large Mercurial repository.
Open a terminal window and use the cd command to change to
the directory containing the project. (That is, the directory containing
the src and nbproject subdirectories.)
Using a text editor (not Notepad!), create a file .hgignore
in that directory with the following contents.
syntax: glob build dist nbproject build.xml manifest.mf
Now run
hg init hg status
What output do you get?
hg command interacts with a Mercurial repository. (Hg is
the chemical symbol for the element
Mercury.)
The hg init command initializes a repository. You
issue it once when you start a project, or when you decide to add version
control to an existing project.
The hg status command shows the current status of the files
in your project. At the beginning, you get a listing such as
? .hgignore ? src/AddressBook.java ? src/AddressBookDemo.java ? src/ArrayListAddressBook.java ? src/ConsoleInOut.java ? src/InOut.java ? src/Item.java ? src/WindowInOut.java
The ? indicates that these files are unmanaged.
Tell Mercurial that you want to add them:
hg add
This command adds all files in all subdirectories that are not excluded
in the .hgignore file.
Now run hg status again. What output do
you get?
Occasionally, you need to remove files and tell Mercurial
that you don't want them to be a part of your project anymore. Then you use
the hg remove command. The moral is: Mercurial doesn't
automatically manage every file in your project directory. You tell it
which ones you want to save.
A next to each file means that these files will be added
when you make the next “commit” to the repository. Do it now:
hg commit -m "initial checkin"
The -m option is required. Put a brief message describing
the reason for the commit. (You usually commit after adding a feature or
fixing a bug.)
Some people like to put longer commit comments, describing the commited change in detail. That is best done from an IDE—see Part C.
Now run hg status again. What output do
you get?
hg status has nothing to report, then all files are
up-to-date.
Edit the file src/AddressBook.java in NetBeans. Make
some change; for example, remove the first javadoc comment. Save the
file.
Now run hg status again. What output do
you get?
M indicates that the file has been changed and is
different from the version in the repository.
Run hg commit again. Now the repository contains both the
original version and your latest changes.
To see the difference between them, run
hg serve
and point your web browser to http://localhost:8000.
What happens?
src/AddressBook.java file.
How can you get it without the line numbers?
If you ever need the old file back, you can copy/paste it
from the browser, or you can use the Mercurial revert command.
That is more convenient inside NetBeans—see section C.
You have just seen one reason to use a version control system: To get an old version of a file back. It's as if your file system had an undo button!
(But remember, you must enable the undo by periodically running hg
commit. You can only revert to committed versions.)
Hit Ctrl + C to stop the hg serve process.
find
You will see the src subdirectory containing your files,
and next to it, a .hg directory containing the repository
data.
Windows users need to install a separate Mercurial implementation from http://bitbucket.org/tortoisehg/thg-winbuild/downloads/ before this part of the lab. Just download and run the installer. (Unfortunately, NetBeans does not work with the Mercurial program in Cygwin.)

If not, try these things:
hg
executable, c:\Program Files\Mercurial on Windows or
/opt/local/bin on the MacIf all else fails, ask your lab assistant or instructor for help.
@author). Save your file and look at the Projects tab.
What do you notice about the file name?

It lists the file(s) that have changed and you can type a commit message that is as detailed as you like.
Type an appropriate message and click Commit.
When you add files, they show up in green. NetBeans
automatically issues an hg add before committing them.
Once in a while, you may want to know how one of your local files differs from the repository.
Make a change to InOut.java, such as adding a comment explaining the purpose of the interface. Then right-click on the file in the Projects tab and select Mercurial -> Diff. You will see a graphical display of the differences.

How do you get back an older version?
(Try it out. First commit the current version, just in case you mess up, then try reverting to an older one.)
As a rule of thumb, it is a good idea to use the command
line for “big ticket” commands, such as hg init
and hg clone. (Lots of things can go wrong with these, and the
IDE often hides the error messages, making it hard to diagnose what is
going on.) Common commands such as hg commit and hg
revert are most convenient in the IDE.
hg clone . /path/to/USBStick/lab5
(assuming you are still in the lab5 project directory;
otherwise type hg clone /path/to/courseDirectory/lab5
/path/to/USBStick/lab5).
The path to the USB stick depends on your operating system.
/media/someName or /media/sdf1 or
something similar (try ls /media to see your choices)/Volumes/someName or /Volumes/NO\ NAME
(try ls /Volumes to see your choices)/cygdrive/someLetter such as
/cygdrive/e (try ls /cygdrive to see your
choices)Then verify that a lab5 directory has been created on the
USB stick.
This directory is now a “clone” of your project.

First, your fellow developers need a copy of the master.
Inserts the USB stick into your buddy's laptop.
Clone the repository onto that laptop:
hg clone /path/toUSBStickOnBuddyLaptop/lab5 /path/to/buddysCourseDirectory/lab5
Your buddy starts NetBeans and makes a Java project with the files in
/path/to/buddysCourseDirectory/lab5.
@author Your
Name.@author Your Buddy's Name.cd /path/to/buddysLabDirectory/lab5 hg push /path/toUSBStickOnBuddyLaptop/lab5
Now your buddy's changes are on the USB stick.

hg pull /path/to/USBStick/lab5
What happens?

But the second set isn't yet applied to your files. Type
hg update
to update your files.
Now run hg status again. What output do
you get?
hg update command modified a file, but that change isn't
yet permanent.
What command do you use to tell the repository that you accept the change?
hg push /path/to/USBStick/lab5
Now your changes are on the USB stick.

This scenario illustrates an important rule: Always pull before you push. If you push your changes without first pulling other changes, the shared repository (and not just yours) will contain multiple change sets (or multiple “heads” in Mercurial speak). Multiple heads aren't good, and it is harder to fix them on the shared repository than yours.

How does your buddy get your changes?
AddressBook.java and adds a line
@authorYour Buddy's name, followed by
hg commit "Added @author tag" hg pull /path/toUSBStickOnBuddyLaptop/lab5 hg update hg push /path/toUSBStickOnBuddyLaptop/lab5
You take the stick back, edit AddressBook.java and add a
line @author Your name, followed by
hg commit "Added @author tag" hg pull /path/toUSBStick/lab5
What happens?
hg update. Instead, a human needs need to make a decision how
the change sets should be merged. Run
hg merge
Then look inside AddressBook.java.
What happens?
<<< === >>> symbols are
“conflict markers” that point you to the part of the code that
you need to fix.
Edit the file so that it becomes
@author Your name, your buddy's name
What do you do to save your changes to the shared repository?
Conflict markers sound scary, but experience has shown that they are quite rare in practice. Most of the time, team members don't edit the same part of a file, and merging works without generating conflicts. And when conflicts occur, they are usually easy to resolve.
In this part, you will retrieve a repository from a server, make some changes, and save your changes on the server.
You can only do this part if you have sent your public key to your instructor and it has been installed in the server.
Issue this command to get the repository:
cd /path/to/courseDirectory/lab5 hg clone ssh://hg@cs12.cs.sjsu.edu:62222/sandbox
Where is the repository clone located?
sandbox/yourname.txt
(using your name, of course, not yourname, unless you have the
misfortune of having the name “Yourname”). Put in some text
about yourself, something like
Hi, my name is Yourname Jones--which isn't a fun name to have. That's why friends call me Why Jay. I live in Drawbridge and am a computer science student at SJSU.
Don't copy this—put some information about yourself.
Save the file.
Now
ssh://hg@cs12.cs.sjsu.edu:62222/sandboxWhat commands did you use?
It is quite likely that you need to pull and
update before you can push.
ssh://hg@cs12.cs.sjsu.edu:62222/sandbox.
What other files did you get?
You now know enough about Mercurial to manage your personal projects and small team projects. Once you are more comfortable with the basics, check out the tutorial at http://hginit.com/ that gives a very nice background explanation in the inner workings of Mercurial.