5
votes

I did a series of dumb steps with my local copy of our shared repository, and I'm looking for a way how to fix it. The steps are:

  • I used bookmarks to have multiple heads of a development branch, that other people use:

    -o---o---o-----o---   <- dev branch
      \----1----1------   <- another head of the dev branch,
                             where I committed stuff
    
  • I created a new branch, still local, some time later

      /---------------x   <- new branch
    -o---o---o-----o---   <- dev branch
      \----1----1------   <- another head of the dev branch,
                             where I committed stuff
    
  • for one head, that contains only my code, I did a rebase on another branch

                       /-1'--1'--  <- rebase
      /---------------x            <- new branch
    -o---o---o-----o---            <- dev branch
      \----1----1------            <- another head of the dev branch,
                                      where I committed stuff
    
  • then, I merged the rebase, and then, a couple of commits later, I merged default

                       ----------d-\      <-default
                                    \
                       /-1'--1'\     \
      /---------------x--------x--x-x-x-- <- new branch 
    -o---o---o-----o---         
      \----1----1------         
    

Now, I wanted to push my new branch to the server (hg push --new-branch -b newBranch), but I get abort: push creates new remote head, since commits 1' belong to dev branch.

What is the right thing to do? I would like to avoid creating this additional head.

Update:

Per request, this is the output of hg heads:

changeset:   839:f2033d695fcd  <- want to push this
branch:      newBranch
tag:         tip
user:        me
date:        Wed Oct 31 13:05:51 2012 +0100

changeset:   826:7fde19d7f467
branch:      devBranch
user:        my-collegue
date:        Tue Oct 23 14:59:42 2012 +0200

changeset:   820:23853bbf68df  <- the part after rebase that got merged
branch:      devBranch
user:        me
date:        Mon Oct 22 15:36:26 2012 +0200

changeset:   807:899344cfb145  <- obsolete (branch with 1's)
branch:      devBranch
parent:      711:454f29c03fb1
user:        me
date:        Mon Oct 22 15:36:26 2012 +0200

changeset:   712:d5e8a62a7f5f  <- default, needs to stay
parent:      648:2bbcc01aa191
user:        me
date:        Wed Aug 22 16:21:09 2012 +0200
2
Don't use free-hand "drawing" - you have console commands and ability to paste commands output in question formatted (hg log or hg glog for tree here and at stackoverflow.com/questions/11982648/…, for example). For now, please, add output of hg heads with comment - which head is obsolete and must not exist (totally or only in push-target). Also read about -r option in push commandLazy Badger
Hi @LazyBadger, I can't provide you the output of log as there are much more commits than I described, and I also forgot the exact commands I executed in order to get to this state... Question updated to contain the output of heads. I don't understand your reference to -r option, how/why should it help?Nikola Knezevic
exact commands doesn't needed in this case - you (not I) have to see tree of devBranch ( from common parent of 807 and 820 to 826), define the possibility (and necessity) of merging devBranch's heads. Or just push -r f2033d695fcd will be enoughLazy Badger
@LazyBadger, if I try hg push -r f2033d695fcd --new-branch, I get abort: push creates new remote head 23853bbf68df on branch devBranch. This is what I'm trying to avoid.Nikola Knezevic
Merge at least this head (all will be better)Lazy Badger

2 Answers

7
votes

You can push only the one head you're interested in mercurial. For you that would mean doing:

hg push -r f2033d695fcd

If the destination repo has been updated you need to pull, merge, and re-push:

hg pull
hg up -r <remote head>
hg merge -r f2033d695fcd
hg ci
hg push
1
votes

I solved the problem, without pushing another head to the repo, and without merging 23853bbf68df onto newBranch. This is probably not the cleanest way to do it, but I will leave it as a reference. In a nutshell, I reconstructed the whole branch by taking all commits and re-applying them.

First, I killed the newBranch'es head 899344cfb145, by using strip on the first diverging revision I did:

hg strip -r 646 

Then, I produced email patches (couldn't play with mq) for all commits that are in newBranch, since it's inception:

hg export -g -r 797:808 -r 810 -r 815:822 -r 824:830 -o "%n-%m.patch"
  • 797:808 are the patches in newBranch that were in the rebased part of devBranch (1' commits from the original figure).
  • 810 and 815:822 are other patchs in newBranch. 811:814 belong to a different branch, so I had to exclude those.
  • 823 is a merge commit with default, so I skipped this one.
  • 824:830 are all the commits after the merge with default.

Now, I imported these patches on a new head of newBranch:

hg up -r 796
# there are 29 patches, applying till merge
hg import --bypass {01..21}*.patch
hg up tip
hg merge default
hg ci -m 'merging in default'
hg import --bypass {22..28}*.patch

Finally, I just stripped of the original head of newBranch.

hg strip -r 797

This may not work in every situation. During the merge, I had to resolve some conflicts, too, but pretty benign. Hope this helps someone.