Code

git-svn: ignore changeless commits when checking for a cherry-pick
authorAndrew Myrick <amyrick@apple.com>
Thu, 7 Jan 2010 00:25:21 +0000 (16:25 -0800)
committerEric Wong <normalperson@yhbt.net>
Sat, 23 Jan 2010 11:23:03 +0000 (03:23 -0800)
Update git-svn to ignore commits that do not change the tree when it is
deciding if an svn merge ticket represents a real branch merge or just a
cherry-pick.

Consider the following integration model in the svn repository:

   F---G  branch1
  /     \
 D  tag1 \   E  tag2
/         \ /
A---B      C  trunk

branch1 is merged to trunk in commit C.

With this patch, git-svn will correctly identify branch1 as a proper merge
parent, instead of incorrectly ignoring it as a cherry-pick.

Signed-off-by: Andrew Myrick <amyrick@apple.com>
Acked-by: Sam Vilain <sam@vilain.net>
Acked-by: Eric Wong <normalperson@yhbt.net>
git-svn.perl

index 650c9e5f02ead07351629d6572e82c3a9ac7ef92..947184afcfe2d9ac49c9bfc5c0fb0fa3538b83fa 100755 (executable)
@@ -3052,12 +3052,36 @@ sub check_cherry_pick {
        for my $range ( @ranges ) {
                delete @commits{_rev_list($range)};
        }
+       for my $commit (keys %commits) {
+               if (has_no_changes($commit)) {
+                       delete $commits{$commit};
+               }
+       }
        return (keys %commits);
 }
 
+sub has_no_changes {
+       my $commit = shift;
+
+       my @revs = split / /, command_oneline(
+               qw(rev-list --parents -1 -m), $commit);
+
+       # Commits with no parents, e.g. the start of a partial branch,
+       # have changes by definition.
+       return 1 if (@revs < 2);
+
+       # Commits with multiple parents, e.g a merge, have no changes
+       # by definition.
+       return 0 if (@revs > 2);
+
+       return (command_oneline("rev-parse", "$commit^{tree}") eq
+               command_oneline("rev-parse", "$commit~1^{tree}"));
+}
+
 BEGIN {
        memoize 'lookup_svn_merge';
        memoize 'check_cherry_pick';
+       memoize 'has_no_changes';
 }
 
 sub parents_exclude {