Mercurial

Author: Hans Fangohr <fangohr@soton.ac.uk>
Date: 2008-05-21
Version: 033c85b22987
Id:talk.txt,v 033c85b22987 2008/05/21 08:42:42 fangohr
Series:SESA2006 2008, last lecture

Hint

Adjust font-size in browser to make slides fill screen. Often, this can be done with CTRL+PLUS or CTRL-MINUS, or pressing the CTRL key and scrolling the mouse wheel (on Mac OS X: use Apple key instead of CTRL)

Outline: Why version control?, Mercurial (Hg), Examples

Hans Fangohr is a Senior Lecturer in Computational Methods in the School of Engineering Sciences at the University of Southampton.

This is a very basic introduction to the use of version control systems, and in particular Mercurial. No advanced features such as merging will be discussed (see Mercurial Tutorial for this).

Why version control (Single users)

Why version control (in team work)

Mercurial

Installation

Download binary from http://www.selenic.com/mercurial/wiki/index.cgi/BinaryPackages

Linux:usually standard package of distribution
MacOS:compile from source or download binary
Windows:recommend TortoiseHg at TortoiseHg http://www.selenic.com/mercurial/wiki/index.cgi/TortoiseHg

Terminology

Repository:

something keeping track of all changes to the project for all the past (hidden in .hg)

You can think of this as a (hidden) collection of the files file-1.doc, file-2.doc, file-3.doc, file-4.doc.

Working copy:

the set (visible) files (in the working directory), i.e. one copy of the project.

Typically, this will contain the most recent version (i.e. file-4.doc)

Getting started with hg

Initialise hg repository

  • Need to do this only once for a given repository:

    $project1> hg init
    

Checking the status of files

In-built help function

First steps 1: Adding files

First steps 2: checking status

First steps 3: modifying the file

First steps 4: Review the change

First steps 5: The history (again)

First steps 6: Adding another file

We create a new file README.txt which contains this line:

The hello.py program prints a friendly message.

Let's check the status, add, commit and check:

$project1> hg status
? README.txt
$project1> hg add README.txt
$project1> hg status
A README.txt
$project1> hg commit -m "Adding RENAME file"
$project1> hg status
$project1>

First steps 7: Study the history

$project1> hg log
changeset:   2:7a6262cf0acf
tag:         tip
user:        Hans Fangohr [phi] <fangohr@soton.ac.uk>
date:        Thu May 15 23:53:41 2008 +0100
summary:     Adding REAME file

changeset:   1:7bcacdc541fb
user:        Hans Fangohr [phi] <fangohr@soton.ac.uk>
date:        Thu May 15 23:35:53 2008 +0100
summary:     Adding main program

changeset:   0:f8087bdd8fc8
user:        Hans Fangohr [phi] <fangohr@soton.ac.uk>
date:        Thu May 15 23:24:31 2008 +0100
summary:     Added my first file

Other ways of reading the history

Graphical interface

$project1> hg view

Using webserver

$project1> hg serve

and point webbrowser to http://localhost:8000

See which line was written when (and by whom!)

$project1> hg blame hello.py
0: def hello(msg):
0:      print "Hello World: %s" % msg
1:
1: hello("from hello.py")

$project1> hg blame -u hello.py
fangohr: def hello(msg):
fangohr:        print "Hello World: %s" % msg
fangohr:
fangohr: hello("from hello.py")

Typical cycle

While programming (or writing a report, creating a web page, etc), we tend to follow this cycle:

  1. do the work (i.e. modify files)

  2. commit changes with commit message

  3. back to 1.

Only occasionally, we need to do special things:

  • examine the history (partly shown)

  • go back to an older snap shot

    -> this is next

The update command

update refers to the files in the working directory (not the repository), and allows 'time travel'.

The update command (part 2)

The update command (part 3)

Adding user-defined tags

User-defined tag examples

Suppose we have released revision 2 as version 1.0 of the software:

$project1> hg tag -r 2 "release 1.0"
$project1> hg tags
tip                                3:691317be5f4b
release 1.0                        2:7a6262cf0acf

Adding user-defined tags (part 2)

Adding user-defined tags (part 3)

What are revision specifiers

Caution!

