Merge branch 'jc/doc-git-updates'
[git] / t / t9903-bash-prompt.sh
1 #!/bin/sh
2 #
3 # Copyright (c) 2012 SZEDER Gábor
4 #
5
6 test_description='test git-specific bash prompt functions'
7
8 . ./lib-bash.sh
9
10 . "$GIT_BUILD_DIR/contrib/completion/git-prompt.sh"
11
12 actual="$TRASH_DIRECTORY/actual"
13
14 test_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
34 test_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
43 test_expect_success 'gitdir - repo as argument' '
44         echo "otherrepo/.git" > expected &&
45         __gitdir "otherrepo" > "$actual" &&
46         test_cmp expected "$actual"
47 '
48
49 test_expect_success 'gitdir - remote as argument' '
50         echo "remote" > expected &&
51         __gitdir "remote" > "$actual" &&
52         test_cmp expected "$actual"
53 '
54
55 test_expect_success 'gitdir - .git directory in cwd' '
56         echo ".git" > expected &&
57         __gitdir > "$actual" &&
58         test_cmp expected "$actual"
59 '
60
61 test_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
70 test_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
79 test_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
88 test_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
98 test_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
109 test_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
117 test_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
128 test_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
139 test_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
152 test_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
161 test_expect_success 'prompt - branch name' '
162         printf " (master)" > expected &&
163         __git_ps1 > "$actual" &&
164         test_cmp expected "$actual"
165 '
166
167 test_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
175 test_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
186 test_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
197 test_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
208 test_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
216 test_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
225 test_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
234 test_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
245 test_expect_success 'prompt - interactive rebase' '
246         printf " (b1|REBASE-i)" > expected
247         echo "#!$SHELL_PATH" >fake_editor.sh &&
248         cat >>fake_editor.sh <<\EOF &&
249 echo "edit $(git log -1 --format="%h")" > "$1"
250 EOF
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
262 test_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
272 test_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
282 test_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
292 test_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
300 test_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
308 test_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
317 test_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
328 test_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
340 test_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
353 test_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
363 test_expect_success 'prompt - dirty status indicator - disabled by config' '
364         printf " (master)" > expected &&
365         echo "dirty" > file &&
366         test_when_finished "git reset --hard" &&
367         test_config bash.showDirtyState false &&
368         (
369                 GIT_PS1_SHOWDIRTYSTATE=y &&
370                 __git_ps1 > "$actual"
371         ) &&
372         test_cmp expected "$actual"
373 '
374
375 test_expect_success 'prompt - dirty status indicator - not shown inside .git directory' '
376         printf " (GIT_DIR!)" > expected &&
377         echo "dirty" > file &&
378         test_when_finished "git reset --hard" &&
379         (
380                 GIT_PS1_SHOWDIRTYSTATE=y &&
381                 cd .git &&
382                 __git_ps1 > "$actual"
383         ) &&
384         test_cmp expected "$actual"
385 '
386
387 test_expect_success 'prompt - stash status indicator - no stash' '
388         printf " (master)" > expected &&
389         (
390                 GIT_PS1_SHOWSTASHSTATE=y &&
391                 __git_ps1 > "$actual"
392         ) &&
393         test_cmp expected "$actual"
394 '
395
396 test_expect_success 'prompt - stash status indicator - stash' '
397         printf " (master $)" > expected &&
398         echo 2 >file &&
399         git stash &&
400         test_when_finished "git stash drop" &&
401         (
402                 GIT_PS1_SHOWSTASHSTATE=y &&
403                 __git_ps1 > "$actual"
404         ) &&
405         test_cmp expected "$actual"
406 '
407
408 test_expect_success 'prompt - stash status indicator - not shown inside .git directory' '
409         printf " (GIT_DIR!)" > expected &&
410         echo 2 >file &&
411         git stash &&
412         test_when_finished "git stash drop" &&
413         (
414                 GIT_PS1_SHOWSTASHSTATE=y &&
415                 cd .git &&
416                 __git_ps1 > "$actual"
417         ) &&
418         test_cmp expected "$actual"
419 '
420
421 test_expect_success 'prompt - untracked files status indicator - no untracked files' '
422         printf " (master)" > expected &&
423         (
424                 GIT_PS1_SHOWUNTRACKEDFILES=y &&
425                 cd otherrepo &&
426                 __git_ps1 > "$actual"
427         ) &&
428         test_cmp expected "$actual"
429 '
430
431 test_expect_success 'prompt - untracked files status indicator - untracked files' '
432         printf " (master %%)" > expected &&
433         (
434                 GIT_PS1_SHOWUNTRACKEDFILES=y &&
435                 __git_ps1 > "$actual"
436         ) &&
437         test_cmp expected "$actual"
438 '
439
440 test_expect_success 'prompt - untracked files status indicator - not shown inside .git directory' '
441         printf " (GIT_DIR!)" > expected &&
442         (
443                 GIT_PS1_SHOWUNTRACKEDFILES=y &&
444                 cd .git &&
445                 __git_ps1 > "$actual"
446         ) &&
447         test_cmp expected "$actual"
448 '
449
450 test_expect_success 'prompt - format string starting with dash' '
451         printf -- "-master" > expected &&
452         __git_ps1 "-%s" > "$actual" &&
453         test_cmp expected "$actual"
454 '
455
456 test_done