/home/bpw/public/bin/hg-setup.py
in a terminal.
scp
to get the file if you have a CS account and scp
installed (allows access from anywhere, not just campus):$ scp your_username@cs.wellesley.edu:~bpw/public_html/wx/s17/appliance/wx-s17.ova .
wx-s17.ova
has finished downloading, start VirtualBox and choose the menu item File > Import Appliance….
wx-s17.ova
, then click Continue.
wx-s17.ova
file to save space.
This section introduces basics of the Mercurial version control system, the hg
tool, and the Bitbucket hosting service.
A Mercurial repository is a structured record of the evolution of a project through multiple revisions in the form of a detailed revision history of its files.[1] Mercurial also calls revisions changesets. Every Mercurial repository is paired with a distinct working copy, a directory containing a snapshot of the project, where the user can prepare new revisions.[2] The repository itself is hidden away (in a hidden directory .hg
inside the working copy’s base directory). The user can make direct changes to the working copy, but interacts with the repository (e.g., to record a new revision) only through the interface provided by the Mercurial tool, hg
. Mercurial supports several useful repository tasks, including:
By allowing interaction with the repository only through its interface, a system like Mercurial abstracts tedious representation and maintenance details away from the error-prone user. The version control software is responsible for principled maintenance of revision history (principles being a great strength of computers) while users are responsible for deciding what versions of a project are appropriate and meaningful to record in the revision history or share revisions with other users.
This model supports a wealth of development tasks such as: quick, reliable, easily recoverable backups; structured collaborative development and sharing of code; structured documentation of project evolution; finding the revision where bug was introduced into the project. Being forced to learn to use principled version control helps you:
Stop losing hours of work because making backups was just too much work to bother with… until you realize the past 7 hours of untested coding entirely breaks everything.
Stop sharing code through email. It has a funny habit of multiplying, shifting around, breaking, and disappearing, especially in office hours.
Stop the scourge of unstructured, unintelligible code-copy litter:
Stop partners from interfering while simultaneously editing on Dropbox or Drive.
Stop sharing passwords or committing file permissions faux pas in the name of collaboration.
Start keeping a structured history of development to simplify future debugging tasks.
Start sharing code easily.
Start trying out risky new features without losing that precious working version.
Start learning a fascinating application of data structures and algorithms (particularly DAGs).
Start getting employed.
A version control system accomplishes none of these improvements on its own, but it helps make the right choice the path of least resistance for you.
Mercurial is driven by a command-line tool called hg
,[3] with commands of the form <code>hg <em>command</em></code>.
Driving a command-line tool for the first time can be unsettling, since it is difficult to see the controls. Once you become familiar, however, you may find it easier, quicker, and more expressive than a modern mouse-based GUI. To keep you company on the journey, Mercurial has a friendly help and documentation system built in. Just run the command hg
to see the controls.
*Note: in this, and all command line transcripts shown in this document, we use $
to represent the command prompt. Following lines are output from commands entered at the prompt.
$ hg
… output omitted here …
Take note of what it shows (omitted here) and the fact that you can summon this at any time.
hg help
shows a longer list of help topics. <code>hg help <em>topic</em></code> shows help about a specific topic. The most common kind of topic is a command. Try running hg help help
to see if hg help
can help you learn how to use the hg help
command.
Bitbucket is a hosting service for Mercurial and git repositories. We could host repositories the CS server, but the Bitbucket web interface allows flexible permissions. Bitbucket accounts are free; a .edu email address allows unlimited repositories and unlimited collaborators.
git
and GitHub?If you have used or heard of a version control system before, it is
probably git
(likely with GitHub hosting), the most widely known
such tool as of 2017. There are many version control systems
available. We use Mercurial for CS240 since it is widely
used and has a relatively simple, predictable, and principled
interface that is often considered the easiest among its peers for new
users to learn quickly. Concepts in git
and hg
are similar;
commands differ.
Mercurial stores history as differences between versions, rather than snapshots of versions. Each can be reconstructed from the other. ↩
Mercurial terminology usually refers to this “next changeset in the making” as the working directory, but we use the alternate term working copy to avoid confusion with the notion of working directory in the shell, as in pwd
. ↩
The clever Mercurial designers are apparently amateur chemists! ↩
assignment-username
.
hg clone ssh://hg@bitbucket.org/cs240spring2018/bits-wendy bits
cd bits
hg add
new files
hg commit
cohesive changes often (got something working/towards working, etc.)
hg add
changes to Bitbucket "often enough" (done working for a little while, etc.)
hg status
is empty and hg outgoing
finds no changes - submission successful
wendy
and their Bitbucket repository for the bits
assignment. $
indicates a command prompt in the shell.wendy
with your own Bitbucket username.
$ mkdir cs240
$ cd cs240
$ hg clone ssh://hg@bitbucket.org/cs240spring2018/bits-wendy bits
requesting all changes
adding changesets
adding manifests
adding file changes
added 6 changesets with 19 changes to 15 files
updating to branch default
15 files updated, 0 files merged, 0 files removed, 0 files unresolved
$ ls
bits
bits
repository along with a working copy on your local machine. The next few parts will use only your local copy of the repository. We will not interact with your Bitbucket repository again until pushing changes.
$ cd bits
$ ls
bits.c Makefile ... [other files omitted for space]
Remember, these files are the working copy, currently a snapshot of the latest revision of the repository, but they tell you nothing about the revision history, which is hidden away.hg log
to obtain a summary of the revision history. (Yes, try it now!) The output is a log of changeset records.
$ hg log --graph
--graph
option (or its shorthand -G
) makes hg log
draw the topological order of changesets, with parent and child directly connected by line segment. hg status
compares the working copy to its parents to determine what files have been changed in the working copy. Try it now!
$ hg status
M bits.c
which indicates that bits.c has been Modified since the last revision.hg diff
shows the exact difference between the current working copy and its parent revision. Lines prefixed by + are additions; lines prefixed by - are deletions. (Do you see your addition to bits.c?)hg commit
records the current working copy as the latest revision in the local repository. (It does not affect any other repositories.) It will open an editor to record a commit message describing the revision. Sometimes it is faster to give the message on the command line with --message or its shorthand -m:
$ hg commit --message "Added name to bits.c"
hg status
should show no changes. The output of hg log --graph
confirms that a new changeset with your commit message has been created and marked as the parent (@) of the working copy.
Without extra arguments, hg commit
commits all changes to all tracked files in the working copy. hg commit FILE or hg commit -m "message" FILE record revisions including changes to FILE only. (Any number of specific files may be given.) This (and the record extension) are helpful for recording several distinct commits from a larger set of changes.hg revert
returns a given file to whatever it looked like in the parent revision (even if you’ve just accidentally deleted it or spent 3 hours rewriting it in a way you now regret). If a modified version exists in the working copy, Mercurial makes a backup of it in filename.c.orig, just in case you regret the revert. hg revert modifies the working copy only, not the revision history. (Try it now! Delete bits.c and use hg revert to bring it back).
hg add
marks a given file for addition to the repository on the next commit. This command does not commit anything to the repository now. Mercurial repositories track revisions to files only if they are explicitly added to the repository.
hg rename A B
renames (moves) a tracked file A
to be tracked under a new name B
. Like hg remove, the effect is not recorded in the revision history until the next commit, but is reflected immediately in the working copy. If you move a tracked file yourself using a linux command, Mercurial notices (and is unhappy)!
hg push
copies local revisions that are not in a remote repository to that remote repository. hg outgoing
lists these revisions without pushing them. By default, both use the remote repository from which the local repository was cloned.
hg push
your changes to your Bitbucket repository now. When working with others, pushing may require more work first, but works fine alone.
hg add
them to the repository.
hg commit
and hg push your latest changes to the repository.
hg status
has empty output and hg outgoing
indicates no changes found.
hg pull
acquires new revisions from a remote repository;
hg incoming
shows them but does not acquire them;
hg update
or hg merge
integrate them with local revisions.
hg update
updates the working copy to the most recently added revision.
hg merge
merges revisions from another branch of history into the working copy.
hg push
shares local revisions with a remote repository.
hg commit
that change.hg push
.hg pull
and hg merge
, and then observes:hg resolve --mark README
to mark README as resolved. Mercurial will refuse to commit if unresolved conflicts remain, to prevent accidental commits of a file full of unmerged conflicts and <<< === >>>.
$ hg resolve --mark README
(no more unresolved files)
$ hg commit -m 'Merged README updates'