ewx

Another thing that annoys me about Perforce

Jul 03, 2010 20:43


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

geek, software development

Previous post Next post
Up