views:

74

answers:

2

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.

+1  A: 

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.

Niall C.
and transplant is just a wrapper around export/import with a little duplicate detection
Ry4an
I get "abort: no diffs found" with either hg 1.3.1 or recent hg. I exported and imported within versions, just to be safe.
Matthew Flaschen
@Matthew: Sorry, was in a hurry earlier. Updated my answer with a command that should work for you.
Niall C.
No, I still get the same error. This is immediately after doing all but the last two lines of my above test script.
Matthew Flaschen
Thanks, both work. I've seen plenty of traditional diffs, but that limitation hadn't occurred to me here. I will keep it in mind in the future, though I know it doesn't apply to much real code.
Matthew Flaschen
+2  A: 

The transplant extension already scraps the branch name:

cd hg_mainline
hg transplant -s ../hg_experimental 1

should do it for you. If you're finding that's not the case you can always use the --filter modify the changesets (perhaps just using grep -v) on the way in.

I will note that if you can come up with a work flow that avoids transplant and retains hashes you're better off. Avoiding named branches entirely makes this easier -- anonymous branches perhaps with bookmarks work as well or better.

Ry4an
There is no -`r` option. As I noted, I experimented with transplant quite a bit, but it always kept the branch (or simply failed).
Matthew Flaschen
Sorry, it's not -r it's just '1'. I just did a transplant and it threw away the branch info. Do you have git-style diffs enabled (I don't?)? Are you using a recent version? 1.6.3 is days old and 1.0.x (or 0.9.6) and ancient.
Ry4an
@Ry4an, I got transplant working with a `grep`. I'd heard of hg bookmarks, but didn't completely grok it before. I've started looking into them, and it seems promising. It certainly avoids the named branch issue.
Matthew Flaschen
Yeah, read http://stevelosh.com/blog/2009/08/a-guide-to-branching-in-mercurial/ and see that in Mercurial 1.6 bookmarks do push/pull with the repo. I still prefer to just use anonymous branches with temporary multiple clones if I'm having a hard time keeping track.
Ry4an