Further to this…
Model Problems
- P4 doesn’t merge renames correctly. Instead when you
merge a rename operation, it deletes the rename source in the
destination branch and copies the source branch’s version of the
renamed file(s). You have to manually re-do the rename every time
you merge across it - expensive if you are in a branch-heavy
environment.
Example
Create project:
$ mkdir -p trunk
$ echo initial > trunk/foo
$ p4 add trunk/foo
//depot/mtest/trunk/foo#1 - opened for add
$ p4 submit -d "initial trunk commit" trunk/...
Submitting change 14.
Locking 1 files ...
add //depot/mtest/trunk/foo#1
Change 14 submitted.
Branch project:
$ p4 integrate -d -t trunk/foo branch/foo
//depot/mtest/branch/foo#1 - branch/sync from //depot/mtest/trunk/foo#1
$ p4 submit -d "branch" branch/...
Submitting change 15.
Locking 1 files ...
branch //depot/mtest/branch/foo#1
Change 15 submitted.
Modify trunk:
$ p4 edit trunk/foo
//depot/mtest/trunk/foo#1 - opened for edit
$ echo additional >> trunk/foo
$ p4 submit -d "edited on trunk" trunk/...
Submitting change 16.
Locking 1 files ...
edit //depot/mtest/trunk/foo#2
Change 16 submitted.
Rename on branch:
$ p4 integrate -d -t branch/foo branch/subdir/foo
//depot/mtest/branch/subdir/foo#1 - branch/sync from //depot/mtest/branch/foo#1
$ p4 delete branch/foo
//depot/mtest/branch/foo#1 - opened for delete
$ p4 submit -d "renamed on branch" branch/...
Submitting change 17.
Locking 2 files ...
delete //depot/mtest/branch/foo#2
branch //depot/mtest/branch/subdir/foo#1
Change 17 submitted.
Attempt to update branch from trunk:
$ p4 integrate trunk/... branch/...
//depot/mtest/branch/foo - can't branch from //depot/mtest/trunk/foo#2 without -d or -Dt flag
...fair enough. But -Dt doesn't actually do what we want, and nor
do any of the other -D options (which are here all enabled via
-d):
$ p4 integrate -d -t trunk/... branch/...
//depot/mtest/branch/foo#2 - branch/sync from //depot/mtest/trunk/foo#2
$ p4 opened
//depot/mtest/branch/foo#2 - branch default change (text)
$ cat branch/foo
initial
additional
$ cat branch/subdir/foo
initial
p4 has not honored the rename. How about if we merge the branch back
onto the trunk instead?
$ p4 integrate -d -t branch/... trunk/...
//depot/mtest/trunk/foo#2 - delete from //depot/mtest/branch/foo#2
//depot/mtest/trunk/subdir/foo#1 - branch/sync from //depot/mtest/branch/subdir/foo#1
$ p4 opened
//depot/mtest/trunk/foo#2 - delete default change (text)
//depot/mtest/trunk/subdir/foo#1 - branch default change (text)
$ cat trunk/foo
cat: trunk/foo: No such file or directory
$ cat trunk/subdir/foo
initial
Going in this direction, p4 has thrown away the trunk changes.
With Bazaar…
Create project:
$ mkdir trunk
$ cd trunk
$ bzr init
$ echo initial > foo
$ bzr add foo
added foo
$ bzr ci -m "initial trunk commit" foo
Committing to: /home/richard/junk/bzr-mtest/trunk/
added foo
Committed revision 1.
Branch project:
$ cd ../
$ bzr clone trunk branch
Branched 1 revision(s).
Modify trunk:
$ cd trunk
$ echo additional >> foo
$ bzr ci -m "edited on trunk"
Committing to: /home/richard/junk/bzr-mtest/trunk/
modified foo
Committed revision 2.
Rename on branch:
$ cd ../branch
$ mkdir subdir
$ bzr add subdir
added subdir
$ bzr mv foo subdir/foo
foo => subdir/foo
$ bzr ci -m "renamed on branch"
Committing to: /home/richard/junk/bzr-mtest/branch/
added subdir
renamed foo => subdir/foo
Committed revision 2.
Update branch from trunk:
$ bzr merge ../trunk
M subdir/foo
All changes applied successfully.
$ cat subdir/foo
initial
additional
$ cat foo
cat: foo: No such file or directory
Or if we instead merged the rename from the branch back to the
trunk:
$ bzr merge ../branch
+N subdir/
R foo => subdir/foo
All changes applied successfully.
$ cat foo
cat: foo: No such file or directory
$ cat subdir/foo
initial
additional
How about with git?
Create project:
$ mkdir trunk
$ cd trunk
$ git init
Initialized empty Git repository in /home/richard/junk/git-mtest/trunk/.git/
$ touch foo
$ echo initial > foo
$ git add foo
$ git commit -m "initial trunk commit"
Created initial commit 74ec5ca: initial trunk commit
1 files changed, 1 insertions(+), 0 deletions(-)
create mode 100644 foo
$ cd ../
Branch project:
$ git clone trunk branch
Initialized empty Git repository in /home/richard/junk/git-mtest/branch/.git/
Edit on trunk:
$ echo modified >> foo
$ git add foo
$ git commit -m "edited on trunk"
Created commit b41980e: edited on trunk
1 files changed, 1 insertions(+), 0 deletions(-)
Rename on branch:
$ mkdir subdir
$ git mv foo subdir/foo
$ git commit -m "renamed on branch"
Created commit c957778: renamed on branch
1 files changed, 0 insertions(+), 0 deletions(-)
rename foo => subdir/foo (100%)
Update branch from trunk:
$ git pull
remote: Counting objects: 5, done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
From /home/richard/junk/git-mtest/trunk/
74ec5ca..b41980e master -> origin/master
Merge made by recursive.
subdir/foo | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
$ cat foo
cat: foo: No such file or directory
$ cat subdir/foo
initial
modified
Or updating the trunk from the branch (in this case using a stunt
branch of ‘branch’ that lacks the change just done above):
$ git pull ../branch otherway
remote: Counting objects: 3, done.
remote: Total 2 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (2/2), done.
From ../branch
* branch otherway -> FETCH_HEAD
Merge made by recursive.
foo => subdir/foo | 0
1 files changed, 0 insertions(+), 0 deletions(-)
rename foo => subdir/foo (100%)
$ cat foo
cat: foo: No such file or directory
$ cat subdir/foo
initial
modified