Merge branch 'ab/mailmap'
[git] / t / t4201-shortlog.sh
1 #!/bin/sh
2 #
3 # Copyright (c) 2006 Johannes E. Schindelin
4 #
5
6 test_description='git shortlog
7 '
8
9 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
10 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
11
12 . ./test-lib.sh
13
14 test_expect_success 'setup' '
15         test_tick &&
16         echo 1 >a1 &&
17         git add a1 &&
18         tree=$(git write-tree) &&
19         commit=$(printf "%s\n" "Test" "" | git commit-tree "$tree") &&
20         git update-ref HEAD "$commit" &&
21
22         echo 2 >a1 &&
23         git commit --quiet -m "This is a very, very long first line for the commit message to see if it is wrapped correctly" a1 &&
24
25         # test if the wrapping is still valid
26         # when replacing all is by treble clefs.
27         echo 3 >a1 &&
28         git commit --quiet -m "$(
29                 echo "This is a very, very long first line for the commit message to see if it is wrapped correctly" |
30                 sed "s/i/1234/g" |
31                 tr 1234 "\360\235\204\236")" a1 &&
32
33         # now fsck up the utf8
34         git config i18n.commitencoding non-utf-8 &&
35         echo 4 >a1 &&
36         git commit --quiet -m "$(
37                 echo "This is a very, very long first line for the commit message to see if it is wrapped correctly" |
38                 sed "s/i/1234/g" |
39                 tr 1234 "\370\235\204\236")" a1 &&
40
41         echo 5 >a1 &&
42         git commit --quiet -m "a                                                                12      34      56      78" a1 &&
43
44         echo 6 >a1 &&
45         git commit --quiet -m "Commit by someone else" \
46                 --author="Someone else <not!me>" a1 &&
47
48         cat >expect.template <<-\EOF
49         A U Thor (5):
50               SUBJECT
51               SUBJECT
52               SUBJECT
53               SUBJECT
54               SUBJECT
55
56         Someone else (1):
57               SUBJECT
58
59         EOF
60 '
61
62 fuzz() {
63         file=$1 &&
64         sed "
65                         s/$OID_REGEX/OBJECT_NAME/g
66                         s/$_x35/OBJID/g
67                         s/^ \{6\}[CTa].*/      SUBJECT/g
68                         s/^ \{8\}[^ ].*/        CONTINUATION/g
69                 " <"$file" >"$file.fuzzy" &&
70         sed "/CONTINUATION/ d" <"$file.fuzzy"
71 }
72
73 test_expect_success 'default output format' '
74         git shortlog HEAD >log &&
75         fuzz log >log.predictable &&
76         test_cmp expect.template log.predictable
77 '
78
79 test_expect_success 'pretty format' '
80         sed s/SUBJECT/OBJECT_NAME/ expect.template >expect &&
81         git shortlog --format="%H" HEAD >log &&
82         fuzz log >log.predictable &&
83         test_cmp expect log.predictable
84 '
85
86 test_expect_success '--abbrev' '
87         sed s/SUBJECT/OBJID/ expect.template >expect &&
88         git shortlog --format="%h" --abbrev=35 HEAD >log &&
89         fuzz log >log.predictable &&
90         test_cmp expect log.predictable
91 '
92
93 test_expect_success 'output from user-defined format is re-wrapped' '
94         sed "s/SUBJECT/two lines/" expect.template >expect &&
95         git shortlog --format="two%nlines" HEAD >log &&
96         fuzz log >log.predictable &&
97         test_cmp expect log.predictable
98 '
99
100 test_expect_success !MINGW 'shortlog wrapping' '
101         cat >expect <<\EOF &&
102 A U Thor (5):
103       Test
104       This is a very, very long first line for the commit message to see if
105          it is wrapped correctly
106       Th𝄞s 𝄞s a very, very long f𝄞rst l𝄞ne for the comm𝄞t message to see 𝄞f
107          𝄞t 𝄞s wrapped correctly
108       Thø\9d\84\9es ø\9d\84\9es a very, very long fø\9d\84\9erst lø\9d\84\9ene for the commø\9d\84\9et
109          message to see ø\9d\84\9ef ø\9d\84\9et ø\9d\84\9es wrapped correctly
110       a                                                         12      34
111          56     78
112
113 Someone else (1):
114       Commit by someone else
115
116 EOF
117         git shortlog -w HEAD >out &&
118         test_cmp expect out
119 '
120
121 test_expect_success !MINGW 'shortlog from non-git directory' '
122         git log --no-expand-tabs HEAD >log &&
123         GIT_DIR=non-existing git shortlog -w <log >out &&
124         test_cmp expect out
125 '
126
127 test_expect_success !MINGW 'shortlog can read --format=raw output' '
128         git log --format=raw HEAD >log &&
129         GIT_DIR=non-existing git shortlog -w <log >out &&
130         test_cmp expect out
131 '
132
133 test_expect_success 'shortlog from non-git directory refuses extra arguments' '
134         test_must_fail env GIT_DIR=non-existing git shortlog foo 2>out &&
135         test_i18ngrep "too many arguments" out
136 '
137
138 test_expect_success 'shortlog should add newline when input line matches wraplen' '
139         cat >expect <<\EOF &&
140 A U Thor (2):
141       bbbbbbbbbbbbbbbbbb: bbbbbbbb bbb bbbb bbbbbbb bb bbbb bbb bbbbb bbbbbb
142       aaaaaaaaaaaaaaaaaaaaaa: aaaaaa aaaaaaaaaa aaaa aaaaaaaa aa aaaa aa aaa
143
144 EOF
145         git shortlog -w >out <<\EOF &&
146 commit 0000000000000000000000000000000000000001
147 Author: A U Thor <author@example.com>
148 Date:   Thu Apr 7 15:14:13 2005 -0700
149
150     aaaaaaaaaaaaaaaaaaaaaa: aaaaaa aaaaaaaaaa aaaa aaaaaaaa aa aaaa aa aaa
151
152 commit 0000000000000000000000000000000000000002
153 Author: A U Thor <author@example.com>
154 Date:   Thu Apr 7 15:14:13 2005 -0700
155
156     bbbbbbbbbbbbbbbbbb: bbbbbbbb bbb bbbb bbbbbbb bb bbbb bbb bbbbb bbbbbb
157
158 EOF
159         test_cmp expect out
160 '
161
162 iconvfromutf8toiso88591() {
163         printf "%s" "$*" | iconv -f UTF-8 -t ISO8859-1
164 }
165
166 DSCHO="Jöhännës \"Dschö\" Schindëlin"
167 DSCHOE="$DSCHO <Johannes.Schindelin@gmx.de>"
168 MSG1="set a1 to 2 and some non-ASCII chars: Äßø"
169 MSG2="set a1 to 3 and some non-ASCII chars: áæï"
170 cat > expect << EOF
171 $DSCHO (2):
172       $MSG1
173       $MSG2
174
175 EOF
176
177 test_expect_success !MINGW 'shortlog encoding' '
178         git reset --hard "$commit" &&
179         git config --unset i18n.commitencoding &&
180         echo 2 > a1 &&
181         git commit --quiet -m "$MSG1" --author="$DSCHOE" a1 &&
182         git config i18n.commitencoding "ISO8859-1" &&
183         echo 3 > a1 &&
184         git commit --quiet -m "$(iconvfromutf8toiso88591 "$MSG2")" \
185                 --author="$(iconvfromutf8toiso88591 "$DSCHOE")" a1 &&
186         git config --unset i18n.commitencoding &&
187         git shortlog HEAD~2.. > out &&
188 test_cmp expect out'
189
190 test_expect_success 'shortlog with revision pseudo options' '
191         git shortlog --all &&
192         git shortlog --branches &&
193         git shortlog --exclude=refs/heads/m* --all
194 '
195
196 test_expect_success 'shortlog with --output=<file>' '
197         git shortlog --output=shortlog -1 main >output &&
198         test_must_be_empty output &&
199         test_line_count = 3 shortlog
200 '
201
202 test_expect_success 'shortlog --committer (internal)' '
203         git checkout --orphan side &&
204         git commit --allow-empty -m one &&
205         git commit --allow-empty -m two &&
206         GIT_COMMITTER_NAME="Sin Nombre" git commit --allow-empty -m three &&
207
208         cat >expect <<-\EOF &&
209              2  C O Mitter
210              1  Sin Nombre
211         EOF
212         git shortlog -nsc HEAD >actual &&
213         test_cmp expect actual
214 '
215
216 test_expect_success 'shortlog --committer (external)' '
217         git log --format=full | git shortlog -nsc >actual &&
218         test_cmp expect actual
219 '
220
221 test_expect_success '--group=committer is the same as --committer' '
222         git shortlog -ns --group=committer HEAD >actual &&
223         test_cmp expect actual
224 '
225
226 test_expect_success 'shortlog --group=trailer:signed-off-by' '
227         git commit --allow-empty -m foo -s &&
228         GIT_COMMITTER_NAME="SOB One" \
229         GIT_COMMITTER_EMAIL=sob@example.com \
230                 git commit --allow-empty -m foo -s &&
231         git commit --allow-empty --amend --no-edit -s &&
232         cat >expect <<-\EOF &&
233              2  C O Mitter <committer@example.com>
234              1  SOB One <sob@example.com>
235         EOF
236         git shortlog -nse --group=trailer:signed-off-by HEAD >actual &&
237         test_cmp expect actual
238 '
239
240 test_expect_success 'trailer idents are split' '
241         cat >expect <<-\EOF &&
242              2  C O Mitter
243              1  SOB One
244         EOF
245         git shortlog -ns --group=trailer:signed-off-by HEAD >actual &&
246         test_cmp expect actual
247 '
248
249 test_expect_success 'trailer idents are mailmapped' '
250         cat >expect <<-\EOF &&
251              2  C O Mitter
252              1  Another Name
253         EOF
254         echo "Another Name <sob@example.com>" >mail.map &&
255         git -c mailmap.file=mail.map shortlog -ns \
256                 --group=trailer:signed-off-by HEAD >actual &&
257         test_cmp expect actual
258 '
259
260 test_expect_success 'shortlog de-duplicates trailers in a single commit' '
261         git commit --allow-empty -F - <<-\EOF &&
262         subject one
263
264         this message has two distinct values, plus a repeat
265
266         Repeated-trailer: Foo
267         Repeated-trailer: Bar
268         Repeated-trailer: Foo
269         EOF
270
271         git commit --allow-empty -F - <<-\EOF &&
272         subject two
273
274         similar to the previous, but without the second distinct value
275
276         Repeated-trailer: Foo
277         Repeated-trailer: Foo
278         EOF
279
280         cat >expect <<-\EOF &&
281              2  Foo
282              1  Bar
283         EOF
284         git shortlog -ns --group=trailer:repeated-trailer -2 HEAD >actual &&
285         test_cmp expect actual
286 '
287
288 test_expect_success 'shortlog can match multiple groups' '
289         git commit --allow-empty -F - <<-\EOF &&
290         subject one
291
292         this has two trailers that are distinct from the author; it will count
293         3 times in the output
294
295         Some-trailer: User A <a@example.com>
296         Another-trailer: User B <b@example.com>
297         EOF
298
299         git commit --allow-empty -F - <<-\EOF &&
300         subject two
301
302         this one has two trailers, one of which is a duplicate with the author;
303         it will only be counted once for them
304
305         Another-trailer: A U Thor <author@example.com>
306         Some-trailer: User B <b@example.com>
307         EOF
308
309         cat >expect <<-\EOF &&
310              2  A U Thor
311              2  User B
312              1  User A
313         EOF
314         git shortlog -ns \
315                 --group=author \
316                 --group=trailer:some-trailer \
317                 --group=trailer:another-trailer \
318                 -2 HEAD >actual &&
319         test_cmp expect actual
320 '
321
322 test_expect_success 'set up option selection tests' '
323         git commit --allow-empty -F - <<-\EOF
324         subject
325
326         body
327
328         Trailer-one: value-one
329         Trailer-two: value-two
330         EOF
331 '
332
333 test_expect_success '--no-group resets group list to author' '
334         cat >expect <<-\EOF &&
335              1  A U Thor
336         EOF
337         git shortlog -ns \
338                 --group=committer \
339                 --group=trailer:trailer-one \
340                 --no-group \
341                 -1 HEAD >actual &&
342         test_cmp expect actual
343 '
344
345 test_expect_success '--no-group resets trailer list' '
346         cat >expect <<-\EOF &&
347              1  value-two
348         EOF
349         git shortlog -ns \
350                 --group=trailer:trailer-one \
351                 --no-group \
352                 --group=trailer:trailer-two \
353                 -1 HEAD >actual &&
354         test_cmp expect actual
355 '
356
357 test_expect_success 'stdin with multiple groups reports error' '
358         git log >log &&
359         test_must_fail git shortlog --group=author --group=committer <log
360 '
361
362 test_done