If you use the push, pull or merge commands, the integers may change. See Mercurial tutorial for details.

Removing files from the repository

Renaming files and directories

You can easily rename a file with hg. Suppose we need to rename README.txt to readme.txt:

$project1> hg rename README.txt readme.txt

This (i) renames the file in the working directory and (ii) include the change in the repository the next time we commit.

A bad way of renaming

You could rename a file as follows:
  • copy README.txt to readme.txt without hg

  • tell hg to remove README.txt from the repository and

  • tell hg to add readme.txt.

This his two disadvantages: (i) hg cannot know that this is the same file and (ii) this will take much more disk space than using hg rename.

Where is all the history stored?

Reverting changes

Uncommitting the commit

If you have committed something that you didn't want to commit, you can undo the last commit (but only the last commit!) with:

$project1> hg rollback

Making copies (backups?) of the repository

You can either

Note

To propagate changes from the original repository (project1) to the cloned copy (my-backup-project), do this:

$> cd my-backup-project1
$my-backup-project1> hg pull

Multiple repositories

Multiple repositories: one master repository

  1. Create the master repository, say:

    $> mkdir master
    $> cd master
    $master> hg init .
    
  2. Add any files that you have already, and commit.

  3. Now indivduals can clone from the master to carry out their work:

    $> hg clone master my-copy-A
    $> cd my-copy-A
    
    • Do the work here, and and modify files, commit as many times as you like (may need pull; see below).

    • When you have completed your work, commit everything and push your changes to the master (may need pull first):

      $my-copy-A> hg push
      

Multiple repositories: one master (2)

  1. To import changes from the master repository (others could have done some work in the mean time) into my-copy-A, use the pull command:

    $my-copy-A> hg commit          #commit all our changes first
    $my-copy-A> hg pull
    

    This will update the repository (not the working directory). To bring changes into the working directory, we have to update:

    $my-copy-A> hg update
    

    If there have been changes on files that we have worked on as well, a merge has to take place (command is hg merge)

    • This is usually automatic and hg will tell us if required.

    • Rarely, one needs to edit a file manually during the merge.

    • After a merge, we need to commit, typically like this:

      $my-copy-A> hg commit -m "merge"
      

Multiple repositories: one master (3)

The cloning, pulling and pushing between repositories can happen

  • on the same file system (computer)

  • between computers using either

    • ssh or

    • the web server

This is an advanced topic (see Mercurial Tutorial).

Scientific truth and reproducibility

Important

When using computer simulations, we should use version control to be able to reproduce any earlier results at any point in the future.

Summary of important commands

hg add (add files)

hg commit (commit changes)

hg status (show modified/missing/added/removed files)

hg log (show log)

hg diff (show diff to version of working directory)

hg parents (show version of working directory)

hg update (updated working directory)

hg clone (copy repository)

hg tag (add tag)

hg tags (list tags)

Abbreviating commands

Most commands can be abbreviated, such as:

status -> st

commit -> ci

diff   -> di

update -> up

rename -> mv

Odd bits of information

Advanced functionality

Read more about these topics in the (inofficial) manual at http://hgbook.red-bean.com

Useful entries in user hg configuration file

On a Linux/Mac OS X user account, this is (an optional) file .hgrc in the home directory:

[ui]
#tell Mercurial what user information to use in commit messages
username = Hans Fangohr [phi] <fangohr@soton.ac.uk>

[extensions]
#this enables the 'hg view' command
hgk=

[web]
#this makes for a nicer layout of the web interface (which is started
#with 'hg serve'
style=gitweb

Use Mercurial without access to server

Suppose we have developer A and B that need to work on the same project, but cannot access any mercurial servers jointly (typically due to firewalls, restrictions imposed by employer, etc). Suppose A hold the repository THEREPO from which the work is meant to start. Somehow, A needs to give B a copy of the repository (mail, email, usbstick, ftp server, ...). Suppose the current tip of that repository is 4f45839f613c:

and email the bundle changes.bundle to B. This bundle contains all changes since the specified base version.

If the bundle contains changes that are already present in B's version of THEREPO, then these will be ignored when pulling.

If B wants to communicate changes to A, he needs to follow the same instructions (to create a bundle and email it to A).


Summary

(end of hand outs)