Search code examples
mercurial

Recovering commits lost after "hg strip"


I have this Mercurial repository where I keep a counter:

$ echo 1 > count
$ hg add count 
$ hg com -m 'incrementing to 1'
$ echo 2 > count
$ hg com -m 'incrementing to 2'

So far so good, but then I committed a mistake:

$ hg com -m 'incrementing to 3'

So I use hg strip to revert this last commit:

$ hg strip --keep -r -2
saved backup bundle to /home/adam/sandbox/count/.hg/strip-backup/bda856a578bf-ff2b025f-backup.hg

Unbeknownst to me, I have committed another, bigger mistake! I stripped the two topmost commits, and I just wanted to strip the topmost one:

$ hg log
changeset:   0:7b5533cf962a
tag:         tip
user:        Adam Victor Nazareth Brandizzi <brandizzi@gmail.com>
date:        Wed May 15 08:00:27 2019 -0300
summary:     incrementing to 1

How I get my commits back?

NOTE: this is a contrived example of a case were I needed to use hg strip. No need to wasting time pointing out there are alternatives etc.


Solution

  • As I've learned from this message in Mercurial's mailing list, the solution is quite straightforward. Note that when I ran hg strip --keep -r -2 I got this line in the output:

    saved backup bundle to /home/adam/sandbox/count/.hg/strip-backup/bda856a578bf-ff2b025f-backup.hg
    

    So, basically, Mercurial made a backup of the original history! Now I just need to pull from it:

    $ hg pull /home/adam/sandbox/count/.hg/strip-backup/bda856a578bf-ff2b025f-backup.hg
    pulling from /home/adam/sandbox/count/.hg/strip-backup/bda856a578bf-ff2b025f-backup.hg
    searching for changes
    adding changesets
    adding manifests
    adding file changes
    added 2 changesets with 2 changes to 1 files
    (run 'hg update' to get a working copy)
    $ hg update
    1 files updated, 0 files merged, 0 files removed, 0 files unresolved
    

    My file is back to the original state...

    $ cat count 
    66
    

    ...as well as my history:

    $ hg log
    changeset:   2:fc4d1cc18a4b
    tag:         tip
    user:        Adam Victor Nazareth Brandizzi <brandizzi@gmail.com>
    date:        Wed May 15 08:00:51 2019 -0300
    summary:     incrementing to 3
    
    changeset:   1:bda856a578bf
    user:        Adam Victor Nazareth Brandizzi <brandizzi@gmail.com>
    date:        Wed May 15 08:00:38 2019 -0300
    summary:     incrementing to 2
    
    changeset:   0:7b5533cf962a
    user:        Adam Victor Nazareth Brandizzi <brandizzi@gmail.com>
    date:        Wed May 15 08:00:27 2019 -0300
    summary:     incrementing to 1
    

    Now I can call the right strip command (hg strip --keep -r -1).

    What if we do not have the backup file name anymore?

    You may have lost the backup file name (it did happen to me!) but you can find it in $YOUR_REPO/.hg/strip-backup. If you have many backups, just list them sorted by time, descending:

    $ ls -tl .hg/strip-backup/
    total 4
    -rw-rw-r-- 1 adam adam 754 May 15 08:10 bda856a578bf-ff2b025f-backup.hg    
    -rw-rw-r-- 1 adam adam 754 May 15 08:02 02ac79859dd0-0902f53b-backup.hg
    

    The last one is probably the one you want.