Search code examples
mercurial

Retroactively use Mercurial rename


In my project, I haven't been using hg remove, hg mv or hg addremove due to ignorance. Consequently, every time I've renamed or moved a file, the history of that file has been messed up and now when I look at an individual file's history, I will only see a portion of the history.

What I'm looking for is a way to go back and retroactively fix all of those renaming mistakes so that the file history will stay together. What I imagine would be most likely is a way to edit the data in ".hg\store\data" to make this work. I've been experimenting, and I see the lines copy: and copyrev: in the data for the files I've renamed, so I suspect that has something to do with it.

Assume that I have control of the central repository and that there are no clones of it currently.


Solution

  • Summary:

    Since you have full control of the repo this can be 100% fixed using normal hg commands.

    The principle idea is to insert new changesets in the right places which effectively correct the original ones.


    Let's say your history looks like this:

    A-B-C-*
    

    (* is your working folder)

    and it was in B that you renamed a file in the filesystem without renaming it in hg.

    Do this:

    hg up A
    hg revert -r B --all
    hg mv oldfilename newfilename
    hg commit -m <message>
    

    The key here is using revert which is used to copy changes from a changeset into your working folder. This only works this way because you have updated to the predecessor of the changeset you are reverting.

    at this point your history looks like:

    A-B-C
     \
      B'-*
    

    where B' is the "corrected" variant of B. Continue with:

    hg rebase -s C -d B'
    

    and you have:

    A-B
     \
      B'-C-*
    

    You can now clean up by doing:

    hg strip B
    

    leaving just:

    A-B'-C-*
    

    Of course where I used revisions like B you need to type the actual revision # or hash.

    You could also use TortoiseHG or some other GUI to do a lot of these steps.