This document introduces Mercurial and Bitbucket, the tools for managing CS 240 code coursework. Quick reference material and an introduction to Mercurial and Bitbucket are followed by a tutorial that covers setup for this course and basic skills for solo and team use. This page describes the student workflow for CodeTub. As you outgrow this document and seek more general information, consult documentation elsewhere.

This document assumes you are using a CS 240 computing environment, as you must for all CS 240 assignments.

To start the tutorial for the first time, skip to Mercurial (hg) and Bitbucket.

Contents

Quick Reference

For reference once you know the basics. To start the tutorial, skip to Mercurial (hg) and Bitbucket.

CS 240 Solo Workflow

For each assignment, each student (e.g., Wendy) has a provided Bitbucket repository cs240-assignment-wendyw.

Once per assignment:

hg clone ssh://hg@bitbucket.org/cs240codetub/cs240-assignment-wendyw cs240-assignment
cd cs240-assignment

Then, multiple times per assignment as needed:

  1. hg add new files
  2. hg commit cohesive changes often
  3. hg push changes to Bitbucket often enough
  4. check submission: work is submitted ifhg status is emptyand hg outgoing finds no changes.

Edicts:

CS 240 Team Workflow

For each assignment, each student (e.g., Wendy) has a provided Bitbucket repository named cs240-assignment-wendyw.

Once per team per assignment (e.g., Wendy and Wanda):

  1. Choose one member’s Bitbucket repository (e.g., cs240-assignment-wendyw) as the team repository that all team members will share.
  2. Wendy Grant write permission on the repository cs240-assignment-wendyw to all team members on Bitbucket. (On repository page: ⚙ Settings (on left) > User and group access > Users)
  3. One or more team members may then hg clone ssh://hg@bitbucket.org/cs240codetub/cs240-assignment-wendyw cs240-assignment
    cd cs240-assignment
  4. Run ./partner.py to record your partner’s Bitbucket username in the repository.

Then, multiple times per assignment as needed:

  1. hg add new files
  2. hg commit cohesive changes often
  3. hg pull and either hg update or hg merge; hg commit others’ changes
  4. hg push changes to Bitbucket often enough
  5. check submission in all local repositories: hg status empty, hg outgoing finds no changes

Edicts:

Mercurial (hg) and Bitbucket Concepts

This section introduces basics of the Mercurial version control system, the hg tool, and the Bitbucket hosting service.

Repository and working copy

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:

  • Record a new revision, along with timestamp, creator, and description.
  • Reconstruct an arbitrary past revision.
  • Compute the difference of two revisions.
  • Clone a repository, record independent revisions in separate clones, and share revisions to bring clones up-to-date with each others’ revisions.

Benefits

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.

hg

Mercurial is driven by a command-line tool called hg,3 with commands of the form hg command.

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. hg help topic 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.

Alas, hg help cannot help with everything…

$ hg help fly
abort: no such help topic: fly
(try "hg help --keyword fly")

… but it can help with most anything actually hg-related.

Bitbucket

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.

Why not 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 CS 240 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.

Setup for CS 240

You must configure your Bitbucket account and Mercurial preferences in your local computing account for CS 240. It Is simple.

Bitbucket Account

Do this once per student before the first software lab.

  1. Create a Bitbucket account using your .edu email address or add your .edu address if you have an account already. Click through the setup steps choosing default options like “Skip” and “No thanks.”
  2. Check your email to confirm your Bitbucket account has unlimited academic access activated.
  3. Fill out this form with your name and Bitbucket username.
    • Your Bitbucket username is not your email address, even though you may log in by email address.
    • To check your Bitbucket username, select the person icon in the upper right corner (old layout) or lower left corner (new layout) and choose “Bitbucket settings”. Look for “Username.”

Local Account

Do this once per local computing account. (e.g., your CS Linux account, your wx appliance, etc.)

  • If you are using a CS Linux machine, run /home/bpw/public/bin/hg-setup.py in a terminal.
    • Run exactly this command.
    • Do not add python in front.
    • Follow the directions the script prints.
  • If you are using the wx appliance, this script runs automatically when you first start the appliance.
    • Follow the directions printed in a terminal the first time you start up the appliance.
  • CS 240 does not support other platforms, but if you wish to install and configure Mercurial with Bitbucket elsewhere for your own use outside CS 240, there are some potentially useful notes here.

Mercurial Solo Basics

This section introduces Mercurial and explores skills for simple solo use of Mercurial. The next section discusses collaboration and other more advanced issues.

Get your assignment repository

