version-controlmercurialbranchrebasetransplant

In hg, how can I drop the branch name when rebasing and/or transplanting from another repo?


Basically, what I want to try is pulling hg revisions from a branch of an experimental repo into a clone of mainline. But I want to discard the branch name so I can push directly into the server-side mainline repo. It's probably best to give a simple example:

hg init hg_mainline
pushd hg_mainline 
touch foo
hg add foo
hg commit -m 'foo'
popd
hg clone hg_mainline hg_experimental
pushd hg_experimental
hg branch bar_branch
touch bar
hg add bar
hg commit -m 'bar'
popd
pushd hg_mainline
hg pull ../hg_experimental
hg log

As you can see, the mainline now includes a rev with "branch: bar_branch." I don't want this revision to have a branch (i.e. it should be default).

It is okay if this requires rewriting history with rebase, transplant, or another tool. I have tried both of these, but couldn't get it working. The most recent revision hash may end up different between the two repos.

So I want the topmost revision of hg_mainline to look like:

changeset:   1:xxxxxxxxxxxx
tag:         tip
user:        ...
date:        ...
summary:     ...

with no named branch.

Again, it's okay if the hash isn't preserved from hg_experimental.

I am currently using hg 1.6.2+55-18e1e7520b67 from an Ubuntu PPA.

EDIT:

I also used 1.3.1. I tested the below on both, and the results here are the same.

I got it working with transplant, but only with the grep -v kludge.

hg transplant -s ../hg_experimental 1 --filter "grep -v '^branch:'"

With:

hg transplant -s ../hg_experimental 1

hg export didn't work either, with or without an appropriate grep.

The changeset patch looks like:

# HG changeset patch
# User Matthew Flaschen <EMAIL>
# Date 1282942390 14400
# Branch bar_branch
# Node ID b8e36efea72642f0a0194301489d5c48f619a921
# Parent  85d9b9773d4ec09676dfcc4af89c142c46279444
bar

I exported from experimental with:

hg export 1 -o '/tmp/%b_%H_%R'

and tried to import to mainline with:

hg import /tmp/hg_experimental_b8e36efea72642f0a0194301489d5c48f619a921_1

It fails with:

abort: no diffs found

EDIT 2:

As noted, the export method failed only because the files were empty. It works correctly with --git or with non-empty files.


Solution

  • The simplest solution is use hg export from the experimental repo, and hg import into the main repo. By default, hg import won't apply any branch information in the patch. The downside is that they'll show up as different changesets in the two repos -- hg incoming in the experimental repo will show the changes you just exported/imported -- so after you do this, you may be better off deleting and recreating the experimental repo if you plan on doing any more experimentation.

    EDIT: From the hg_mainline repository:

    hg export -r 1 -R ../hg_experimental | hg import -
    

    EDIT2: From hg help diffs:

    Mercurial's default format for showing changes between two versions of a file is compatible with the unified format of GNU diff, which can be used by GNU patch and many other standard tools.

    While this standard format is often enough, it does not encode the following information: (snip)

    • creation or deletion of empty files

    The test files are empty in your test script, so you need to either enter something into them, or use the --git option to hg export.