Reputation: 1824
I'm trying to find out how to move several files in mercurial from one directory to another in all branches at once. The idea is that i have some files in a directory
a/some_file
which should be moved to
b/a/some_file
but do this in the branchstructure
10 9
| |
| 8
| |
|____/
7
|
...
to keep in mind is that some of the files in node 9 already have changed but should also be moved upwards one directory. Also I would like to add some files at node 7 so that they exist in both branches. But the important thing is to move the files.
Upvotes: 0
Views: 122
Reputation: 1848
Renames propagate across merges, so if you check out the files at changeset 7, rename them there and then merge the rename change to the rest of the branches, Mercurial should do the right thing.
See for example what happens in the following trace of commands. I start by creating a test repository:
saturn:/tmp$ hg init test
saturn:/tmp$ cd test
Then, I make sure that a file called 'foo.txt' exists at the toplevel directory on a branch called br.7
:
saturn:/tmp/test$ echo foo > foo.txt
saturn:/tmp/test$ hg commit -Am 'add foo'
adding foo.txt
saturn:/tmp/test$ hg branch br.7
marked working directory as branch br.7
(branches are permanent and global, did you want a bookmark?)
saturn:/tmp/test$ hg commit -m 'br.7 opened'
Then I fork two other branches, br.8
and br.9
from the latest changeset of the `br.7' branch:
saturn:/tmp/test$ hg up -C br.7
0 files updated, 0 files merged, 0 files removed, 0 files unresolved
saturn:/tmp/test$ hg branch br.8
marked working directory as branch br.8
(branches are permanent and global, did you want a bookmark?)
saturn:/tmp/test$ hg commit -m 'br.8 opened'
saturn:/tmp/test$ hg up -C br.7
0 files updated, 0 files merged, 0 files removed, 0 files unresolved
saturn:/tmp/test$ hg branch br.9
marked working directory as branch br.9
(branches are permanent and global, did you want a bookmark?)
saturn:/tmp/test$ hg commit -m 'br.9 opened'
Now the changeset graph looks like this:
saturn:/tmp/test$ hg log --graph --style=compact
@ 3[tip]:1 f3f155b61aa8 2013-01-09 23:48 +0100 gkeramidas
| br.9 opened
|
| o 2 ad3b03105da7 2013-01-09 23:48 +0100 gkeramidas
|/ br.8 opened
|
o 1 9cfed898c77b 2013-01-09 23:48 +0100 gkeramidas
| br.7 opened
|
o 0 9a6f15da68d7 2013-01-09 23:47 +0100 gkeramidas
add foo
So if I try renaming the file in branch br.7
first and then merge the rename upwards, here's what happens:
saturn:/tmp/test$ hg up -C br.7
0 files updated, 0 files merged, 0 files removed, 0 files unresolved
saturn:/tmp/test$ mkdir subdir
saturn:/tmp/test$ hg rename foo.txt subdir/foo.txt
saturn:/tmp/test$ hg commit -m 'Rename foo.txt'
saturn:/tmp/test$ hg branches
br.7 4:d57b57b98f19
br.9 3:f3f155b61aa8
br.8 2:ad3b03105da7
default 0:9a6f15da68d7 (inactive)
Then, finally, I merge the rename changeset from branch br.7
to the higher branches:
saturn:/tmp/test$ hg up -C br.8
1 files updated, 0 files merged, 1 files removed, 0 files unresolved
saturn:/tmp/test$ hg merge br.7
1 files updated, 0 files merged, 1 files removed, 0 files unresolved
(branch merge, don't forget to commit)
and the result of the merge looks like this in git-style diff output:
saturn:/tmp/test$ hg diff --git
diff --git a/foo.txt b/foo.txt
deleted file mode 100644
--- a/foo.txt
+++ /dev/null
@@ -1,1 +0,0 @@
-foo
diff --git a/subdir/foo.txt b/subdir/foo.txt
--- /dev/null
+++ b/subdir/foo.txt
@@ -0,0 +1,1 @@
+foo
If I commit this change, the history now looks like this:
saturn:/tmp/test$ hg log --graph --style=compact
@ 5[tip]:2,4 22b095e35b43 2013-01-10 00:02 +0100 gkeramidas
|\ Merge rename of foo.txt
| |
| o 4:1 d57b57b98f19 2013-01-09 23:49 +0100 gkeramidas
| | Rename foo.txt
| |
| | o 3:1 f3f155b61aa8 2013-01-09 23:48 +0100 gkeramidas
| |/ br.9 opened
| |
o | 2 ad3b03105da7 2013-01-09 23:48 +0100 gkeramidas
|/ br.8 opened
|
o 1 9cfed898c77b 2013-01-09 23:48 +0100 gkeramidas
| br.7 opened
|
o 0 9a6f15da68d7 2013-01-09 23:47 +0100 gkeramidas
add foo
Notice how the rename looks like a real actual 'merge' operation now, and see how log --copies can go back through the rename operation to the original change that added foo.txt
in this output:
saturn:/tmp/test$ hg log --copies --style=compact foo.txt subdir/foo.txt
4:1 d57b57b98f19 2013-01-09 23:49 +0100 gkeramidas
Rename foo.txt
0 9a6f15da68d7 2013-01-09 23:47 +0100 gkeramidas
add foo
This way, you can have a single changeset (changeset d57b57b98f19 in this example) that does the rename operation at the oldest possible place, and you can merge this changeset to all upper branches too. You'd still have to do each branch separately, but I like the idea of being able to track all of: what was renamed, who did the rename, when it happened and when it was merged to a derivative branch.
Upvotes: 1