The CS 240 “Code Tub” hosts one repository per student per assignment on Bitbucket. For a student with Bitbucket username wendyw, the repository for a given assignment is called cs240-assignment-wendyw. This repository provides starter code and is the place where you will submit work for instructors to collect and grade.

To begin work, you must clone this Bitbucket-hosted repository to get a copy on your local computer account.

hg clone

Do this once per assignment/repository. This step will make a copy of your repository on your local machine. You will use this copy to make and save changes.

If you plan to work both on the CS lab machines and on the wx appliance, you will need to read information on working in teams. We recommend working on one or the other, but not both, until you are comfortable with Mercurial.

These steps follow an archetypal CS 240 student with Bitbucket username wendyw and their Bitbucket repository for the lab1 assignment. $ indicates a command prompt in the shell.

On your local machine, open a shell, create or navigate to a directory where you would like to store CS 240 assignments (~/cs240 is a great choice), and then clone your Bitbucket repository. Replace wendyw with your own Bitbucket username.

$ mkdir cs240
$ cd cs240
$ hg clone ssh://hg@bitbucket.org/cs240codetub/cs240-lab1-wendyw cs240-lab1
requesting all changes
adding changesets
adding manifests
adding file changes
added 2 changesets with 2 changes to 2 files
updating to branch default
2 files updated, 0 files merged, 0 files removed, 0 files unresolved

The hg clone command copies the entire revision history of wendyw’s Bitbucket repository cs240-lab1-wendyw to the local machine and constructs a working copy of the latest revision in a directory called cs240-lab1.

$ ls
cs240-lab1

Inspect history

You should now have a clone of the cs240-lab1 repository along with a working copy on your local machine. The next few parts will use only on your local copy of the repository. We will not interact with your Bitbucket repository again until pushing changes.

Change directory into the working copy base directory and list its contents.

$ cd cs240-lab1
$ ls
hello.c Makefile

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

Run the command hg log to obtain a summary of the revision history. (Yes, actually run it!) The output is a log of changeset records.

Each changeset has two number identifiers separated by a colon. The large right-hand number in hexadecimal notation is a permanent, unique changeset ID for the changeset. The smaller left hand number is a local revision number in place simply for easier reference than the large hexadecimal changeset ID. The revision number is valid only within this clone of the repository.

Revision history often happens to be a linear (i.e., totally ordered) sequence of changesets, but is a directed acyclic graph (i.e., partially ordered) in general. Each changeset (except for the first) is descended from one or two earlier changesets,4 called its parents, representing the preceding version(s) of the repository. To see the order of changesets more clearly, run the command:

$ hg log --graph

The --graph option (or its shorthand -G) makes hg log draw the topological order of changesets, with parent and child directly connected by line segment. The working copy is the intuitive next changeset in the making, not yet recorded in history, so it does not show up in the log. It does have one or two parents, labeled by @ in the log. All other changesets are labeled by o.

The tag tip labels the changeset most recently added to this repository, though we ignore it for now.

Aside: inspect local repository in browser

Running hg serve and opening http://localhost:8000/ in a browser provides a graphical interface for inspecting revision history. When you are done, type ^C (control key + C key) in your shell to terminate the hg serve command.

Commit changes

While editing the working copy, it is useful to inspect its differences with the most recent revision in the repository.

hg status

hg status compares the working copy to its parents to determine what files have been changed in the working copy. Try it!

$ hg status

Notice that the command did not show any output. This means the working copy is identical to its parent, the “latest” revision in history: nothing in the working copy has been changed.

Let’s make a change. Add your name in a comment at the top of hello.c and save it. Now check again to see if Mercurial has noticed your changes.

$ hg status
M hello.c

M hello.c indicates that hello.c has been Modified since the last revision.

hg diff

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. Did Mercurial detect your change?

