Mercurial notes by follower

Notes on using Mercurial

(See also: Using Mercurial with GitHub)

Changing the name of author/committer in Mercurial

(Note: This requires that the repository hasn't been pushed anywhere. See this page for more on issues related to Editing History.)

I have an existing Mercurial repository that used the default (i.e. user@localhost) username for the author of commits made to the repository. Before pushing the repository somewhere public I wanted to change the username to a legitimate form.

I found a post on how to Change the username on a Mercurial changeset which suggests using the Convert extension.

  1. The Convert extension is distributed with Mercurial and needs to be enabled with the following change to your .hg/hgrc (for a single project) or ~/.hgrc file (for all projects):

        [extensions]
        hgext.convert=
    
  2. Create a file authors.txt with a map from old to new username e.g.:

        me@localhost=me <me@example.com>
    
  3. From the root of the repository run:

        hg convert --authors authors.txt . ../<output-repo>
    

    You should see something like this as a result:

        initializing destination ../<output-repo> repository
        scanning source...
        sorting...
        converting...
        11 [...]
        [...]
        0 [...]
        Writing author map file ../<output-repo>/.hg/authormap
    
  4. The output directory will be empty aside from a hidden .hg file. To have the current files appear run:

        cd ../<output-repo>/
        hg update
    

    This should result in:

        [...] files updated, 0 files merged, 0 files removed, 0 files unresolved
    

    And you're done.

  5. I deleted the generated authormap file as this will be a one-off conversion:

        rm .hg/authormap
    

Importing/merging one existing Mercurial repository into another

I found a number of suggestions including hg import && hg export or hg pull --force and hg pull --force (again) or hg transplant.

I decided to test the Mercurial Transplant extension::

  1. Changed current directory to the destination repository.

  2. Enabled the Transplant extension by adding this to .hg/hgrc:

        [extensions]
        transplant=
    
  3. Initiated the transplant with:

        hg transplant --source /<source-repo-directory>/ 0:
    

    This results in:

        searching for changes
        warning: repository is unrelated
        applying  [...]
        [...]
        [...] transplanted to [...]
    
  4. The transplant appeared to work but then I discovered two issues:

    • If the source repository had additions/deletions (?) that left a directory (or directory tree) without files, the entire directory (or directory tree) is left in the working directory. (This is when you recall that Mercurial doesn't version directories only files. :) ) Deleting the empty directories manually seemed to solve this.

    • More seriously, after testing an alternative approach (see below) I realised that while a commit that created a tag was transplanted the actual tag fails to work--I assume this is due to a different hash for the related changeset?

Since transplant doesn't require a separate merge step it turns out it's somewhat more "transparent" than using hg pull --force but due to the second issue above and the possible upside of the required explicit merge/commit step I've decided to use the hg pull --force approach:

  1. Changed current directory to the destination repository.

  2. Initiate the pull:

        hg pull --force /<source-repo-directory>/
    

    This results in:

        pulling from /<source-repo-directory>
        searching for changes
        warning: repository is unrelated
        adding changesets
        adding manifests
        adding file changes
        added [...] changesets with [...] changes to [...] files (+1 heads)
        (run 'hg heads' to see heads, 'hg merge' to merge)
    

    Note the (+1 heads).

  3. According to the posts I found the following merge was all that was required:

        hg merge
    

    But this resulted in the following error:

        abort: branch 'default' has 3 heads - please merge with an explicit rev
        (run 'hg heads .' to see heads)
    

    This I assume is because I'm using hg-git and bookmarks in order to get git-compatible branches.

  4. In order to test the result I previewed a merge with:

        hg merge -P -r tip
    

    and when it seemed okay initiated the actual merge with:

        hg merge -r tip
    

    which resulted in:

        [...] files updated, 0 files merged, 0 files removed, 0 files unresolved
        (branch merge, don't forget to commit)
    
  5. Finally I committed the merge with:

        hg commit -m "<some-awesome-commit-message>"
    
  6. Running the hg tags command at this stage was what alerted me to the hg transplant approach not correctly handling tags.