completion: split __git_ps1 into a separate script
[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_failure '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 - gitfile in cwd' '
110         echo "$TRASH_DIRECTORY/otherrepo/.git" > expected &&
111         echo "gitdir: $TRASH_DIRECTORY/otherrepo/.git" > subdir/.git &&
112         test_when_finished "rm -f subdir/.git" &&
113         (
114                 cd subdir &&
115                 __gitdir > "$actual"
116         ) &&
117         test_cmp expected "$actual"
118 '
119
120 test_expect_success 'gitdir - gitfile in parent' '
121         echo "$TRASH_DIRECTORY/otherrepo/.git" > expected &&
122         echo "gitdir: $TRASH_DIRECTORY/otherrepo/.git" > subdir/.git &&
123         test_when_finished "rm -f subdir/.git" &&
124         (
125                 cd subdir/subsubdir &&
126                 __gitdir > "$actual"
127         ) &&
128         test_cmp expected "$actual"
129 '
130
131 test_expect_success SYMLINKS 'gitdir - resulting path avoids symlinks' '
132         echo "$TRASH_DIRECTORY/otherrepo/.git" > expected &&
133         mkdir otherrepo/dir &&
134         test_when_finished "rm -rf otherrepo/dir" &&
135         ln -s otherrepo/dir link &&
136         test_when_finished "rm -f link" &&
137         (
138                 cd link &&
139                 __gitdir > "$actual"
140         ) &&
141         test_cmp expected "$actual"
142 '
143
144 test_expect_success 'gitdir - not a git repository' '
145         (
146                 cd subdir/subsubdir &&
147                 GIT_CEILING_DIRECTORIES="$TRASH_DIRECTORY" &&
148                 export GIT_CEILING_DIRECTORIES &&
149                 test_must_fail __gitdir
150         )
151 '
152
153 test_expect_success 'prompt - branch name' '
154         printf " (master)" > expected &&
155         __git_ps1 > "$actual" &&
156         test_cmp expected "$actual"
157 '
158
159 test_expect_success 'prompt - detached head' '
160         printf " ((%s...))" $(git log -1 --format="%h" b1^) > expected &&
161         git checkout b1^ &&
162         test_when_finished "git checkout master" &&
163         __git_ps1 > "$actual" &&
164         test_cmp expected "$actual"
165 '
166
167 test_expect_success 'prompt - describe detached head - contains' '
168         printf " ((t2~1))" > expected &&
169         git checkout b1^ &&
170         test_when_finished "git checkout master" &&
171         (
172                 GIT_PS1_DESCRIBE_STYLE=contains &&
173                 __git_ps1 > "$actual"
174         ) &&
175         test_cmp expected "$actual"
176 '
177
178 test_expect_success 'prompt - describe detached head - branch' '
179         printf " ((b1~1))" > expected &&
180         git checkout b1^ &&
181         test_when_finished "git checkout master" &&
182         (
183                 GIT_PS1_DESCRIBE_STYLE=branch &&
184                 __git_ps1 > "$actual"
185         ) &&
186         test_cmp expected "$actual"
187 '
188
189 test_expect_success 'prompt - describe detached head - describe' '
190         printf " ((t1-1-g%s))" $(git log -1 --format="%h" b1^) > expected &&
191         git checkout b1^ &&
192         test_when_finished "git checkout master" &&
193         (
194                 GIT_PS1_DESCRIBE_STYLE=describe &&
195                 __git_ps1 > "$actual"
196         ) &&
197         test_cmp expected "$actual"
198 '
199
200 test_expect_success 'prompt - describe detached head - default' '
201         printf " ((t2))" > expected &&
202         git checkout --detach b1 &&
203         test_when_finished "git checkout master" &&
204         __git_ps1 > "$actual" &&
205         test_cmp expected "$actual"
206 '
207
208 test_expect_success 'prompt - inside .git directory' '
209         printf " (GIT_DIR!)" > expected &&
210         (
211                 cd .git &&
212                 __git_ps1 > "$actual"
213         ) &&
214         test_cmp expected "$actual"
215 '
216
217 test_expect_success 'prompt - deep inside .git directory' '
218         printf " (GIT_DIR!)" > expected &&
219         (
220                 cd .git/refs/heads &&
221                 __git_ps1 > "$actual"
222         ) &&
223         test_cmp expected "$actual"
224 '
225
226 test_expect_success 'prompt - inside bare repository' '
227         printf " (BARE:master)" > expected &&
228         git init --bare bare.git &&
229         test_when_finished "rm -rf bare.git" &&
230         (
231                 cd bare.git &&
232                 __git_ps1 > "$actual"
233         ) &&
234         test_cmp expected "$actual"
235 '
236
237 test_expect_success 'prompt - interactive rebase' '
238         printf " (b1|REBASE-i)" > expected
239         echo "#!$SHELL_PATH" >fake_editor.sh &&
240         cat >>fake_editor.sh <<\EOF &&
241 echo "edit $(git log -1 --format="%h")" > "$1"
242 EOF
243         test_when_finished "rm -f fake_editor.sh" &&
244         chmod a+x fake_editor.sh &&
245         test_set_editor "$TRASH_DIRECTORY/fake_editor.sh" &&
246         git checkout b1 &&
247         test_when_finished "git checkout master" &&
248         git rebase -i HEAD^ &&
249         test_when_finished "git rebase --abort"
250         __git_ps1 > "$actual" &&
251         test_cmp expected "$actual"
252 '
253
254 test_expect_success 'prompt - rebase merge' '
255         printf " (b2|REBASE-m)" > expected &&
256         git checkout b2 &&
257         test_when_finished "git checkout master" &&
258         test_must_fail git rebase --merge b1 b2 &&
259         test_when_finished "git rebase --abort" &&
260         __git_ps1 > "$actual" &&
261         test_cmp expected "$actual"
262 '
263
264 test_expect_success 'prompt - rebase' '
265         printf " ((t2)|REBASE)" > expected &&
266         git checkout b2 &&
267         test_when_finished "git checkout master" &&
268         test_must_fail git rebase b1 b2 &&
269         test_when_finished "git rebase --abort" &&
270         __git_ps1 > "$actual" &&
271         test_cmp expected "$actual"
272 '
273
274 test_expect_success 'prompt - merge' '
275         printf " (b1|MERGING)" > expected &&
276         git checkout b1 &&
277         test_when_finished "git checkout master" &&
278         test_must_fail git merge b2 &&
279         test_when_finished "git reset --hard" &&
280         __git_ps1 > "$actual" &&
281         test_cmp expected "$actual"
282 '
283
284 test_expect_success 'prompt - cherry-pick' '
285         printf " (master|CHERRY-PICKING)" > expected &&
286         test_must_fail git cherry-pick b1 &&
287         test_when_finished "git reset --hard" &&
288         __git_ps1 > "$actual" &&
289         test_cmp expected "$actual"
290 '
291
292 test_expect_success 'prompt - bisect' '
293         printf " (master|BISECTING)" > expected &&
294         git bisect start &&
295         test_when_finished "git bisect reset" &&
296         __git_ps1 > "$actual" &&
297         test_cmp expected "$actual"
298 '
299
300 test_expect_success 'prompt - dirty status indicator - clean' '
301         printf " (master)" > expected &&
302         (
303                 GIT_PS1_SHOWDIRTYSTATE=y &&
304                 __git_ps1 > "$actual"
305         ) &&
306         test_cmp expected "$actual"
307 '
308
309 test_expect_success 'prompt - dirty status indicator - dirty worktree' '
310         printf " (master *)" > expected &&
311         echo "dirty" > file &&
312         test_when_finished "git reset --hard" &&
313         (
314                 GIT_PS1_SHOWDIRTYSTATE=y &&
315                 __git_ps1 > "$actual"
316         ) &&
317         test_cmp expected "$actual"
318 '
319
320 test_expect_success 'prompt - dirty status indicator - dirty index' '
321         printf " (master +)" > expected &&
322         echo "dirty" > file &&
323         test_when_finished "git reset --hard" &&
324         git add -u &&
325         (
326                 GIT_PS1_SHOWDIRTYSTATE=y &&
327                 __git_ps1 > "$actual"
328         ) &&
329         test_cmp expected "$actual"
330 '
331
332 test_expect_success 'prompt - dirty status indicator - dirty index and worktree' '
333         printf " (master *+)" > expected &&
334         echo "dirty index" > file &&
335         test_when_finished "git reset --hard" &&
336         git add -u &&
337         echo "dirty worktree" > file &&
338         (
339                 GIT_PS1_SHOWDIRTYSTATE=y &&
340                 __git_ps1 > "$actual"
341         ) &&
342         test_cmp expected "$actual"
343 '
344
345 test_expect_success 'prompt - dirty status indicator - before root commit' '
346         printf " (master #)" > expected &&
347         (
348                 GIT_PS1_SHOWDIRTYSTATE=y &&
349                 cd otherrepo &&
350                 __git_ps1 > "$actual"
351         ) &&
352         test_cmp expected "$actual"
353 '
354
355 test_expect_success 'prompt - dirty status indicator - disabled by config' '
356         printf " (master)" > expected &&
357         echo "dirty" > file &&
358         test_when_finished "git reset --hard" &&
359         test_config bash.showDirtyState false &&
360         (
361                 GIT_PS1_SHOWDIRTYSTATE=y &&
362                 __git_ps1 > "$actual"
363         ) &&
364         test_cmp expected "$actual"
365 '
366
367 test_expect_success 'prompt - dirty status indicator - not shown inside .git directory' '
368         printf " (GIT_DIR!)" > expected &&
369         echo "dirty" > file &&
370         test_when_finished "git reset --hard" &&
371         (
372                 GIT_PS1_SHOWDIRTYSTATE=y &&
373                 cd .git &&
374                 __git_ps1 > "$actual"
375         ) &&
376         test_cmp expected "$actual"
377 '
378
379 test_expect_success 'prompt - stash status indicator - no stash' '
380         printf " (master)" > expected &&
381         (
382                 GIT_PS1_SHOWSTASHSTATE=y &&
383                 __git_ps1 > "$actual"
384         ) &&
385         test_cmp expected "$actual"
386 '
387
388 test_expect_success 'prompt - stash status indicator - stash' '
389         printf " (master $)" > expected &&
390         echo 2 >file &&
391         git stash &&
392         test_when_finished "git stash drop" &&
393         (
394                 GIT_PS1_SHOWSTASHSTATE=y &&
395                 __git_ps1 > "$actual"
396         ) &&
397         test_cmp expected "$actual"
398 '
399
400 test_expect_success 'prompt - stash status indicator - not shown inside .git directory' '
401         printf " (GIT_DIR!)" > expected &&
402         echo 2 >file &&
403         git stash &&
404         test_when_finished "git stash drop" &&
405         (
406                 GIT_PS1_SHOWSTASHSTATE=y &&
407                 cd .git &&
408                 __git_ps1 > "$actual"
409         ) &&
410         test_cmp expected "$actual"
411 '
412
413 test_expect_success 'prompt - untracked files status indicator - no untracked files' '
414         printf " (master)" > expected &&
415         (
416                 GIT_PS1_SHOWUNTRACKEDFILES=y &&
417                 cd otherrepo &&
418                 __git_ps1 > "$actual"
419         ) &&
420         test_cmp expected "$actual"
421 '
422
423 test_expect_success 'prompt - untracked files status indicator - untracked files' '
424         printf " (master %%)" > expected &&
425         (
426                 GIT_PS1_SHOWUNTRACKEDFILES=y &&
427                 __git_ps1 > "$actual"
428         ) &&
429         test_cmp expected "$actual"
430 '
431
432 test_expect_success 'prompt - untracked files status indicator - not shown inside .git directory' '
433         printf " (GIT_DIR!)" > expected &&
434         (
435                 GIT_PS1_SHOWUNTRACKEDFILES=y &&
436                 cd .git &&
437                 __git_ps1 > "$actual"
438         ) &&
439         test_cmp expected "$actual"
440 '
441
442 test_expect_success 'prompt - format string starting with dash' '
443         printf -- "-master" > expected &&
444         __git_ps1 "-%s" > "$actual" &&
445         test_cmp expected "$actual"
446 '
447
448 test_done