1#!/bin/sh
2#
3# Copyright (c) 2012 SZEDER Gábor
4#
5
6test_description='test git-specific bash prompt functions'
7
8. ./lib-bash.sh
9
10. "$GIT_BUILD_DIR/contrib/completion/git-prompt.sh"
11
12actual="$TRASH_DIRECTORY/actual"
13
14test_expect_success 'setup for prompt tests' '
15 mkdir -p subdir/subsubdir &&
16 git init otherrepo &&
17 echo 1 > file &&
18 git add file &&
19 test_tick &&
20 git commit -m initial &&
21 git tag -a -m msg1 t1 &&
22 git checkout -b b1 &&
23 echo 2 > file &&
24 git commit -m "second b1" file &&
25 echo 3 > file &&
26 git commit -m "third b1" file &&
27 git tag -a -m msg2 t2 &&
28 git checkout -b b2 master &&
29 echo 0 > file &&
30 git commit -m "second b2" file &&
31 git checkout master
32'
33
34test_expect_success 'gitdir - from command line (through $__git_dir)' '
35 echo "$TRASH_DIRECTORY/otherrepo/.git" > expected &&
36 (
37 __git_dir="$TRASH_DIRECTORY/otherrepo/.git" &&
38 __gitdir > "$actual"
39 ) &&
40 test_cmp expected "$actual"
41'
42
43test_expect_success 'gitdir - repo as argument' '
44 echo "otherrepo/.git" > expected &&
45 __gitdir "otherrepo" > "$actual" &&
46 test_cmp expected "$actual"
47'
48
49test_expect_success 'gitdir - remote as argument' '
50 echo "remote" > expected &&
51 __gitdir "remote" > "$actual" &&
52 test_cmp expected "$actual"
53'
54
55test_expect_success 'gitdir - .git directory in cwd' '
56 echo ".git" > expected &&
57 __gitdir > "$actual" &&
58 test_cmp expected "$actual"
59'
60
61test_expect_success 'gitdir - .git directory in parent' '
62 echo "$TRASH_DIRECTORY/.git" > expected &&
63 (
64 cd subdir/subsubdir &&
65 __gitdir > "$actual"
66 ) &&
67 test_cmp expected "$actual"
68'
69
70test_expect_success 'gitdir - cwd is a .git directory' '
71 echo "." > expected &&
72 (
73 cd .git &&
74 __gitdir > "$actual"
75 ) &&
76 test_cmp expected "$actual"
77'
78
79test_expect_success 'gitdir - parent is a .git directory' '
80 echo "$TRASH_DIRECTORY/.git" > expected &&
81 (
82 cd .git/refs/heads &&
83 __gitdir > "$actual"
84 ) &&
85 test_cmp expected "$actual"
86'
87
88test_expect_success 'gitdir - $GIT_DIR set while .git directory in cwd' '
89 echo "$TRASH_DIRECTORY/otherrepo/.git" > expected &&
90 (
91 GIT_DIR="$TRASH_DIRECTORY/otherrepo/.git" &&
92 export GIT_DIR &&
93 __gitdir > "$actual"
94 ) &&
95 test_cmp expected "$actual"
96'
97
98test_expect_success 'gitdir - $GIT_DIR set while .git directory in parent' '
99 echo "$TRASH_DIRECTORY/otherrepo/.git" > expected &&
100 (
101 GIT_DIR="$TRASH_DIRECTORY/otherrepo/.git" &&
102 export GIT_DIR &&
103 cd subdir &&
104 __gitdir > "$actual"
105 ) &&
106 test_cmp expected "$actual"
107'
108
109test_expect_success 'gitdir - non-existing $GIT_DIR' '
110 (
111 GIT_DIR="$TRASH_DIRECTORY/non-existing" &&
112 export GIT_DIR &&
113 test_must_fail __gitdir
114 )
115'
116
117test_expect_success 'gitdir - gitfile in cwd' '
118 echo "$TRASH_DIRECTORY/otherrepo/.git" > expected &&
119 echo "gitdir: $TRASH_DIRECTORY/otherrepo/.git" > subdir/.git &&
120 test_when_finished "rm -f subdir/.git" &&
121 (
122 cd subdir &&
123 __gitdir > "$actual"
124 ) &&
125 test_cmp expected "$actual"
126'
127
128test_expect_success 'gitdir - gitfile in parent' '
129 echo "$TRASH_DIRECTORY/otherrepo/.git" > expected &&
130 echo "gitdir: $TRASH_DIRECTORY/otherrepo/.git" > subdir/.git &&
131 test_when_finished "rm -f subdir/.git" &&
132 (
133 cd subdir/subsubdir &&
134 __gitdir > "$actual"
135 ) &&
136 test_cmp expected "$actual"
137'
138
139test_expect_success SYMLINKS 'gitdir - resulting path avoids symlinks' '
140 echo "$TRASH_DIRECTORY/otherrepo/.git" > expected &&
141 mkdir otherrepo/dir &&
142 test_when_finished "rm -rf otherrepo/dir" &&
143 ln -s otherrepo/dir link &&
144 test_when_finished "rm -f link" &&
145 (
146 cd link &&
147 __gitdir > "$actual"
148 ) &&
149 test_cmp expected "$actual"
150'
151
152test_expect_success 'gitdir - not a git repository' '
153 (
154 cd subdir/subsubdir &&
155 GIT_CEILING_DIRECTORIES="$TRASH_DIRECTORY" &&
156 export GIT_CEILING_DIRECTORIES &&
157 test_must_fail __gitdir
158 )
159'
160
161test_expect_success 'prompt - branch name' '
162 printf " (master)" > expected &&
163 __git_ps1 > "$actual" &&
164 test_cmp expected "$actual"
165'
166
167test_expect_success 'prompt - detached head' '
168 printf " ((%s...))" $(git log -1 --format="%h" b1^) > expected &&
169 git checkout b1^ &&
170 test_when_finished "git checkout master" &&
171 __git_ps1 > "$actual" &&
172 test_cmp expected "$actual"
173'
174
175test_expect_success 'prompt - describe detached head - contains' '
176 printf " ((t2~1))" > expected &&
177 git checkout b1^ &&
178 test_when_finished "git checkout master" &&
179 (
180 GIT_PS1_DESCRIBE_STYLE=contains &&
181 __git_ps1 > "$actual"
182 ) &&
183 test_cmp expected "$actual"
184'
185
186test_expect_success 'prompt - describe detached head - branch' '
187 printf " ((b1~1))" > expected &&
188 git checkout b1^ &&
189 test_when_finished "git checkout master" &&
190 (
191 GIT_PS1_DESCRIBE_STYLE=branch &&
192 __git_ps1 > "$actual"
193 ) &&
194 test_cmp expected "$actual"
195'
196
197test_expect_success 'prompt - describe detached head - describe' '
198 printf " ((t1-1-g%s))" $(git log -1 --format="%h" b1^) > expected &&
199 git checkout b1^ &&
200 test_when_finished "git checkout master" &&
201 (
202 GIT_PS1_DESCRIBE_STYLE=describe &&
203 __git_ps1 > "$actual"
204 ) &&
205 test_cmp expected "$actual"
206'
207
208test_expect_success 'prompt - describe detached head - default' '
209 printf " ((t2))" > expected &&
210 git checkout --detach b1 &&
211 test_when_finished "git checkout master" &&
212 __git_ps1 > "$actual" &&
213 test_cmp expected "$actual"
214'
215
216test_expect_success 'prompt - inside .git directory' '
217 printf " (GIT_DIR!)" > expected &&
218 (
219 cd .git &&
220 __git_ps1 > "$actual"
221 ) &&
222 test_cmp expected "$actual"
223'
224
225test_expect_success 'prompt - deep inside .git directory' '
226 printf " (GIT_DIR!)" > expected &&
227 (
228 cd .git/refs/heads &&
229 __git_ps1 > "$actual"
230 ) &&
231 test_cmp expected "$actual"
232'
233
234test_expect_success 'prompt - inside bare repository' '
235 printf " (BARE:master)" > expected &&
236 git init --bare bare.git &&
237 test_when_finished "rm -rf bare.git" &&
238 (
239 cd bare.git &&
240 __git_ps1 > "$actual"
241 ) &&
242 test_cmp expected "$actual"
243'
244
245test_expect_success 'prompt - interactive rebase' '
246 printf " (b1|REBASE-i)" > expected
247 echo "#!$SHELL_PATH" >fake_editor.sh &&
248 cat >>fake_editor.sh <<\EOF &&
249echo "edit $(git log -1 --format="%h")" > "$1"
250EOF
251 test_when_finished "rm -f fake_editor.sh" &&
252 chmod a+x fake_editor.sh &&
253 test_set_editor "$TRASH_DIRECTORY/fake_editor.sh" &&
254 git checkout b1 &&
255 test_when_finished "git checkout master" &&
256 git rebase -i HEAD^ &&
257 test_when_finished "git rebase --abort"
258 __git_ps1 > "$actual" &&
259 test_cmp expected "$actual"
260'
261
262test_expect_success 'prompt - rebase merge' '
263 printf " (b2|REBASE-m)" > expected &&
264 git checkout b2 &&
265 test_when_finished "git checkout master" &&
266 test_must_fail git rebase --merge b1 b2 &&
267 test_when_finished "git rebase --abort" &&
268 __git_ps1 > "$actual" &&
269 test_cmp expected "$actual"
270'
271
272test_expect_success 'prompt - rebase' '
273 printf " ((t2)|REBASE)" > expected &&
274 git checkout b2 &&
275 test_when_finished "git checkout master" &&
276 test_must_fail git rebase b1 b2 &&
277 test_when_finished "git rebase --abort" &&
278 __git_ps1 > "$actual" &&
279 test_cmp expected "$actual"
280'
281
282test_expect_success 'prompt - merge' '
283 printf " (b1|MERGING)" > expected &&
284 git checkout b1 &&
285 test_when_finished "git checkout master" &&
286 test_must_fail git merge b2 &&
287 test_when_finished "git reset --hard" &&
288 __git_ps1 > "$actual" &&
289 test_cmp expected "$actual"
290'
291
292test_expect_success 'prompt - cherry-pick' '
293 printf " (master|CHERRY-PICKING)" > expected &&
294 test_must_fail git cherry-pick b1 &&
295 test_when_finished "git reset --hard" &&
296 __git_ps1 > "$actual" &&
297 test_cmp expected "$actual"
298'
299
300test_expect_success 'prompt - bisect' '
301 printf " (master|BISECTING)" > expected &&
302 git bisect start &&
303 test_when_finished "git bisect reset" &&
304 __git_ps1 > "$actual" &&
305 test_cmp expected "$actual"
306'
307
308test_expect_success 'prompt - dirty status indicator - clean' '
309 printf " (master)" > expected &&
310 (
311 GIT_PS1_SHOWDIRTYSTATE=y &&
312 __git_ps1 > "$actual"
313 ) &&
314 test_cmp expected "$actual"
315'
316
317test_expect_success 'prompt - dirty status indicator - dirty worktree' '
318 printf " (master *)" > expected &&
319 echo "dirty" > file &&
320 test_when_finished "git reset --hard" &&
321 (
322 GIT_PS1_SHOWDIRTYSTATE=y &&
323 __git_ps1 > "$actual"
324 ) &&
325 test_cmp expected "$actual"
326'
327
328test_expect_success 'prompt - dirty status indicator - dirty index' '
329 printf " (master +)" > expected &&
330 echo "dirty" > file &&
331 test_when_finished "git reset --hard" &&
332 git add -u &&
333 (
334 GIT_PS1_SHOWDIRTYSTATE=y &&
335 __git_ps1 > "$actual"
336 ) &&
337 test_cmp expected "$actual"
338'
339
340test_expect_success 'prompt - dirty status indicator - dirty index and worktree' '
341 printf " (master *+)" > expected &&
342 echo "dirty index" > file &&
343 test_when_finished "git reset --hard" &&
344 git add -u &&
345 echo "dirty worktree" > file &&
346 (
347 GIT_PS1_SHOWDIRTYSTATE=y &&
348 __git_ps1 > "$actual"
349 ) &&
350 test_cmp expected "$actual"
351'
352
353test_expect_success 'prompt - dirty status indicator - before root commit' '
354 printf " (master #)" > expected &&
355 (
356 GIT_PS1_SHOWDIRTYSTATE=y &&
357 cd otherrepo &&
358 __git_ps1 > "$actual"
359 ) &&
360 test_cmp expected "$actual"
361'
362
363test_expect_success 'prompt - dirty status indicator - shell variable unset with config disabled' '
364 printf " (master)" > expected &&
365 echo "dirty" > file &&
366 test_when_finished "git reset --hard" &&
367 test_config bash.showDirtyState false &&
368 (
369 sane_unset GIT_PS1_SHOWDIRTYSTATE &&
370 __git_ps1 > "$actual"
371 ) &&
372 test_cmp expected "$actual"
373'
374
375test_expect_success 'prompt - dirty status indicator - shell variable unset with config enabled' '
376 printf " (master)" > expected &&
377 echo "dirty" > file &&
378 test_when_finished "git reset --hard" &&
379 test_config bash.showDirtyState true &&
380 (
381 sane_unset GIT_PS1_SHOWDIRTYSTATE &&
382 __git_ps1 > "$actual"
383 ) &&
384 test_cmp expected "$actual"
385'
386
387test_expect_success 'prompt - dirty status indicator - shell variable set with config disabled' '
388 printf " (master)" > expected &&
389 echo "dirty" > file &&
390 test_when_finished "git reset --hard" &&
391 test_config bash.showDirtyState false &&
392 (
393 GIT_PS1_SHOWDIRTYSTATE=y &&
394 __git_ps1 > "$actual"
395 ) &&
396 test_cmp expected "$actual"
397'
398
399test_expect_success 'prompt - dirty status indicator - shell variable set with config enabled' '
400 printf " (master *)" > expected &&
401 echo "dirty" > file &&
402 test_when_finished "git reset --hard" &&
403 test_config bash.showDirtyState true &&
404 (
405 GIT_PS1_SHOWDIRTYSTATE=y &&
406 __git_ps1 > "$actual"
407 ) &&
408 test_cmp expected "$actual"
409'
410
411test_expect_success 'prompt - dirty status indicator - not shown inside .git directory' '
412 printf " (GIT_DIR!)" > expected &&
413 echo "dirty" > file &&
414 test_when_finished "git reset --hard" &&
415 (
416 GIT_PS1_SHOWDIRTYSTATE=y &&
417 cd .git &&
418 __git_ps1 > "$actual"
419 ) &&
420 test_cmp expected "$actual"
421'
422
423test_expect_success 'prompt - stash status indicator - no stash' '
424 printf " (master)" > expected &&
425 (
426 GIT_PS1_SHOWSTASHSTATE=y &&
427 __git_ps1 > "$actual"
428 ) &&
429 test_cmp expected "$actual"
430'
431
432test_expect_success 'prompt - stash status indicator - stash' '
433 printf " (master $)" > expected &&
434 echo 2 >file &&
435 git stash &&
436 test_when_finished "git stash drop" &&
437 (
438 GIT_PS1_SHOWSTASHSTATE=y &&
439 __git_ps1 > "$actual"
440 ) &&
441 test_cmp expected "$actual"
442'
443
444test_expect_success 'prompt - stash status indicator - not shown inside .git directory' '
445 printf " (GIT_DIR!)" > expected &&
446 echo 2 >file &&
447 git stash &&
448 test_when_finished "git stash drop" &&
449 (
450 GIT_PS1_SHOWSTASHSTATE=y &&
451 cd .git &&
452 __git_ps1 > "$actual"
453 ) &&
454 test_cmp expected "$actual"
455'
456
457test_expect_success 'prompt - untracked files status indicator - no untracked files' '
458 printf " (master)" > expected &&
459 (
460 GIT_PS1_SHOWUNTRACKEDFILES=y &&
461 cd otherrepo &&
462 __git_ps1 > "$actual"
463 ) &&
464 test_cmp expected "$actual"
465'
466
467test_expect_success 'prompt - untracked files status indicator - untracked files' '
468 printf " (master %%)" > expected &&
469 (
470 GIT_PS1_SHOWUNTRACKEDFILES=y &&
471 __git_ps1 > "$actual"
472 ) &&
473 test_cmp expected "$actual"
474'
475
476test_expect_success 'prompt - untracked files status indicator - shell variable unset with config disabled' '
477 printf " (master)" > expected &&
478 test_config bash.showUntrackedFiles false &&
479 (
480 sane_unset GIT_PS1_SHOWUNTRACKEDFILES &&
481 __git_ps1 > "$actual"
482 ) &&
483 test_cmp expected "$actual"
484'
485
486test_expect_success 'prompt - untracked files status indicator - shell variable unset with config enabled' '
487 printf " (master)" > expected &&
488 test_config bash.showUntrackedFiles true &&
489 (
490 sane_unset GIT_PS1_SHOWUNTRACKEDFILES &&
491 __git_ps1 > "$actual"
492 ) &&
493 test_cmp expected "$actual"
494'
495
496test_expect_success 'prompt - untracked files status indicator - shell variable set with config disabled' '
497 printf " (master)" > expected &&
498 test_config bash.showUntrackedFiles false &&
499 (
500 GIT_PS1_SHOWUNTRACKEDFILES=y &&
501 __git_ps1 > "$actual"
502 ) &&
503 test_cmp expected "$actual"
504'
505
506test_expect_success 'prompt - untracked files status indicator - shell variable set with config enabled' '
507 printf " (master %%)" > expected &&
508 test_config bash.showUntrackedFiles true &&
509 (
510 GIT_PS1_SHOWUNTRACKEDFILES=y &&
511 __git_ps1 > "$actual"
512 ) &&
513 test_cmp expected "$actual"
514'
515
516test_expect_success 'prompt - untracked files status indicator - not shown inside .git directory' '
517 printf " (GIT_DIR!)" > expected &&
518 (
519 GIT_PS1_SHOWUNTRACKEDFILES=y &&
520 cd .git &&
521 __git_ps1 > "$actual"
522 ) &&
523 test_cmp expected "$actual"
524'
525
526test_expect_success 'prompt - format string starting with dash' '
527 printf -- "-master" > expected &&
528 __git_ps1 "-%s" > "$actual" &&
529 test_cmp expected "$actual"
530'
531
532test_done