Merge branch 'rs/wt-status-cleanup'
[git] / t / t7006-pager.sh
1 #!/bin/sh
2
3 test_description='Test automatic use of a pager.'
4
5 . ./test-lib.sh
6 . "$TEST_DIRECTORY"/lib-pager.sh
7 . "$TEST_DIRECTORY"/lib-terminal.sh
8
9 test_expect_success 'setup' '
10         sane_unset GIT_PAGER GIT_PAGER_IN_USE &&
11         test_unconfig core.pager &&
12
13         PAGER="cat >paginated.out" &&
14         export PAGER &&
15
16         test_commit initial
17 '
18
19 test_expect_success TTY 'some commands use a pager' '
20         rm -f paginated.out &&
21         test_terminal git log &&
22         test -e paginated.out
23 '
24
25 test_expect_failure TTY 'pager runs from subdir' '
26         echo subdir/paginated.out >expected &&
27         mkdir -p subdir &&
28         rm -f paginated.out subdir/paginated.out &&
29         (
30                 cd subdir &&
31                 test_terminal git log
32         ) &&
33         {
34                 ls paginated.out subdir/paginated.out ||
35                 :
36         } >actual &&
37         test_cmp expected actual
38 '
39
40 test_expect_success TTY 'LESS and LV envvars are set for pagination' '
41         (
42                 sane_unset LESS LV &&
43                 PAGER="env >pager-env.out; wc" &&
44                 export PAGER &&
45
46                 test_terminal git log
47         ) &&
48         grep ^LESS= pager-env.out &&
49         grep ^LV= pager-env.out
50 '
51
52 test_expect_success !MINGW,TTY 'LESS and LV envvars set by git-sh-setup' '
53         (
54                 sane_unset LESS LV &&
55                 PAGER="env >pager-env.out; wc" &&
56                 export PAGER &&
57                 PATH="$(git --exec-path):$PATH" &&
58                 export PATH &&
59                 test_terminal sh -c ". git-sh-setup && git_pager"
60         ) &&
61         grep ^LESS= pager-env.out &&
62         grep ^LV= pager-env.out
63 '
64
65 test_expect_success TTY 'some commands do not use a pager' '
66         rm -f paginated.out &&
67         test_terminal git rev-list HEAD &&
68         ! test -e paginated.out
69 '
70
71 test_expect_success 'no pager when stdout is a pipe' '
72         rm -f paginated.out &&
73         git log | cat &&
74         ! test -e paginated.out
75 '
76
77 test_expect_success 'no pager when stdout is a regular file' '
78         rm -f paginated.out &&
79         git log >file &&
80         ! test -e paginated.out
81 '
82
83 test_expect_success TTY 'git --paginate rev-list uses a pager' '
84         rm -f paginated.out &&
85         test_terminal git --paginate rev-list HEAD &&
86         test -e paginated.out
87 '
88
89 test_expect_success 'no pager even with --paginate when stdout is a pipe' '
90         rm -f file paginated.out &&
91         git --paginate log | cat &&
92         ! test -e paginated.out
93 '
94
95 test_expect_success TTY 'no pager with --no-pager' '
96         rm -f paginated.out &&
97         test_terminal git --no-pager log &&
98         ! test -e paginated.out
99 '
100
101 test_expect_success TTY 'configuration can disable pager' '
102         rm -f paginated.out &&
103         test_unconfig pager.grep &&
104         test_terminal git grep initial &&
105         test -e paginated.out &&
106
107         rm -f paginated.out &&
108         test_config pager.grep false &&
109         test_terminal git grep initial &&
110         ! test -e paginated.out
111 '
112
113 test_expect_success TTY 'git config uses a pager if configured to' '
114         rm -f paginated.out &&
115         test_config pager.config true &&
116         test_terminal git config --list &&
117         test -e paginated.out
118 '
119
120 test_expect_success TTY 'configuration can enable pager (from subdir)' '
121         rm -f paginated.out &&
122         mkdir -p subdir &&
123         test_config pager.bundle true &&
124
125         git bundle create test.bundle --all &&
126         rm -f paginated.out subdir/paginated.out &&
127         (
128                 cd subdir &&
129                 test_terminal git bundle unbundle ../test.bundle
130         ) &&
131         {
132                 test -e paginated.out ||
133                 test -e subdir/paginated.out
134         }
135 '
136
137 # A colored commit log will begin with an appropriate ANSI escape
138 # for the first color; the text "commit" comes later.
139 colorful() {
140         read firstline <$1
141         ! expr "$firstline" : "[a-zA-Z]" >/dev/null
142 }
143
144 test_expect_success 'tests can detect color' '
145         rm -f colorful.log colorless.log &&
146         git log --no-color >colorless.log &&
147         git log --color >colorful.log &&
148         ! colorful colorless.log &&
149         colorful colorful.log
150 '
151
152 test_expect_success 'no color when stdout is a regular file' '
153         rm -f colorless.log &&
154         test_config color.ui auto &&
155         git log >colorless.log &&
156         ! colorful colorless.log
157 '
158
159 test_expect_success TTY 'color when writing to a pager' '
160         rm -f paginated.out &&
161         test_config color.ui auto &&
162         test_terminal env TERM=vt100 git log &&
163         colorful paginated.out
164 '
165
166 test_expect_success TTY 'colors are suppressed by color.pager' '
167         rm -f paginated.out &&
168         test_config color.ui auto &&
169         test_config color.pager false &&
170         test_terminal env TERM=vt100 git log &&
171         ! colorful paginated.out
172 '
173
174 test_expect_success 'color when writing to a file intended for a pager' '
175         rm -f colorful.log &&
176         test_config color.ui auto &&
177         (
178                 TERM=vt100 &&
179                 GIT_PAGER_IN_USE=true &&
180                 export TERM GIT_PAGER_IN_USE &&
181                 git log >colorful.log
182         ) &&
183         colorful colorful.log
184 '
185
186 test_expect_success TTY 'colors are sent to pager for external commands' '
187         test_config alias.externallog "!git log" &&
188         test_config color.ui auto &&
189         test_terminal env TERM=vt100 git -p externallog &&
190         colorful paginated.out
191 '
192
193 # Use this helper to make it easy for the caller of your
194 # terminal-using function to specify whether it should fail.
195 # If you write
196 #
197 #       your_test() {
198 #               parse_args "$@"
199 #
200 #               $test_expectation "$cmd - behaves well" "
201 #                       ...
202 #                       $full_command &&
203 #                       ...
204 #               "
205 #       }
206 #
207 # then your test can be used like this:
208 #
209 #       your_test expect_(success|failure) [test_must_fail] 'git foo'
210 #
211 parse_args() {
212         test_expectation="test_$1"
213         shift
214         if test "$1" = test_must_fail
215         then
216                 full_command="test_must_fail test_terminal "
217                 shift
218         else
219                 full_command="test_terminal "
220         fi
221         cmd=$1
222         full_command="$full_command $1"
223 }
224
225 test_default_pager() {
226         parse_args "$@"
227
228         $test_expectation SIMPLEPAGER,TTY "$cmd - default pager is used by default" "
229                 sane_unset PAGER GIT_PAGER &&
230                 test_unconfig core.pager &&
231                 rm -f default_pager_used &&
232                 cat >\$less <<-\EOF &&
233                 #!/bin/sh
234                 wc >default_pager_used
235                 EOF
236                 chmod +x \$less &&
237                 (
238                         PATH=.:\$PATH &&
239                         export PATH &&
240                         $full_command
241                 ) &&
242                 test -e default_pager_used
243         "
244 }
245
246 test_PAGER_overrides() {
247         parse_args "$@"
248
249         $test_expectation TTY "$cmd - PAGER overrides default pager" "
250                 sane_unset GIT_PAGER &&
251                 test_unconfig core.pager &&
252                 rm -f PAGER_used &&
253                 PAGER='wc >PAGER_used' &&
254                 export PAGER &&
255                 $full_command &&
256                 test -e PAGER_used
257         "
258 }
259
260 test_core_pager_overrides() {
261         if_local_config=
262         used_if_wanted='overrides PAGER'
263         test_core_pager "$@"
264 }
265
266 test_local_config_ignored() {
267         if_local_config='! '
268         used_if_wanted='is not used'
269         test_core_pager "$@"
270 }
271
272 test_core_pager() {
273         parse_args "$@"
274
275         $test_expectation TTY "$cmd - repository-local core.pager setting $used_if_wanted" "
276                 sane_unset GIT_PAGER &&
277                 rm -f core.pager_used &&
278                 PAGER=wc &&
279                 export PAGER &&
280                 test_config core.pager 'wc >core.pager_used' &&
281                 $full_command &&
282                 ${if_local_config}test -e core.pager_used
283         "
284 }
285
286 test_core_pager_subdir() {
287         if_local_config=
288         used_if_wanted='overrides PAGER'
289         test_pager_subdir_helper "$@"
290 }
291
292 test_no_local_config_subdir() {
293         if_local_config='! '
294         used_if_wanted='is not used'
295         test_pager_subdir_helper "$@"
296 }
297
298 test_pager_subdir_helper() {
299         parse_args "$@"
300
301         $test_expectation TTY "$cmd - core.pager $used_if_wanted from subdirectory" "
302                 sane_unset GIT_PAGER &&
303                 rm -f core.pager_used &&
304                 rm -fr sub &&
305                 PAGER=wc &&
306                 stampname=\$(pwd)/core.pager_used &&
307                 export PAGER stampname &&
308                 test_config core.pager 'wc >\"\$stampname\"' &&
309                 mkdir sub &&
310                 (
311                         cd sub &&
312                         $full_command
313                 ) &&
314                 ${if_local_config}test -e core.pager_used
315         "
316 }
317
318 test_GIT_PAGER_overrides() {
319         parse_args "$@"
320
321         $test_expectation TTY "$cmd - GIT_PAGER overrides core.pager" "
322                 rm -f GIT_PAGER_used &&
323                 test_config core.pager wc &&
324                 GIT_PAGER='wc >GIT_PAGER_used' &&
325                 export GIT_PAGER &&
326                 $full_command &&
327                 test -e GIT_PAGER_used
328         "
329 }
330
331 test_doesnt_paginate() {
332         parse_args "$@"
333
334         $test_expectation TTY "no pager for '$cmd'" "
335                 rm -f GIT_PAGER_used &&
336                 GIT_PAGER='wc >GIT_PAGER_used' &&
337                 export GIT_PAGER &&
338                 $full_command &&
339                 ! test -e GIT_PAGER_used
340         "
341 }
342
343 test_pager_choices() {
344         test_default_pager        expect_success "$@"
345         test_PAGER_overrides      expect_success "$@"
346         test_core_pager_overrides expect_success "$@"
347         test_core_pager_subdir    expect_success "$@"
348         test_GIT_PAGER_overrides  expect_success "$@"
349 }
350
351 test_expect_success 'setup: some aliases' '
352         git config alias.aliasedlog log &&
353         git config alias.true "!true"
354 '
355
356 test_pager_choices                       'git log'
357 test_pager_choices                       'git -p log'
358 test_pager_choices                       'git aliasedlog'
359
360 test_default_pager        expect_success 'git -p aliasedlog'
361 test_PAGER_overrides      expect_success 'git -p aliasedlog'
362 test_core_pager_overrides expect_success 'git -p aliasedlog'
363 test_core_pager_subdir    expect_success 'git -p aliasedlog'
364 test_GIT_PAGER_overrides  expect_success 'git -p aliasedlog'
365
366 test_default_pager        expect_success 'git -p true'
367 test_PAGER_overrides      expect_success 'git -p true'
368 test_core_pager_overrides expect_success 'git -p true'
369 test_core_pager_subdir    expect_success 'git -p true'
370 test_GIT_PAGER_overrides  expect_success 'git -p true'
371
372 test_default_pager        expect_success test_must_fail 'git -p request-pull'
373 test_PAGER_overrides      expect_success test_must_fail 'git -p request-pull'
374 test_core_pager_overrides expect_success test_must_fail 'git -p request-pull'
375 test_core_pager_subdir    expect_success test_must_fail 'git -p request-pull'
376 test_GIT_PAGER_overrides  expect_success test_must_fail 'git -p request-pull'
377
378 test_default_pager        expect_success test_must_fail 'git -p'
379 test_PAGER_overrides      expect_success test_must_fail 'git -p'
380 test_local_config_ignored expect_failure test_must_fail 'git -p'
381 test_GIT_PAGER_overrides  expect_success test_must_fail 'git -p'
382
383 test_expect_success TTY 'core.pager in repo config works and retains cwd' '
384         sane_unset GIT_PAGER &&
385         test_config core.pager "cat >cwd-retained" &&
386         (
387                 cd sub &&
388                 rm -f cwd-retained &&
389                 test_terminal git -p rev-parse HEAD &&
390                 test_path_is_file cwd-retained
391         )
392 '
393
394 test_expect_success TTY 'core.pager is found via alias in subdirectory' '
395         sane_unset GIT_PAGER &&
396         test_config core.pager "cat >via-alias" &&
397         (
398                 cd sub &&
399                 rm -f via-alias &&
400                 test_terminal git -c alias.r="-p rev-parse" r HEAD &&
401                 test_path_is_file via-alias
402         )
403 '
404
405 test_doesnt_paginate      expect_failure test_must_fail 'git -p nonsense'
406
407 test_pager_choices                       'git shortlog'
408 test_expect_success 'setup: configure shortlog not to paginate' '
409         git config pager.shortlog false
410 '
411 test_doesnt_paginate      expect_success 'git shortlog'
412 test_no_local_config_subdir expect_success 'git shortlog'
413 test_default_pager        expect_success 'git -p shortlog'
414 test_core_pager_subdir    expect_success 'git -p shortlog'
415
416 test_core_pager_subdir    expect_success test_must_fail \
417                                          'git -p apply </dev/null'
418
419 test_expect_success TTY 'command-specific pager' '
420         sane_unset PAGER GIT_PAGER &&
421         echo "foo:initial" >expect &&
422         >actual &&
423         test_unconfig core.pager &&
424         test_config pager.log "sed s/^/foo:/ >actual" &&
425         test_terminal git log --format=%s -1 &&
426         test_cmp expect actual
427 '
428
429 test_expect_success TTY 'command-specific pager overrides core.pager' '
430         sane_unset PAGER GIT_PAGER &&
431         echo "foo:initial" >expect &&
432         >actual &&
433         test_config core.pager "exit 1" &&
434         test_config pager.log "sed s/^/foo:/ >actual" &&
435         test_terminal git log --format=%s -1 &&
436         test_cmp expect actual
437 '
438
439 test_expect_success TTY 'command-specific pager overridden by environment' '
440         GIT_PAGER="sed s/^/foo:/ >actual" && export GIT_PAGER &&
441         >actual &&
442         echo "foo:initial" >expect &&
443         test_config pager.log "exit 1" &&
444         test_terminal git log --format=%s -1 &&
445         test_cmp expect actual
446 '
447
448 test_expect_success 'setup external command' '
449         cat >git-external <<-\EOF &&
450         #!/bin/sh
451         git "$@"
452         EOF
453         chmod +x git-external
454 '
455
456 test_expect_success TTY 'command-specific pager works for external commands' '
457         sane_unset PAGER GIT_PAGER &&
458         echo "foo:initial" >expect &&
459         >actual &&
460         test_config pager.external "sed s/^/foo:/ >actual" &&
461         test_terminal git --exec-path="$(pwd)" external log --format=%s -1 &&
462         test_cmp expect actual
463 '
464
465 test_expect_success TTY 'sub-commands of externals use their own pager' '
466         sane_unset PAGER GIT_PAGER &&
467         echo "foo:initial" >expect &&
468         >actual &&
469         test_config pager.log "sed s/^/foo:/ >actual" &&
470         test_terminal git --exec-path=. external log --format=%s -1 &&
471         test_cmp expect actual
472 '
473
474 test_expect_success TTY 'external command pagers override sub-commands' '
475         sane_unset PAGER GIT_PAGER &&
476         >expect &&
477         >actual &&
478         test_config pager.external false &&
479         test_config pager.log "sed s/^/log:/ >actual" &&
480         test_terminal git --exec-path=. external log --format=%s -1 &&
481         test_cmp expect actual
482 '
483
484 test_expect_success 'command with underscores does not complain' '
485         write_script git-under_score <<-\EOF &&
486         echo ok
487         EOF
488         git --exec-path=. under_score >actual 2>&1 &&
489         echo ok >expect &&
490         test_cmp expect actual
491 '
492
493 test_done