hg commit

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 (specified by environment variable $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 hello.c"

No output means success. 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 recorded several distinct commits from a larger set of changes.

When to commit

The Commit Rule: one commit should record one logical, independent change – an atomic unit of work. Learning the right commit granularity is much like learning good code style. It comes with time and practice, and there’s rarely a single unassailable judgment of what constitutes a reasonable commit. A good proxy, for starters, is to try to avoid committing code that does not compile (Especially if working with others!), but to commit often enough that you will not lose signficant work if your working copy suddenly disappears and you need to revert to a previously committed version. For example, don’t commit a half-written function that will cause your program to fail to compile. Wait to commit until you have a compiling (if not fully implemented) function, or at least comment out the syntactically offending piece.

hg revert

Overwrite the file hello.c with something bogus. Hey, might as well delete it.

$ echo bogus > hello.c
$ hg status
M hello.c
$ rm hello.c
$ hg status
! hello.c

Well, actually, we need that file for some more examples. Mercurial sees that it is missing (! hello.c), so just hg revert hello.c to resurrect it.

$ hg revert hello.c
$ hg status

hg revert hello.c reverts hello.c in the working copy 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 hello.c.orig, just in case you regret the revert. hg revert modifies the working copy only, not the revision history.5

Add and (re)move files

Mercurial repositories track revisions to files only if they are explicitly added to the repository.6

Create a new file, README, with some lucid, insightful note inside, and then try to run hg commit to commit it.

$ hg commit
nothing changed

README is untracked, so hg commit ignores, although hg status does see it, and that it is untracked (?).

$ hg status
? README

hg add

Run hg add README to mark README for addition to the repository on the next commit. This command does not commit anything to the repository now.

$ hg add README
$ hg status
A README

The status A indicates README is marked for addition, which constitutes a change since the last revision. hg diff agrees, showing a difference that is the entire contents of README. Run hg commit to commit a new revision including README.

Mercurial tracks files, not directories, so you cannot add an empty directory, but you can add a non-empty directory, which will add of the files in that directory (and recursively in any subdirectories).

hg forget, hg remove

To complement hg add, hg forget README stops tracking README but leaves it untouched in the working copy. hg remove README (or hg rm README) stops tracking README and immediately removes README from the working copy. Like hg add, the effect of these commands is not recorded in the revision history until the next commit. hg status shows R for files marked for removal. hg forget and hg remove do not remove README from existing revisions, only from the next revision and beyond.

hg rename / hg move / hg mv

hg rename A B (or hg move or hg mv) 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.7 If you move a tracked file yourself, Mercurial notices:

$ mv README README.txt
$ hg status
! README
? README.txt

You could undo your mistake and then do it the right way (mv README.txt README; hg mv README README.txt) or just mention it after the fact: hg mv --after README README.txt or hg mv -A README README.txt

Push changes

So far, we have cloned a remote repository and committed some changes to our local repository. We have not yet modified the Bitbucket repository cs240-lab1-wendyw. Even if you do not have any collaborators sharing your Bitbucket repository, it is good to push your new local revisions to Bitbucket reasonably often, if only as a backup. (What if your computer hits a meteorite, for example?)

hg push

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.8

hg push your changes to your Bitbucket repository now. When working with others, pushing may require more work first, but works fine alone.

Submit work

To submit your work, commit and push your final revision to your Bitbucket repository. That’s all! The course staff will collect it there. Here is a detailed checklist if you want to double check:

  1. If you created any new files beyond the starter files (this is rare), hg add them to the repository.
  2. hg commit and hg push your latest changes to the repository.

Here are two separate ways to check that your work has been submitted:

  • Your work is submitted if hg status has empty output and hg outgoing indicates no changes found.
  • Your work is submitted if the Bitbucket page for your repository shows the revisions you want to submit. In the left sidebar, click Commits to see the revision history. For the repository cs240-lab1-wendyw, visit: https://bitbucket.org/cs240codetub/cs240-lab1-wendyw

Workflow

Review the quick reference for a workflow summary.

Mercurial Team Basics

To work with a team, each team member clones the Bitbucket repository and pushes and pulls revisions through it.

We need a few more commands to make this work: 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. As discussed earlier, hg push shares local revisions with a remote repository.

In this section, work with a partner who also has access to your Bitbucket repository. We will call the Bitbucket repository owner Wendy and her partner Wanda. (It Is OK if Wendy and Wanda are the same person.)

To get started, say “Wendy and Wanda” 10 times fast.

Wanda Make a new clone of the Bitbucket repository cs240-lab1-wendyw separate from Wendy’s local clone. It is OK if they are on the same computer and even if they are both in Wendy’s local account. They just need to be separate directories.

Get remote changes

hg pull

hg pull brings new revisions into the repository, but does not touch the working copy.

Wendy After Wanda has cloned the repository, commit and push a new change to Bitbucket.

Wanda Run hg pull to get Wendy’s changes.

$ hg pull
pulling from ssh://hg@bitbucket.org/cs240codetub/cs240-lab1-wendyw
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)

Note the last line of output – before acting on this, examine the state of the repository. First, look in your working copy at the file Wendy changed. Do you see the change? Second, run hg log -G and look for the @. (Remember, this marks the revision that is the parent of the working copy.) Note that Wendy’s recent revision comes after the revision that is the working copy parent.

hg pull brings new revisions into the repository, but does not touch the working copy.

hg update

hg update updates the working copy to the most recently added revision.

The Update Rule: commit before updating.

