+ } elsif ($new =~ /^0+$/) {
+ # Deletion of a branch
+ $subj .= ' Branch deleted';
+ print $out "Deleted branch $branch ($old).\n";
+ } else {
+ my $lca = `git merge-base $old $new`; die if $?;
+ chomp $lca;
+ if ($lca eq $old) {
+ # Fast forward ... scan all objects
+ my @commits = scan_commits($old, $new);
+ my @nonmerges = grep { @{$_->{parents}} == 1 } @commits;
+ @commits or return;
+
+ # Construct subject
+ # Try to recognize simple merges and display them as such
+ 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))) {
+ # Pushed a merge of the current branch with another local branch
+ $subj .= ' ' . $c0->{subject};
+ } elsif ($n0) {
+ # Otherwise take the subject of the first non-merge commit
+ $subj .= ' ' . $n0->{subject};
+ } else {
+ # If there is none, take the first merge
+ $subj .= ' ' . $c0->{subject};
+ }
+
+ print $out "Push to branch $branch ($old -> $new)\n\n";
+
+ # If there are multiple commits, mention that
+ if (@nonmerges > 1) {
+ $subj .= ' [' . (scalar @commits) . ' commits]';
+ print $out 'Pushed ', (scalar @commits), " commits. Overall diffstat:\n\n";
+ }
+
+ # Print an overall diffstat
+ system 'git', 'diff', '--stat', $old, $new;
+ print $out "\n";
+ my $pos_after_header = output_size($out);
+
+ # Show individual commits with diffs
+ system 'git', 'log', @rev_list_options, @diff_options, '-p', "$old..$new";
+
+ # If the file is too long, truncate it and print just a summary
+ if (defined($max_diff_size) && output_size($out) > $max_diff_size) {
+ $out->truncate($pos_after_header);
+ output_size($out);
+ print $out "Diff was too long, printing just a summary.\n\n";
+ system 'git', 'log', @rev_list_options, "$old..$new";
+ }
+ } elsif ($lca eq $new) {
+ # Rewind
+ $subj .= ' Branch rewound';
+ 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 "Commits from common ancestor:\n\n";
+ system 'git', 'rev-list', @rev_list_options, $new, "^$old";