Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit1b984d4

Browse files
committed
git_topo_order script, to match up commits across branches.
This script is intended to substitute for cvs2cl in generating releasenotes and scrutinizing what got back-patched to which branches.Script by me. Support for --since by Alex Hunsaker.
1 parent3977618 commit1b984d4

File tree

1 file changed

+155
-0
lines changed

1 file changed

+155
-0
lines changed

‎src/tools/git_topo_order

Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
#!/usr/bin/perl
2+
3+
#
4+
# Display all commits on active branches, merging together commits from
5+
# different branches that occur close together in time and with identical
6+
# log messages. Most of the time, such commits occur in the same order
7+
# on all branches, and we print them out in that order. However, if commit
8+
# A occurs before commit B on branch X and commit B occurs before commit A
9+
# on branch Y, then there's no ordering which is consistent with both
10+
# branches.
11+
#
12+
# When we encounter a situation where there's no single "best" commit to
13+
# print next, we print the one that involves the least distortion of the
14+
# commit order, summed across all branches. In the event of a further tie,
15+
# the commit from the newer branch prints first. It is best not to sort
16+
# based on timestamp, because git timestamps aren't necessarily in order
17+
# (since the timestamp is provided by the committer's machine), even though
18+
# for the portion of the history we imported from CVS, we expect that they
19+
# will be.
20+
#
21+
# Even though we don't use timestamps to order commits, it is used to
22+
# identify which commits happened at about the same time, for the purpose
23+
# of matching up commits from different branches.
24+
#
25+
26+
use strict;
27+
use warnings;
28+
require Date::Calc;
29+
require Getopt::Long;
30+
require IPC::Open2;
31+
32+
my@BRANCHES =qw(master REL9_0_STABLE REL8_4_STABLE REL8_3_STABLE
33+
REL8_2_STABLE REL8_1_STABLE REL8_0_STABLE REL7_4_STABLE);
34+
35+
my$since;
36+
Getopt::Long::GetOptions('since=s'=> \$since) || usage();
37+
usage()if@ARGV;
38+
39+
my@git =qw(git log --date=iso);
40+
push@git,'--since=' .$sinceifdefined$since;
41+
42+
my%all_commits;
43+
my%all_commits_by_branch;
44+
45+
my%commit;
46+
formy$branch (@BRANCHES) {
47+
my$commitnum = 0;
48+
IPC::Open2::open2(my$git_out,my$git_in,@git,"origin/$branch")
49+
||die"can't run@git origin/$branch:$!";
50+
while (my$line = <$git_out>) {
51+
if ($line =~/^commit\s+(.*)/) {
52+
push_commit(\%commit)if%commit;
53+
%commit = (
54+
'branch'=>$branch,
55+
'commit'=>$1,
56+
'message'=>'',
57+
'commitnum'=>$commitnum++,
58+
);
59+
}
60+
elsif ($line =~/^Author:\s+(.*)/) {
61+
$commit{'author'} =$1;
62+
}
63+
elsif ($line =~/^Date:\s+(.*)/) {
64+
$commit{'date'} =$1;
65+
}
66+
elsif ($line =~/^\s+/) {
67+
$commit{'message'} .=$line;
68+
}
69+
}
70+
}
71+
72+
my%position;
73+
formy$branch (@BRANCHES) {
74+
$position{$branch} = 0;
75+
}
76+
while (1) {
77+
my$best_branch;
78+
my$best_inversions;
79+
formy$branch (@BRANCHES) {
80+
my$leader =$all_commits_by_branch{$branch}->[$position{$branch}];
81+
nextif !defined$leader;
82+
my$inversions = 0;
83+
formy$branch2 (@BRANCHES) {
84+
if (defined$leader->{'branch_position'}{$branch2}) {
85+
$inversions +=$leader->{'branch_position'}{$branch2}
86+
-$position{$branch2};
87+
}
88+
}
89+
if (!defined$best_inversions ||$inversions <$best_inversions) {
90+
$best_branch =$branch;
91+
$best_inversions =$inversions;
92+
}
93+
}
94+
lastif !defined$best_branch;
95+
my$winner =
96+
$all_commits_by_branch{$best_branch}->[$position{$best_branch}];
97+
print$winner->{'header'};
98+
print"Commit-Order-Inversions:$best_inversions\n"
99+
if$best_inversions != 0;
100+
print$winner->{'message'};
101+
$winner->{'done'} = 1;
102+
formy$branch (@BRANCHES) {
103+
my$leader =$all_commits_by_branch{$branch}->[$position{$branch}];
104+
if (defined$leader &&$leader->{'done'}) {
105+
++$position{$branch};
106+
redo;
107+
}
108+
}
109+
}
110+
111+
subpush_commit {
112+
my ($c) =@_;
113+
my$ht = hash_commit($c);
114+
my$ts = parse_datetime($c->{'date'});
115+
my$cc;
116+
formy$candidate (@{$all_commits{$ht}}) {
117+
if (abs($ts -$candidate->{'timestamp'}) < 600
118+
&& !exists$candidate->{'branch_position'}{$c->{'branch'}})
119+
{
120+
$cc =$candidate;
121+
last;
122+
}
123+
}
124+
if (!defined$cc) {
125+
$cc = {
126+
'header'=>sprintf("Author:%s\n",$c->{'author'}),
127+
'message'=>$c->{'message'},
128+
'timestamp'=>$ts
129+
};
130+
push @{$all_commits{$ht}},$cc;
131+
}
132+
$cc->{'header'} .=sprintf"Branch:%s [%s]%s\n",
133+
$c->{'branch'},substr($c->{'commit'}, 0, 9),$c->{'date'};
134+
push @{$all_commits_by_branch{$c->{'branch'}}},$cc;
135+
$cc->{'branch_position'}{$c->{'branch'}} =
136+
-1+@{$all_commits_by_branch{$c->{'branch'}}};
137+
}
138+
139+
subhash_commit {
140+
my ($c) =@_;
141+
return$c->{'author'} ."\0" .$c->{'message'};
142+
}
143+
144+
subparse_datetime {
145+
my ($dt) =@_;
146+
$dt =~/^(\d\d\d\d)-(\d\d)-(\d\d)\s+(\d\d):(\d\d):(\d\d)/;
147+
return Date::Calc::Mktime($1,$2,$3,$4,$5,$6);
148+
}
149+
150+
subusage {
151+
printSTDERR<<EOM;
152+
Usage: git-topo-order [--since=SINCE]
153+
EOM
154+
exit 1;
155+
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp