Updating Your Mercurial Repository
By daniel on Apr 22, 2008
... while working on uncommitted changes.
Sometimes when you are working on a fix - or an RFE, you'd like to sync-up with your parent's repository and pull any changes it contains without having to commit your own work in progress. Here is my own recipe - direct from my mercurial cookbook.
First you will need to make sure that the mq and fetch extensions are enabled in your .hgrc file. Ok, you don't really need fetch - you can do with the pull/update/merge/commit sequence - but personally I like fetch better. To enable mq and fetch, simply put those two lines under [extensions] in your .hgrc:
[extensions] fetch= mq=
Although I am not very comfortable with mq, since I don't speak diff & patch fluently, I have found it very useful for this use case. I am sure that mq is much more powerful than what my clumsy usage use it for - but I am now rather comfortable with the way I use it in this use case.
The idea is as follows:
zipto create a zip file containing all the files in which you have uncommitted changes. This is just in case something goes wrong.
mqto create a patch file for those changes, and to unapply them so that you get back a clean repository in which you can pull the parent updates.
hg fetchto pull the changes from the parent repository.
- Use the patch generated by mq in order to reapply your uncommitted changes, leaving them uncommitted, just as they were before. This is the part that may fail, and we have saved a copy of the files you were working on in a zip just for that case.
Before you start this sequence however - make sure to add all the new files
you have created to mercurial. You can use
hg status -nu to list
all the files that are not tracked by mercurial yet. If any of these is part
of your changes, add it to mercurial using
hg add. This will make
sure that this file is also included in the patch that we will generate using mq
hg status -ma. Check that all the files listed are part of your changes and that nothing is missing. If everything is OK, choose a name for labelling your work in progress. Something without whitespaces in it of course - since we will use this name for our zip and patch files - let's say you've decided to name it MyChanges. When this is done, you are ready to roll!
# make a Zip of your changes - just to be safe # (Note: the command below is in bash syntax) zip -r MyChanges.zip $(hg status -nma) # create a patch containing your changes hg qnew -f MyChanges # 'unapply' the patch, leaving the repository with # no uncommitted changes. hg qpop -a # Now hg status should see no uncommitted changes. # and hg heads should see only one head (tip) # now pull & update & merge hg fetch # now reapply the patch, to get back your changes as # new uncommitted changes: gpatch -p 1 < .hg/patches/MyChanges
There should be no problem applying the patch created by mq in
.hg/patches/MyChanges provided that none of the
files you were working on was modified by someone else in the
parent repository. If one of these files had been modified by
someone else, then it is likely that the
will fail to update that file. If it does, it will create a
file.rej file for each file in which the patch
couldn't be applied.
So if any
.rej file is created by gpatch (don't worry,
it will tell you if it creates any), then you will need to merge your
changes in the correponding file manually. The easiest way to do that - unless you
speak diff and patch fluently, is to expand the
MyChanges.zip file somewhere else, and then use your favorite
interactive merge tool - for instance the good old filemerge
from Teamware, to reintroduce your changes in that file.
At the end - you should have an updated repository again containing your uncommitted changes - on which you can continue working as if nothing had happened.
If, after a while, you need to update again, you can redo that whole sequence. Just make sure to use a new name for your changes - for instance, MyChanges2.
Well, that's my own recipe. I realize I might not be using the full power of mq, but it has worked for me until now...
I hope it might help you too!