include "../_i/1.h"; ?>
I used a directory named "myrepo" for a demonstration, but you can
use Mercurial in any directory. You can even cd
into an
existing directory full of files and start version-controlling it with
Mercurial; just do hg init .
. (Remember that in Unix,
. refers to the current directory). All this does is create the
hidden .hg
directory where Mercurial tracks the history
of your files, it doesn't change your files in any other way. You'll
still have to hg add
each file you want tracked.
You can mix tracked and untracked files in the same directory;
just hg add
some and put the names of others in
your .hgignore
file, so they don't always show up
in hg status
.
If you hg init
a directory and turn it into a
Mercurial repo, you can then version-track any files inside that
directory, and inside any sub-directories, on down the chain.
mypages/ - things_to_remember.txt - mysite/ - index.html - css/ - style.css - print.css - img/ - grimacing_soccer_player.jpg - anothersite/ - ...
If you cd mypages/
and then hg init
mysite
, it will create mypages/mysite/.hg/ (it
would also create the mysite directory if it didn't
already exist).
mypages/ - things_to_remember.txt - mysite/ - index.html - css/ - style.css - print.css - img/ - grimacing_soccer_player.jpg - anothersite/ - ...
Then you can hg add index.html
, or hg add
img/grimacing_soccer_player.jpg
, or cd css
and hg add style.css print.css
(or just hg add
*
). But you can't add things_to_remember.txt
or anything in the anothersite directory.
If you wanted to version control everything, you could of
course hg init
the mypages directory
instead, and keep everything in one big repo. But
if mysite and anothersite are
separate sites that you maintain independently from each other, you'd
probably want to manage them as two separate repos with separate
version histories instead.
You can even nest one Mercurial repo inside another; the inner one will manage only the files inside it, of course, and the outer one will completely ignore all the files inside the inner one).
Technically, the repository is just the .hg directory where Mercurial stores all its version-history metadata, and the directory containing it (where your files live) is the working directory. The working directory represents a snapshot of your files at some point in the version history.
- mysite/ <---- working directory - .hg/ <---- repository - index.html - css/ - style.css - print.css
So far, we've always kept our working directory at
the most recent version, or tip. But we can revert to
any previous state with the hg update
command.
cd
into the working directory where you did last
week's homework. First do an hg status
to see if there
are any uncommitted modifications; if there are, do hg
diff
to see the changes and then either hg commit -m
'some message'
to commit them, or hg revert
filename.py
to abandon them. (If you only ever committed a
single change, make some change and commit it so hg log
shows you at least two revisions.)
Run hg log
, and pick some previous revision. I'll pick 0:
carljm@kale:~/testproj$ hg log changeset: 1:c38c63ca48cc tag: tip user: Carl Meyerdate: Thu Sep 17 16:10:27 2009 -0400 summary: changes changeset: 0:db16fd315f06 user: carljm@dj.goshen.edu date: Thu Sep 17 14:16:09 2009 -0400 summary: first commit
Run hg parents
to see what revision the working
directory is currently based on; should be the tip (latest)
revision. Then:
carljm@kale:~/testproj$ hg update 0 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
Mercurial tells that one file was changed between the revision I
was at and the one I just updated to. Now hg parents
will
tell me that my working directory is based on revision 0; and if I
look at my files, I will see that they are indeed the versions I had
right after my first commit (revision 0). my recent changes aren't
lost, of course; hg log
still shows the full history,
and hg update 1
(or hg update tip
, or
just hg update
) will return me to my most recent
version.
If you have uncommitted changes in the files in your working
directory, hg update
will try to "carry them along" in
your time travelling, by applying the "same" changes to the older
versions of your file(s). This can be very handy but most of the time
you don't need it: just commit first, or abandon your changes by
providing the -C
flag: hg update -C
.
$ ssh dj.goshen.edu
It's a (virtual) Linux server dedicated to this class; but it gives
you a Unix-style bash shell, just like on your Macs (or even more like
www.goshen.edu). You have a home directory
in /home/yourname
(in place
of /Users/yourname
on a Mac), and that's where you are
placed initially when you ssh in (pwd
to verify). You can
also ssh into it from off-campus, which will help some of you out.
First off, mkdir homework
to create a directory where
you'll put your homework assignments from here on out. Within it,
create numbered directories for each week's homework (just to help me
find things more easily).
If you need to transfer files to/from dj.goshen.edu:
carljm@kale:~$ scp my_file.txt carljm@dj.goshen.edu:~/some_dir/ my_file.txt 100% 5 0.0KB/s 00:00
Or to pull a file down:
carljm@kale:~$ scp carljm@dj.goshen.edu:~/some_dir/my_file.txt . my_file.txt 100% 5 0.0KB/s 00:00
In both cases, I can leave out the carljm@ if my local username is the same. On a campus machine, it will be, since both are my GC username.
You can also transfer files using any GUI FTP client that supports the SFTP protocol.
Rather than copying individual files, you'll often have a Mercurial
repo that you want to keep in sync between two different machines. Or
you keep the primary copy on dj.goshen.edu, but you want to work on it
on a lab Mac, so you don't have to deal with network latency for your
editing. This is where hg clone
, hg pull
,
and hg push
come into play.
hg clone
creates a new copy of an existing repo.
hg pull
pulls changesets from some other repo into
your current one.
hg push
pushes changesets from your current repo into
some other one.
Say I've got a local repository on my computer, and I want to create a clone of it on dj.goshen.edu:
carljm@kale:~/testproj$ hg clone . ssh://dj.goshen.edu/newtest searching for changes remote: adding changesets remote: adding manifests remote: adding file changes remote: added 2 changesets with 2 changes to 1 files
. refers to my current directory, which is a Mercurial working directory. The second argument _could_ just be a path to some other (not-yet-existing) directory on my own computer, but in this case I give it an ssh://dj.goshen.edu URL. The path is relative to my home directory, so this will create a copy of my local testproj in a directory named newtest on dj.goshen.edu.
If I now ssh into dj.goshen.edu and ls
the newrepo directory, it won't have anything in it
except the .hg repo dir. This is because neither hg clone
nor hg push
nor hg pull
will modify the
working directory; they just copy changesets in the version
history.
In the case of a brand-new clone, this means it has no working
directory contents at all yet, even though all your version history is
there inside the .hg directory. All you need to do
is cd newrepo
and then hg update
to give
yourself an up-to-date working directory.
hg pull
provides a shortcut, hg pull -u
which just performs an automatic hg update
after
pulling. It's the only one with this shortcut because it's the only
one that brings new changesets into your current (local) repo.
In your local repository, make some changes and make a new commit. Then run:
carljm@kale:~/testproj$ hg push ssh://dj.goshen.edu/newtest pushing to ssh://dj.goshen.edu/newtest searching for changes remote: adding changesets remote: adding manifests remote: adding file changes remote: added 1 changesets with 1 changes to 1 files
carljm@dj:~/newtest$ hg log changeset: 2:4970659539b4 tag: tip user: Carl Meyerdate: Thu Sep 17 18:04:14 2009 -0400 summary: more changes changeset: 1:c38c63ca48cc user: Carl Meyer date: Thu Sep 17 16:10:27 2009 -0400 summary: changes changeset: 0:db16fd315f06 user: carljm@dj.goshen.edu date: Thu Sep 17 14:16:09 2009 -0400 summary: first commit
carljm@dj:~/newtest$ hg parents changeset: 1:c38c63ca48cc user: Carl Meyerdate: Thu Sep 17 16:10:27 2009 -0400 summary: changes carljm@dj:~/newtest\$ hg update 1 files updated, 0 files merged, 0 files removed, 0 files unresolved carljm@dj:~/newtest\$ hg parents changeset: 2:4970659539b4 tag: tip user: Carl Meyer date: Thu Sep 17 18:04:14 2009 -0400 summary: more changes
carljm@dj:~/newtest$ emacs file.txt carljm@dj:~/newtest$ hg commit -m 'yet another change' carljm@kale:~/testproj$ hg pull ssh://dj.goshen.edu/newtest pulling from ssh://dj.goshen.edu/newtest searching for changes adding changesets adding manifests adding file changes added 1 changesets with 1 changes to 1 files (run 'hg update' to get a working copy) carljm@kale:~/testproj$ hg update 1 files updated, 0 files merged, 0 files removed, 0 files unresolved