Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hg almost committed to wrong branch

I have a changeset that is uncommitted. I noticed that I am currently on the wrong branch, so before I commit this, I would like to switch to the branch that I meant to be on, then commit.

How difficult is this to achieve in Hg?

like image 926
Davis Dimitriov Avatar asked Sep 14 '11 13:09

Davis Dimitriov


4 Answers

If there is a linear path between the current parent revision and the target revision, then you can just issue

hg update right-branch

and Mercurial will merge the changes in your working copy into the target revision.

This is done using the full merge tool machinery so things like renames are taken into account and you'll get a three-way merge program in case of conflicts. The shelve- and diff-based approaches lack this and requires you to fix conflicts by hand using .rej files. You can even see the current merge status with hg resolve --list and re-merge selected files since Mercurial makes the necessary backups for you.

If there is not a linear path, you will get this warning:

abort: crosses branches (merge branches or use --clean to discard changes)

You can then get what you want by first updating back to a common ancestor, and then updating forward again. I'm not 100% sure why we issue this warning, but searching the mailinglist archives should give you the answer if you're curious.

like image 128
Martin Geisler Avatar answered Oct 20 '22 14:10

Martin Geisler


If you'd like to do this without the shelve extension, do the following:

hg diff --git > ../work_in_progress.patch
hg up desired-branch
hg import --no-commit ../work_in_progress.patch

Where ../work_in_progress.patch can be any path you want (I usually store my patches just above my repository) and desired-branch is the branch you actually want to apply your changes to.

Note that any solution I've found starts to fall apart if the branch you are on and the branch you're going to are different enough that your patch doesn't apply smoothly. In that case, you start getting into having to manually resolve conflicts.

like image 43
Chris Phillips Avatar answered Oct 20 '22 15:10

Chris Phillips


If you're using TortoiseHg, it's very easy to achieve with the shelve ability of THG (http://tortoisehg.bitbucket.io/manual/2.9/shelve.html). In the commit dialog, just click the Shelve button (whose icon is a file with a Z superimposed) then the double right arrow to shelve all changes. Close the shelve dialog, update to the correct changeset, open the shelve dialog and click the double left arrow to unshelve them.

If you're not using THG, you can install the hgshelve extension (https://www.mercurial-scm.org/wiki/ShelveExtension), but I'm not familiar with it.

Seems you can also achieve the same result with Mercurial Queues (http://mercurial.808500.n3.nabble.com/Shelve-extension-td802439.html).

like image 32
mo. Avatar answered Oct 20 '22 14:10

mo.


Unfortunately Mercurial doesn't support shelving out of the box so you need to make a temporary commit and the transfer it to the proper branch using rebase or tramsplant or make a diff and apply it manually. You can also use a 3rd-party shelve extension, see https://www.mercurial-scm.org/wiki/ShelveExtension and https://www.mercurial-scm.org/wiki/AtticExtension

like image 1
wRAR Avatar answered Oct 20 '22 14:10

wRAR