user1780424
user1780424

Reputation: 413

Split Mercurial Revision into two: (1) moving files, (2) edit over moved files

I have a commit where I moved the files into a different folder, and then made changes to those files.

I want to split this revision into two:

  1. Only the file moves
  2. the rest of modifications on those moved files.

How can I accomplish this with Mercurial/hg ?

I know I can move the current files to a different folder (e.g. folder -> backup_folder), then start from scratch and do the actual move and then hg commit it, and finally rename backup_folder -> folder and commit a new revision on top. But, I rather have an hg command that intelligibly splits it all based upon the "rename from/rename to" lines that hg log -vpr REV shows.

Upvotes: 2

Views: 87

Answers (1)

StayOnTarget
StayOnTarget

Reputation: 13008

This assumes the existing commits haven't yet been pushed anywhere else. If so, then this will not work properly because you can't modify history that is public.

Let's say your history looks like this:

A-B-*

where B has the move & modifications, and * is the current working directory.

Say B contains to results of copying from a/b/c/file1 to d/e/f/file2.

To retroactively split B into two parts:


Approach 1: "Pure" Mercurial (command line)

  1. hg up A

  2. hg revert -r B

    (At this point the working directory will contain both the file moves & file changes)

  3. For each moved & modified file:

    hg cat --output=a/b/c/file1 --rev=B d/e/f/file2

    (Now each of the moved files will have its original contents, but in the new location.)

  4. hg commit ... (creates B')

  5. hg revert -r B

    (which restores the file contents.)

  6. hg commit ... (creates C)

    So now your history looks like:

    A-B
     \
      B'-C-*
  1. hg strip B

    (or you could use hg prune if you also use histedit.)

    Leaving:

    A-B'-C-*

At #5 you could probably rebase as well, which should produce the same outcome and also disposes of the original commit B which other


Approach 2: TortoiseHG on Windows (mostly GUI)

I use TortoiseHG and also WinMerge as the visual diff tool. Given that setup, I think it would be quicker to do the same thing this way:

  1. In THG, right click on A, choose "Update"

  2. Right click on B, choose "Revert All Files"

  3. Open each moved & modified file in visual Diff (^D)

    • Revert all changes in the diff tool, save the file
  4. Commit ...

  5. Right click on B, choose "Revert All Files"

  6. Commit ...

  7. Right click on B, Modify History, Strip

Presumably THG with other diff tools, or not on Windows, would work similarly.


To address the question about using the log... if you look at the log like so:

hg log --git -vpr  revision#

it will contain lines like:

copy from a/b/c/file1
copy to d/e/f/file2

I know of no simple / direct way to get hg to read those lines and use them to reapply commands. And though this will enumerate all the copied files, just looking at commit B using any other means would do that also. So I don't think using the log gets you very far, unfortunately.

Upvotes: 1

Related Questions