X-Git-Url: http://mj.ucw.cz/gitweb/?a=blobdiff_plain;ds=sidebyside;f=update2;h=55e8a8e1c682e8bdf9c8e5389021978e72947bfd;hb=refs%2Fheads%2Fmaster;hp=bfea61cebe7afbc21d65c44f509d223514bd8e74;hpb=ee618b3f756846835b1da90445ec68c3dacb8a58;p=git-tools.git diff --git a/update2 b/update2 index bfea61c..55e8a8e 100755 --- a/update2 +++ b/update2 @@ -36,29 +36,37 @@ my @diff_options = ('-C'); sub update_ref($$$); +open ORIG_STDIN, '<&', \*STDIN; open ORIG_STDOUT, '>&', \*STDOUT; if (@ARGV) { - update_ref($ARGV[0], $ARGV[1], $ARGV[2]); #FIXME + update_ref($ARGV[0], $ARGV[1], $ARGV[2]); } else { - while () { + while () { chomp; my ($old, $new, $ref) = /^(\S+) (\S+) (.*)/ or die "Error parsing hook input ($_)\n"; update_ref($ref, $old, $new); } } -sub scan_branches($$) { +sub get_source($$) { my ($ref, $new) = @_; - # Is there any branch pointing to $new (other than $ref)? - for (`git branch -v --no-abbrev`) { + # Get branch (different from $ref) whose tip is $new + my @branches = (); + for (`git for-each-ref refs/heads`) { chomp; - my ($name, $sha) = /^..(\S+)\s+(\S+)/ or die; - if ($name ne $ref && $sha eq $new) { - return $name; + my ($sha, $type, $name) = m{^(\S+) (\S+)\trefs/heads/(\S+)$} or die; + if ((!defined($ref) || $name ne $ref) && $sha eq $new && $type eq 'commit') { + push @branches, $name; } } - return; + if (@branches == 1) { + return $branches[0]; + } elsif (@branches) { + return sprintf("%s [and %d other]", $branches[0], @branches-1); + } else { + return; + } } sub scan_commits($$) { @@ -97,7 +105,7 @@ sub update_branch($$$$$) if ($old =~ /^0+$/) { # Creation of a branch $subj .= ' Created branch'; - my $copy_of = scan_branches($branch, $new); + my $copy_of = get_source($branch, $new); if (defined $copy_of) { $subj .= " as a copy of $copy_of"; print $out "Created branch $branch as a copy of $copy_of ($new).\n"; @@ -123,10 +131,15 @@ sub update_branch($$$$$) my $c0 = $commits[0]; my $n0 = $nonmerges[0]; my $c0p = $c0->{parents}; + if (@{$c0p} == 2 && ($c0p->[0] eq $old || $c0p->[1] eq $old) && - $c0->{subject} =~ m{^\s*Merge branch '([^']*)' into (\S+)} && - (($1 eq $branch) != ($2 eq $branch))) { + ( + $c0->{subject} =~ m{^\s*Merge branch '([^']*)' into (\S+)} && + ($1 eq $branch) != ($2 eq $branch) + ) || ( + $c0->{subject} =~ m{^\s*Merge branch '([^']*)'( of |$)} + )) { # Pushed a merge of the current branch with another local branch $subj .= ' ' . $c0->{subject}; } elsif ($n0) { @@ -137,7 +150,7 @@ sub update_branch($$$$$) $subj .= ' ' . $c0->{subject}; } - print $out "Push to branch $branch ($old -> $new)\n\n"; + print $out "Push to branch $branch ($old..$new)\n\n"; # If there are multiple commits, mention that if (@nonmerges > 1) { @@ -163,12 +176,12 @@ sub update_branch($$$$$) } elsif ($lca eq $new) { # Rewind $subj .= ' Branch rewound'; - print $out "Rewound branch $branch ($old -> $new).\n\n"; + print $out "Rewound branch $branch ($old..$new).\n\n"; most_recent($new); } else { # Otherwise it is a rebase $subj .= ' Branch rebased'; - print $out "Rebased branch $branch ($old -> $new).\n\n"; + print $out "Rebased branch $branch ($old..$new).\n\n"; print $out "Commits from common ancestor:\n\n"; system 'git', 'rev-list', @rev_list_options, $new, "^$old"; } @@ -179,6 +192,32 @@ sub update_branch($$$$$) return 1; } +sub update_tag($$$$$) +{ + my ($tag, $old, $new, $out, $headers) = @_; + + my $subj = '[' . $subject_prefix . ']'; + if ($new =~ /^0+$/) { + $subj .= " Deleted tag $tag"; + print $out "Deleted tag $tag ($old).\n"; + } else { + my $copy_of = get_source(undef, $new); + my $cp = defined($copy_of) ? " to branch $copy_of" : ""; + if ($old =~ /^0+/) { + $subj .= " Created tag $tag$cp"; + print $out "Created tag $tag$cp ($new).\n\n"; + } else { + $subj .= " Changed tag $tag$cp"; + print $out "Changed tag $tag$cp ($old..$new).\n\n"; + } + most_recent($new); + } + + $headers->{'Subject'} = $subj; + $headers->{'X-Git-Tag'} = $tag; + return 1; +} + sub update_ref($$$) { my ($ref, $old, $new) = @_; @@ -199,6 +238,7 @@ sub update_ref($$$) my $send; if ($type eq 'heads') { $send = update_branch($name, $old, $new, $out, $headers); } + elsif ($type eq 'tags') { $send = update_tag($name, $old, $new, $out, $headers); } $out->close(); $send or return; @@ -211,6 +251,7 @@ sub update_ref($$$) '-x', '-e', 'set charset="utf-8"', '-e', 'set send_charset="us-ascii:iso-8859-2:utf-8"', + '-e', 'set record=', '-s', $headers->{'Subject'}, ); delete $headers->{'Subject'};