Wanda Make sure all of your working copy changes are committed (check hg status). Then run hg update (or hg up for short) to update your working copy with Wendy’s recent revision as the the hg pull output suggested.

$ hg update
1 files updated, 0 files merged, 0 files removed, 0 files unresolved

Wanda Now check for Wendy’s changes in the working copy and find the working copy parent in hg log -G once more. Which revision is the parent (@) of the working copy?

The Update Rule: commit before updating. hg update changes your working copy. If you have uncommitted changes in your working copy, you might lose them by updating. Committing your changes first means you can definitely restore your current working copy later. More generally, each commit should be a small, distinct unit of work. Updating to include other revisions in the middle of creating a new change breaks this independence.

Merge divergent changes

Wanda Edit the first line of hello.c and hg commit your change. hg incoming to see if Wendy has pushed any more changes. (She has not.) hg push your change to Bitbucket.

Wendy Edit hello.c to add a new line of text at the end of the file, then hg commit your change. Next, hg pull to get any changes Wanda has pushed.

$ hg pull
pulling from ssh://hg@bitbucket.org/cs240codetub/cs240-lab1-wendyw
searching for changes
adding changesets
adding manifests
adding file changes
added 1 changesets with 1 changes to 1 files
(run 'hg heads' to see heads, 'hg merge to merge)

(She has.) Now, try hg update to update your working copy with Wanda’s changes.

$ hg update
abort: crosses branches (use 'hg merge' or 'hg update -C')

hg update refuses because Wanda’s changes do not follow Wendy’s in history; they happened concurrently, in different branches of history, or roughly, “in an unknown order.” If we simply replace Wendy’s working copy with Wanda’s new revision (that’s what hg update -C would do), we will just start using Wanda’s revision instead of Wendy’s revision, which is not what we want.

Wendy Examine the structure of history with hg log -G and note the following:

  • Wendy’s working copy still has a single parent (@), and it is the same as before pulling Wanda’s changes. One more time: hg pull does not touch the working copy (and neither does hg update if it fails – you can verify that with hg status).
  • There are two heads, i.e., revisions with no children. This indicates that history has split into two divergent branches. You can also use hg heads at any time to see just the heads.

To get both Wendy’s changes and Wanda’s changes at the same time, we must merge them.

hg merge

hg merge merges revisions from another branch of history into the working copy.

The Merge Rule: commit before merging and commit immediately after merging (and resolving any conflicts). The changeset including a merge should include only changes immediately related to merging.

Wendy As hg pull originally suggested, we will (not yet) run hg merge to integrate Wanda’s changes into Wendy’s working copy without losing either set of changes. But first, make sure any outstanding changes are committed. Check hg status for that. All clear? Now merge:

$ hg merge
merging hello.c
0 files updated, 1 file merged, 0 files removed, 0 files unresolved
(branch merge, don't forget to commit)

Look at the summary: changes to hello.c were merged. Take a look at hello.c, then step back and take a moment to think how awesome that is!

Are you back? We have a bit more to do.

To support the merge, the working copy now has two parents, the ends of the two divergent branches of history. Run hg log -G and look for @ to see this. (You can also run hg parents at any time to see just the parents of the working copy or an arbitrary revision.)

Wendy As the output of hg merge helpfully reminds us, Wendy should immediately hg commit this merged revision before making any new changes.9

Wendy Run hg log -G again to see how this merge and commit affected history. We are now back to one head (revision without children) and it is the parent of Wendy’s working copy. History has become a directed acyclic graph, but we have reconverged on a single history containing both Wendy’s and Wanda’s changes.

Perspective

Consider: in a few commands, hg accomplished the entire tedious process of copying Wanda’s files to Wendy’s computer, painstakingly determining which files have been updated by each person, and getting the newest revision of each file in place. In fact, it can merge changes in different files and even in different parts of the same file. Wow!

Excitement aside, it is important to remember that, while highly useful, automated merging is not magic nor is it a license to edit haphazardly without coordinating with your team. Even when a merge succeeds at a textual level, the end result may not be meaningful. This means it is still important to:

  • communicate with your teammates about what everyone is editing so you know what to expect from merges; and
  • do some testing or other sanity-checking on the result of a merge.

Resolve conflicts

Note: this part may depend on the merge = internal:merge entry in the Mercurial configuration we did above. Without this configuration option, Mercurial may use merge facilities in other programs on your system not described here. It may or may not be easier to navigate.

Two divergent changes to the same lines in a file constitute a conflict that cannot be merged automatically. Mercurial is good, but it cannot read your team’s collective mind to decide what to do with a conflict, so it asks you. Try it:

Both Wendy and Wanda Edit the first line in README to hold different text (i.e., Wendy’s revision and Wanda’s revision should differ in the first line). hg commit that change.

Wendy hg push.

Wanda hg pull and hg merge, then observe:

$ hg pull
pulling from ssh://hg@bitbucket.org/cs240codetub/cs240-lab1-wendyw
searching for changes
adding changesets
adding manifests
adding file changes
added 1 changesets with 1 changes to 1 files (+1 heads)
(run 'hg heads' to see heads, 'hg merge' to merge)
$ hg merge
merging README
warning: conflicts during merge.
merging README incomplete! (edit conflicts, then use 'hg resolve --mark')
0 files updated, 0 files merged, 0 files removed, 1 files unresolved
use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon

Note several cues in the output: Mercurial tried to merge, but Wendy and Wanda made conflicting changes, so there’s no obvious way to merge and preserve both of their changes. Instead of doing something arbitrary, Mercurial did the following:

  • Put the pre-existing working copy of README in README.orig.
  • Annotate conflicts in README using special notation.
  • Mark README as unresolved, such that we cannot commit until explicitly resolving the conflict.

Opening up README, we see something like this:

<<<<<<< local
This is the read me edited by Wendy and awesomified by Wanda.
=======
This README was created by Wendy.
>>>>>>> other

<<<<<<< local, =======, and >>>>>>> other delineate conflicting revisions. The first is from the local working copy. The second is from the other competing revision.

To resolve the conflict, edit the file to remove these markers and save whatever final contents you wish. Then, run 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 <<< === >>>.

Finally, live by the merge rule: commit immediately once you have finished merging (and resolved any conflicts), and before making any unrelated changes. The changeset including a merge should include only changes immediately related to merging.

$ hg resolve --mark README
(no more unresolved files)
$ hg commit -m 'Merged README updates'

The Merge Rule: commit before merging and commit immediately after merging (and resolving any conflicts). The changeset including a merge should include only changes immediately related to merging.

Push changes

To complete the cycle, push your changes (especially if you just merged) to share with your team. If another teammate has pushed changes to your Bitbucket repository since you last pulled, you will need to pull and merge those changes before you can push. Mercurial detects this case.

$ hg push
pushing to ssh://hg@bitbucket.org/cs240codetub/cs240-lab1-wendyw
searching for changes
remote has heads on branch 'default' that are not known locally: 4fc62a727627
abort: push creates new remote head 985ebfbdedf3!
(pull and merge or see "hg help push" for details about pushing new heads)

Take Mercurial’s first suggestion (pull and merge). Do not try to “push new heads.”10

Once your local repository is up-to-date with the remote repository, the push will succeed.

$ hg push
pushing to ssh://hg@bitbucket.org/cs240codetub/cs240-lab1-wendyw
searching for changes
adding changesets
adding manifests
adding file changes
added 2 changesets with 2 changes to 1 files

Other merge tools

Mercurial can be connected to many other tools (including modes in Emacs and vi) that allow you to review conflicts one at a time and click or type a keyboard command to select one version or another, or type in a new one. See other resources for more.

Workflow

Review the quick reference for a workflow summary.

Other Resources

Mercurial

Bitbucket

Configure Mercurial with Bitbucket from Scratch

Not Supported

For CS 240, you should be working on an approved computing environment. Use the setup instructions above. This section no longer describes what the automated setup scripts do, in case you want to do the same on your own machine for personal non-CS 240 use.

License and Acknowledgments

Creative Commons License
Mercurial (hg) for Code Assignments by Benjamin P. Wood is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.

This page describes the student workflow for CodeTub.

Thanks to Scott Anderson and Jean Herbst for comments that improved this page. Please contact me with any suggestions, bug reports, etc.

  1. Mercurial stores history as differences between versions, rather than snapshots of versions. Each can be reconstructed from the other.

  2. 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.

  3. The clever Mercurial designers are apparently amateur chemists!

  4. Hence the history DAG has maximum out-degree 2, where edges are directed from child to parent.

  5. For more advanced time travel, learn about merging, then consult documentation about hg update.

  6. There are many good reasons to track only explicitly added files. One is that compilers and other tools create a lot of automatically generated files that are derived purely from other files in the repository.

  7. hg rename is actually just hg copy (hg cp) followed by hg remove. I cannot recall using hg cp, but I use hg mv a lot.

  8. Actually you can change that: hg help paths.

  9. More generally, a commit containing a merge should only contain additional edits if those edits are necessary to make the merged revision correct. (Look ahead to conflict resolution to understand this.)

  10. There are times when this is desired, but if that time is now, you are beyond the level of this document anyway.