Jesper Noehr

Pythonista, RESTafarian, Binary Poet & Proud Bucketeer

Archive for the ‘hg’ Category

Mercurial powertip: Move changesets out of the way momentarily

with 2 comments

Sometimes you may be working in a repository, and want to momentarily move changesets out of the way. From what I can gather, you can get the same results as you get with “git stash”, but it offers much more.

Say that you have been working on an experimental feature, but need to fix a bug. You don’t want to sit and be careful only to commit the files modified by the bugfix, especially if the bugfix touches files you’ve already modified.

Your log could look like this:

$ hg log
changeset:   2:41009a6aa783
tag:         tip
summary:     adding B

changeset:   1:419ab519b195
summary:     adding C

changeset:   0:8f276b14c116
summary:     adding A



Now, changeset 1 & 2 are the experimental changes. You need to get rid of these before you can fix the bug.

It’s important that you have a “patch queue” repository inside your repository first, this is what “qinit” is for. Afterwards, we’ll import the changesets into the patch queue, using qimport:

$ hg qinit -c # tell hg to create a versioned patch queue in .hg/patches/
$ hg qimport -r 2:1


Now lets take a look at the log:

$ hg log
changeset:   2:41009a6aa783
tag:         qtip
tag:         2.diff
tag:         tip
summary:     adding B

changeset:   1:419ab519b195
tag:         1.diff
tag:         qbase
summary:     adding C

changeset:   0:8f276b14c116
tag:         qparent
summary:     adding A



The changesets are still there, but they’re a little different; They’ve been tagged with a couple of things – first, is the filename the changeset was saved as. In this case, your changes are in ‘.hg/patches/1.diff’ and ‘.hg/patches/2.diff’. Go on, have a look. There’s also some new semantic, namely ‘qbase’, ‘qtip’ and ‘qparent’. This is a way for MQ to keep track of the queue tip, the queue base and the parent.

But, you may notice that the changesets are still present. This is because they are “applied” to the repository. To get rid of them, we use qpop:

$ hg qpop -a # pop all patches from the stack
patch queue is now empty
$ hg log
changeset:   0:8f276b14c116
tag:         tip
summary:     adding A



Lovely. You can now see which patches are available via qseries:

$ hg qseries
1.diff
2.diff



To pop them back on the stack, you can use ‘qpush -a’. But first, we have a bug to fix:

$ echo 'D' > D
$ hg add D
$ hg ci -m "Adding D, which we'll pretend fixes a bug."



And the log:

$ hg log
changeset:   1:5d41625a80b5
tag:         tip
summary:     adding D (which is a bugfix)

changeset:   0:8f276b14c116
summary:     adding A



Now push that fix out, or whatever you want to. Time to get the experimental changesets back. We’ll use ‘qpush -a’ for that:

$ hg qpush -a
applying 1.diff
applying 2.diff
now at: 2.diff



You can run log to see what happened. Needless to say, your patches are there. Lets turn them back into normal changesets:

$ hg qfinish 3:2 # they're not 2:1 anymore, we have another changeset
                   in before them now, consult 'hg log' for details
$ hg log
changeset:   3:1a07541824d3
tag:         tip
summary:     adding B

changeset:   2:b4a1402f9b50
summary:     adding C

changeset:   1:5d41625a80b5
summary:     adding D (which is a bugfix)

changeset:   0:8f276b14c116
summary:     adding A



Et viola.

There’s much more you can do with MQ. If you’re only importing a single changeset, you can name the patch via ‘qimport -n’. You can give your patches to other people, and you can even push your patch queue around. ‘qimport’ will even import patches from outside your repository. You can move the order of patches around, you can do guards, .. MQ is really a wonderful addition to Mercurial.

Written by jespern

April 10th, 2009 at 12:04 pm

Posted in hg

Mercurial powertip: Un-add a file

without comments

Something that isn’t entirely clear from the use of Mercurial, is how to un-add a file you accidentally added, before you commit.


$ hg add data/
adding data/index.txt
adding data/README
adding data/hugefile.db

$ hg status
A data/index.txt
A data/README
A data/hugefile.db

Oops. Didn’t want to add ‘hugefile.db’. How to undo that add?


$ hg revert data/hugefile.db

Did that do the right thing?


$ ls data/hugefile.db # still there?
data/hugefile.db

$ hg status
A data/index.txt
A data/README
? data/hugefile.db

Yep!

Written by jespern

March 2nd, 2009 at 10:04 am

Posted in hg

Tagged with ,