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?
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.
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.
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).
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With