Search code examples
mercurial

Mercurial: Move a modified file between commits


Let's say I have the following commit history:

A - newest
B
C - oldest

I have changed a file foo in B, but I want to move the change from B to A.

How can I do that with hg?


Solution

  • There are several different ways that I can think of. Both have some moderate user requirements (please make sure you have backed up or pushed to a non-publishing repository first).

    1 ) Use histedit and amend (requires that each extensions be enabled).

    - copy file you wish to move to a safe location
    - run hg histedit and edit changeset b and restore file to its original state
    - run hg histedit --continue to commit changes.
    - copy file from safe location to repository
    - run hg amend to append file to changeset A
    

    2 ) Use split and histedit.

    - run hg split -r b
    
        - split out all but the file you wish to move into a new changeset
    
        - create a new changeset onto of that containing the fie (give it a temporary description)
    
    - run hg histedit
    
        - move the temp change above A
    
        - roll the temp change into A
    

    3 ) Use hg-evolve uncommit / amend. While this is a somewhat advanced method, I much prefer this one myself.

    - run hg update B
    
    - run hg uncommit and select the file you wish to move.
    
    - run hg evolve to correct the stack
    
    - run hg update A
    
        Note: if you get a warning about needing to use --clean use hg shelve before
                running the update followed by hg unshelve afterwords.
    
    - run hg amend to add file to change A
    

    4 ) Use hg uncommit all contents of changesets A and B and then recommit using hg commit -i to reassemble the changesets with the desired content.

    There are likely a number of other ways, but this is what came to me.