]>
Commit | Line | Data |
---|---|---|
c8b48ba4 JH |
1 | #!/usr/bin/perl -w |
2 | # | |
3 | # Copyright (c) 2005 Junio C Hamano | |
4 | # | |
5 | # Read .git/FETCH_HEAD and make a human readable merge message | |
6 | # by grouping branches and tags together to form a single line. | |
7 | ||
8 | use strict; | |
9 | ||
10 | my @src; | |
11 | my %src; | |
12 | sub andjoin { | |
13 | my ($label, $labels, $stuff) = @_; | |
14 | my $l = scalar @$stuff; | |
15 | my $m = ''; | |
16 | if ($l == 0) { | |
17 | return (); | |
18 | } | |
19 | if ($l == 1) { | |
20 | $m = "$label$stuff->[0]"; | |
21 | } | |
22 | else { | |
23 | $m = ("$labels" . | |
24 | join (', ', @{$stuff}[0..$l-2]) . | |
25 | " and $stuff->[-1]"); | |
26 | } | |
27 | return ($m); | |
28 | } | |
29 | ||
1cb30387 | 30 | sub repoconfig { |
a92c73ec | 31 | my ($val) = qx{git-repo-config --get merge.summary}; |
1cb30387 JH |
32 | return $val; |
33 | } | |
34 | ||
2b020455 | 35 | sub current_branch { |
a92c73ec | 36 | my ($bra) = qx{git-symbolic-ref HEAD}; |
a15f4331 | 37 | chomp($bra); |
2b020455 JH |
38 | $bra =~ s|^refs/heads/||; |
39 | if ($bra ne 'master') { | |
40 | $bra = " into $bra"; | |
41 | } else { | |
42 | $bra = ""; | |
43 | } | |
2b020455 | 44 | return $bra; |
1cb30387 JH |
45 | } |
46 | ||
47 | sub shortlog { | |
d37a1ed7 | 48 | my ($tip) = @_; |
a92c73ec | 49 | my @result; |
bbe60241 | 50 | foreach ( qx{git-log --no-merges --topo-order --pretty=oneline $tip ^HEAD} ) { |
1cb30387 JH |
51 | s/^[0-9a-f]{40}\s+//; |
52 | push @result, $_; | |
53 | } | |
a92c73ec | 54 | die "git-log failed\n" if $?; |
1cb30387 JH |
55 | return @result; |
56 | } | |
57 | ||
58 | my @origin = (); | |
c8b48ba4 | 59 | while (<>) { |
1cb30387 | 60 | my ($bname, $tname, $gname, $src, $sha1, $origin); |
c8b48ba4 | 61 | chomp; |
1cb30387 JH |
62 | s/^([0-9a-f]*) //; |
63 | $sha1 = $1; | |
05dd8e2e JH |
64 | next if (/^not-for-merge/); |
65 | s/^ //; | |
c8b48ba4 JH |
66 | if (s/ of (.*)$//) { |
67 | $src = $1; | |
68 | } else { | |
69 | # Pulling HEAD | |
70 | $src = $_; | |
71 | $_ = 'HEAD'; | |
72 | } | |
73 | if (! exists $src{$src}) { | |
74 | push @src, $src; | |
75 | $src{$src} = { | |
76 | BRANCH => [], | |
77 | TAG => [], | |
687b8be8 | 78 | R_BRANCH => [], |
c8b48ba4 JH |
79 | GENERIC => [], |
80 | # &1 == has HEAD. | |
81 | # &2 == has others. | |
82 | HEAD_STATUS => 0, | |
83 | }; | |
84 | } | |
85 | if (/^branch (.*)$/) { | |
1cb30387 | 86 | $origin = $1; |
c8b48ba4 JH |
87 | push @{$src{$src}{BRANCH}}, $1; |
88 | $src{$src}{HEAD_STATUS} |= 2; | |
89 | } | |
90 | elsif (/^tag (.*)$/) { | |
1cb30387 | 91 | $origin = $_; |
c8b48ba4 JH |
92 | push @{$src{$src}{TAG}}, $1; |
93 | $src{$src}{HEAD_STATUS} |= 2; | |
94 | } | |
687b8be8 EW |
95 | elsif (/^remote branch (.*)$/) { |
96 | $origin = $1; | |
97 | push @{$src{$src}{R_BRANCH}}, $1; | |
98 | $src{$src}{HEAD_STATUS} |= 2; | |
99 | } | |
c8b48ba4 | 100 | elsif (/^HEAD$/) { |
1cb30387 | 101 | $origin = $src; |
c8b48ba4 JH |
102 | $src{$src}{HEAD_STATUS} |= 1; |
103 | } | |
104 | else { | |
105 | push @{$src{$src}{GENERIC}}, $_; | |
106 | $src{$src}{HEAD_STATUS} |= 2; | |
1cb30387 JH |
107 | $origin = $src; |
108 | } | |
109 | if ($src eq '.' || $src eq $origin) { | |
110 | $origin =~ s/^'(.*)'$/$1/; | |
111 | push @origin, [$sha1, "$origin"]; | |
112 | } | |
113 | else { | |
114 | push @origin, [$sha1, "$origin of $src"]; | |
c8b48ba4 JH |
115 | } |
116 | } | |
117 | ||
118 | my @msg; | |
119 | for my $src (@src) { | |
120 | if ($src{$src}{HEAD_STATUS} == 1) { | |
121 | # Only HEAD is fetched, nothing else. | |
122 | push @msg, $src; | |
123 | next; | |
124 | } | |
125 | my @this; | |
126 | if ($src{$src}{HEAD_STATUS} == 3) { | |
127 | # HEAD is fetched among others. | |
128 | push @this, andjoin('', '', ['HEAD']); | |
129 | } | |
130 | push @this, andjoin("branch ", "branches ", | |
131 | $src{$src}{BRANCH}); | |
687b8be8 EW |
132 | push @this, andjoin("remote branch ", "remote branches ", |
133 | $src{$src}{R_BRANCH}); | |
c8b48ba4 JH |
134 | push @this, andjoin("tag ", "tags ", |
135 | $src{$src}{TAG}); | |
136 | push @this, andjoin("commit ", "commits ", | |
137 | $src{$src}{GENERIC}); | |
138 | my $this = join(', ', @this); | |
139 | if ($src ne '.') { | |
05dd8e2e | 140 | $this .= " of $src"; |
c8b48ba4 JH |
141 | } |
142 | push @msg, $this; | |
143 | } | |
2b020455 JH |
144 | |
145 | my $into = current_branch(); | |
146 | ||
147 | print "Merge ", join("; ", @msg), $into, "\n"; | |
1cb30387 JH |
148 | |
149 | if (!repoconfig) { | |
150 | exit(0); | |
151 | } | |
152 | ||
153 | # We limit the merge message to the latst 20 or so per each branch. | |
154 | my $limit = 20; | |
155 | ||
156 | for (@origin) { | |
157 | my ($sha1, $name) = @$_; | |
d37a1ed7 | 158 | my @log = shortlog($sha1); |
1cb30387 JH |
159 | if ($limit + 1 <= @log) { |
160 | print "\n* $name: (" . scalar(@log) . " commits)\n"; | |
161 | } | |
162 | else { | |
163 | print "\n* $name:\n"; | |
164 | } | |
165 | my $cnt = 0; | |
166 | for my $log (@log) { | |
167 | if ($limit < ++$cnt) { | |
168 | print " ...\n"; | |
169 | last; | |
170 | } | |
171 | print " $log"; | |
172 | } | |
173 | } |