From 30d2e1005838c7ece353ef2ac269cfdc37e937be Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Sun, 26 Sep 2010 00:21:51 -0400 Subject: [PATCH] Fix some more bugs in git_changelog. 1. Don't forget the last (oldest) commit on the oldest branch. 2. When considering which commit to print next, if two alternatives have the same "distortion" score (which is actually the normal case, since generally the "distortion" is 0), then choose the later timestamp to print first. I don't know where Robert got the idea to ignore timestamps and sort by branch age, but it wasn't a good idea: the resulting ordering of commits was just plain bizarre anywhere that some branches had many fewer commits than others, which is the typical situation for us. --- src/tools/git_changelog | 37 +++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/src/tools/git_changelog b/src/tools/git_changelog index 3424cb72bd..766f66a4da 100755 --- a/src/tools/git_changelog +++ b/src/tools/git_changelog @@ -5,24 +5,19 @@ # # Display all commits on active branches, merging together commits from # different branches that occur close together in time and with identical -# log messages. Most of the time, such commits occur in the same order -# on all branches, and we print them out in that order. However, if commit -# A occurs before commit B on branch X and commit B occurs before commit A -# on branch Y, then there's no ordering which is consistent with both -# branches. +# log messages. +# +# Most of the time, matchable commits occur in the same order on all branches, +# and we print them out in that order. However, if commit A occurs before +# commit B on branch X and commit B occurs before commit A on branch Y, then +# there's no ordering which is consistent with both branches. # # When we encounter a situation where there's no single "best" commit to # print next, we print the one that involves the least distortion of the -# commit order, summed across all branches. In the event of a further tie, -# the commit from the newer branch prints first. It is best not to sort -# based on timestamp, because git timestamps aren't necessarily in order -# (since the timestamp is provided by the committer's machine), even though -# for the portion of the history we imported from CVS, we expect that they -# will be. -# -# Even though we don't use timestamps to order commits, they are used to -# identify which commits happened at about the same time, for the purpose -# of matching up commits from different branches. +# commit order, summed across all branches. In the event of a tie on the +# distortion measure (which is actually the common case: normally, the +# distortion is zero), we choose the commit with latest timestamp. If +# that's a tie too, the commit from the newer branch prints first. # use strict; @@ -48,12 +43,12 @@ push @git, '--since=' . $since if defined $since; my %all_commits; my %all_commits_by_branch; -my %commit; for my $branch (@BRANCHES) { - my $commitnum = 0; my $pid = IPC::Open2::open2(my $git_out, my $git_in, @git, "origin/$branch") || die "can't run @git origin/$branch: $!"; + my $commitnum = 0; + my %commit; while (my $line = <$git_out>) { if ($line =~ /^commit\s+(.*)/) { push_commit(\%commit) if %commit; @@ -74,6 +69,7 @@ for my $branch (@BRANCHES) { $commit{'message'} .= $line; } } + push_commit(\%commit) if %commit; waitpid($pid, 0); my $child_exit_status = $? >> 8; die "@git origin/$branch failed" if $child_exit_status != 0; @@ -87,6 +83,7 @@ for my $branch (@BRANCHES) { while (1) { my $best_branch; my $best_inversions; + my $best_timestamp; for my $branch (@BRANCHES) { my $leader = $all_commits_by_branch{$branch}->[$position{$branch}]; next if !defined $leader; @@ -97,9 +94,13 @@ while (1) { - $position{$branch2}; } } - if (!defined $best_inversions || $inversions < $best_inversions) { + if (!defined $best_inversions || + $inversions < $best_inversions || + ($inversions == $best_inversions && + $leader->{'timestamp'} > $best_timestamp)) { $best_branch = $branch; $best_inversions = $inversions; + $best_timestamp = $leader->{'timestamp'}; } } last if !defined $best_branch;