1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
|
test_description='Check content on log page'
. ./setup.sh
test_expect_success 'the log lists the whole of a short history' '
cgit_ok_url "foo/log" >tmp &&
test_grep ">commit 1<" tmp &&
test_grep ">commit 5<" tmp
'
test_expect_success 'the first log page holds fifty commits' '
cgit_ok_url "bar/log" >tmp &&
test_grep ">commit 1<" tmp &&
test_grep ">commit 50<" tmp
'
test_expect_success 'the log counts the files and lines a commit changed' '
test_create_repo repos/counts &&
(
cd repos/counts &&
printf "1\n2\n3\n" >a.txt &&
git add a.txt &&
git commit -m "add a" &&
printf "1\n3\n4\n5\n" >a.txt &&
echo x >b.txt &&
git add a.txt b.txt &&
git commit -m "change both"
) &&
cgitrc_repo countsrc counts enable-log-filecount=1 enable-log-linecount=1 &&
cgit_ok countsrc "url=counts/log/" >tmp &&
test_grep ">change both</a>.*<td class=.col-count.>2</td><td class=.col-count.><span class=.deletions.>-1</span>/<span class=.insertions.>+3</span></td>" tmp
'
test_expect_success 'set up a history the commit orders tell apart' '
test_create_repo repos/order &&
(
cd repos/order &&
tree=$(git mktree </dev/null) &&
x=$(GIT_COMMITTER_DATE="1700000030 +0000" git commit-tree -m x $tree) &&
y1=$(GIT_COMMITTER_DATE="1700000040 +0000" git commit-tree -m y1 -p $x $tree) &&
y2=$(GIT_COMMITTER_DATE="1700000045 +0000" git commit-tree -m y2 -p $y1 $tree) &&
z1=$(GIT_COMMITTER_DATE="1700000020 +0000" git commit-tree -m z1 -p $x $tree) &&
z2=$(GIT_COMMITTER_DATE="1700000042 +0000" git commit-tree -m z2 -p $z1 $tree) &&
m=$(GIT_COMMITTER_DATE="1700000050 +0000" git commit-tree -m m -p $y2 -p $z2 $tree) &&
git update-ref refs/heads/master $m &&
git log --format=%s >../../order.plain &&
git log --date-order --format=%s >../../order.date &&
git log --topo-order --format=%s >../../order.topo
) &&
! cmp -s order.plain order.date &&
! cmp -s order.date order.topo &&
! cmp -s order.plain order.topo &&
cgitrc_repo orderrc order &&
cgitrc_repo orderdaterc order commit-sort=date &&
cgitrc_repo ordertoporc order repo.commit-sort=topo
'
test_expect_success 'commit-sort orders the log as git log does' '
for sort in plain date topo
do
case $sort in
plain) rc=orderrc ;;
date) rc=orderdaterc ;;
topo) rc=ordertoporc ;;
esac &&
cgit_ok $rc "url=order/log/" >tmp &&
sed -n "s/.*<a href=.\/order\/commit\/?id=[0-9a-f]*.>\([a-z0-9]*\)<\/a>.*/\1/p" tmp >actual &&
test_cmp order.$sort actual || return 1
done
'
selected_options() {
sed -n "/<select name=.h./,/<\/select>/p" "$1" | grep " selected"
}
test_expect_success 'a detached head stays selected in the switcher' '
sha=$(git -C repos/foo rev-parse master~1) &&
cgit_ok_url "foo/log&h=$sha" >tmp &&
selected_options tmp >selected &&
test_line_count = 1 selected &&
test_grep "option value=.$sha. selected" selected
'
test_expect_success 'a tag head stays selected in the switcher' '
git -C repos/foo tag t-switch master~1 &&
test_when_finished "git -C repos/foo tag -d t-switch" &&
cgit_ok_url "foo/log&h=t-switch" >tmp &&
selected_options tmp >selected &&
test_line_count = 1 selected &&
test_grep "option value=.t-switch. selected>t-switch (detached)" selected
'
test_expect_success 'a branch head keeps its plain option' '
cgit_ok_url "foo/log&h=master" >tmp &&
selected_options tmp >selected &&
test_line_count = 1 selected &&
test_grep "option value=.master. selected>master<" selected &&
test_grep ! "detached" tmp
'
test_expect_success 'a pinned commit is selected in place of its branch' '
sha=$(git -C repos/foo rev-parse master~1) &&
cgit_ok_url "foo/commit&id=$sha" >tmp &&
selected_options tmp >selected &&
test_line_count = 1 selected &&
short=$(echo "$sha" | cut -c1-10) &&
test_grep "option value=.$sha. selected>$short (detached)<" selected &&
test_grep "<option value=.master.>master</option>" tmp
'
test_expect_success 'a search escapes the space in its links' '
cgit_ok_url "with+space/log&qt=grep&q=commit+1" >tmp &&
test_grep "/with%20space/log/?qt=grep" tmp &&
test_grep "/log/?qt=grep&q=commit+1" tmp &&
test_grep ! "href=./with space/" tmp &&
test_grep ! "q=commit 1" tmp
'
test_expect_success 'a search lists only the commits it matches' '
cgit_ok_url "with+space/log&qt=grep&q=commit+1" >tmp &&
test_grep ">commit 1<" tmp &&
test_grep ! "commit 2" tmp
'
test_expect_success 'a search ignores case' '
cgit_ok_url "foo/log&qt=grep&q=COMMIT+1" >tmp &&
test_grep ">commit 1<" tmp &&
test_grep ! ">commit 2<" tmp
'
test_expect_success 'a committer search matches the committer' '
mkrepo repos/who 1 &&
GIT_COMMITTER_NAME="Other Committer" git -C repos/who commit --allow-empty -m "by other" &&
cgitrc_repo whorc who &&
cgit_ok whorc "url=who/log/&qt=committer&q=other" >tmp &&
test_grep ">by other<" tmp &&
test_grep ! ">commit 1<" tmp &&
cgit_ok whorc "url=who/log/&qt=author&q=other" >tmp &&
test_grep "No commits match the search" tmp
'
test_expect_success 'a search matching nothing says so' '
cgit_ok_url "foo/log&qt=grep&q=no+such+commit" >tmp &&
test_grep "<tr class=.nohover.><td colspan=.5.>No commits match the search</td></tr>" tmp &&
cgit_ok_url "foo/log&qt=grep&q=commit+1" >tmp &&
test_grep ">commit 1<" tmp &&
test_grep ! "No commits match" tmp
'
test_expect_success 'the log labels branches and both kinds of tag' '
mkrepo repos/deco 3 &&
git -C repos/deco branch side HEAD~1 &&
git -C repos/deco tag deco-light HEAD~1 &&
git -C repos/deco tag -a -m annotated deco-annotated HEAD~2 &&
cgitrc_repo decorc deco &&
cgit_ok decorc "url=deco/log/" >tmp &&
test_grep "<a class=.branch-deco. href=./deco/log/.>master</a>" tmp &&
test_grep "<a class=.branch-deco. href=./deco/log/?h=side.>side</a>" tmp &&
test_grep "<a class=.tag-deco. href=./deco/tag/?h=deco-light.>deco-light</a>" tmp &&
test_grep "<a class=.tag-annotated-deco. href=./deco/tag/?h=deco-annotated.>deco-annotated</a>" tmp
'
test_expect_success 'set up a renamed file to follow' '
test_create_repo repos/fol &&
(
cd repos/fol &&
echo 1 >a.txt &&
git add a.txt &&
git commit -m "create a" &&
for i in 2 3 4
do
echo $i >>a.txt &&
git commit -am "edit a $i" || return 1
done &&
git mv a.txt b.txt &&
git commit -m "rename to b" &&
for i in 6 7 8
do
echo $i >>b.txt &&
git commit -am "edit b $i" || return 1
done
) &&
cgitrc_repo folrc fol enable-follow-links=1 max-commit-count=3
'
test_expect_success 'a followed log reaches the root commit' '
cgit_ok folrc "url=fol/log/b.txt&follow=1&ofs=6" >tmp &&
grep ">edit a 2<" tmp &&
grep ">create a<" tmp
'
test_expect_success 'the pager of a followed log keeps the name followed' '
cgit_ok folrc "url=fol/log/b.txt&follow=1&ofs=3" >tmp &&
grep ">edit a 3<" tmp &&
grep "href=./fol/log/b.txt?follow=1.>\[prev\]" tmp &&
grep "href=./fol/log/b.txt?ofs=6&follow=1.>\[next\]" tmp
'
test_expect_success 'a cut subject keeps whole characters' '
git -C repos/foo commit --allow-empty -m "日本語の説明文です日本語の説明文です" &&
cgitrc_copy subjectrc max-message-length=20 &&
cgit_ok subjectrc "url=foo/log/" >tmp &&
grep ">日本語の説\.\.\.</a>" tmp
'
test_expect_success 'a message limit below 15 turns the cut off' '
git -C repos/foo commit --allow-empty -m "a subject well past fourteen bytes" &&
cgitrc_copy cutrc max-message-length=15 &&
cgit_ok cutrc "url=foo/log/" >tmp &&
test_grep ">a subject we\.\.\.</a>" tmp &&
cgitrc_copy nocutrc max-message-length=14 &&
cgit_ok nocutrc "url=foo/log/" >tmp &&
test_grep ">a subject well past fourteen bytes</a>" tmp
'
test_expect_success 'an expanded log moves the cut part of a subject down' '
mkrepo repos/wrap 1 &&
git -C repos/wrap commit --allow-empty -m "one two three four five six seven eight" &&
cgitrc_repo wraprc wrap max-message-length=30 &&
cgit_ok wraprc "url=wrap/log/&showmsg=1" >tmp &&
test_grep ">one two three four five \.\.\.</a>" tmp &&
sed -n "/class=.logmsg.>\$/{n;p;q;}" tmp >msg &&
echo "six seven eight" >expect &&
test_cmp expect msg
'
test_expect_success 'the log draws the commit graph when enabled' '
cgitrc_copy graphrc enable-commit-graph=1 &&
cgit_ok graphrc "url=foo/log/" >tmp &&
grep "class=.commitgraph." tmp &&
grep "<th scope=.col. aria-label=.Graph.></th>" tmp
'
test_expect_success 'a followed log heads its age column with the graph on' '
{
echo "enable-commit-graph=1" &&
cat folrc
} >folgraphrc &&
cgit_ok folgraphrc "url=fol/log/b.txt&follow=1" >tmp &&
grep "<th class=.left. scope=.col.>Age</th><th class=.left. scope=.col.>Commit message" tmp &&
test_grep ! "aria-label=.Graph." tmp
'
test_expect_success 'a search for brackets matches them literally' '
git -C repos/foo commit --allow-empty -m "fix [brackets] in docs" &&
cgit_ok_url "foo/log&qt=grep&q=%5Bbrackets" >tmp &&
grep "fix \\[brackets\\] in docs" tmp
'
test_expect_success 'a walk that cannot start answers one error page' '
git clone -q repos/foo gap &&
old=$(git -C gap rev-parse HEAD~4) &&
parent=$(git -C gap rev-parse HEAD~2) &&
rm gap/.git/objects/$(echo $parent | cut -c1-2)/$(echo $parent | cut -c3-) &&
cgitrc_repo gaprc gap "repo.path=$PWD/gap/.git" &&
cgit_rc gaprc "url=gap/log/&qt=range&q=$old..master" >tmp 2>err &&
test $(grep -c "^Status:" tmp) = 1 &&
grep "^Status: 500" tmp &&
grep "Unable to read the history" tmp &&
test_grep "Could not read $parent" err
'
test_done
|