15
15
# Bash: PS1='[\u@\h \W$(__git_ps1 " (%s)")]\$ '
16
16
# ZSH: PS1='[%n@%m %c$(__git_ps1 " (%s)")]\$ '
17
17
# the optional argument will be used as format string.
18
- # 3b) Alternatively, if you are using bash, __git_ps1 can be
19
- # used for PROMPT_COMMAND with two parameters, <pre> and
20
- # < post>, which are strings you would put in $PS1 before
21
- # and after the status string generated by the git-prompt
22
- # machinery. e.g.
18
+ # 3b) Alternatively, for a slighly faster prompt, if you are
19
+ # using bash, __git_ps1 can be used for PROMPT_COMMAND
20
+ # with two parameters, <pre> and < post>, which are strings
21
+ # you would put in $PS1 before and after the status string
22
+ # generated by the git-prompt machinery. e.g.
23
23
# Bash: PROMPT_COMMAND='__git_ps1 "\u@\h:\w" "\\\$ "'
24
24
# ZSH: precmd () { __git_ps1 "%n" ":%~$ " "|%s" }
25
25
# will show username, at-sign, host, colon, cwd, then
80
80
# GIT_PS1_SHOWCOLORHINTS to a nonempty value. The colors are based on
81
81
# the colored output of "git status -sb".
82
82
83
- # __gitdir accepts 0 or 1 arguments (i.e., location)
84
- # returns location of .git repo
85
- __gitdir ()
86
- {
87
- # Note: this function is duplicated in git-completion.bash
88
- # When updating it, make sure you update the other one to match.
89
- if [ -z " ${1-} " ]; then
90
- if [ -n " ${__git_dir-} " ]; then
91
- echo " $__git_dir "
92
- elif [ -n " ${GIT_DIR-} " ]; then
93
- test -d " ${GIT_DIR-} " || return 1
94
- echo " $GIT_DIR "
95
- elif [ -d .git ]; then
96
- echo .git
97
- else
98
- git rev-parse --git-dir 2> /dev/null
99
- fi
100
- elif [ -d " $1 /.git" ]; then
101
- echo " $1 /.git"
102
- else
103
- echo " $1 "
104
- fi
105
- }
106
-
107
83
# stores the divergence from upstream in $p
108
84
# used by GIT_PS1_SHOWUPSTREAM
109
85
__git_ps1_show_upstream ()
@@ -335,50 +311,83 @@ __git_ps1 ()
335
311
;;
336
312
esac
337
313
338
- local g=" $( __gitdir) "
339
- if [ -z " $g " ]; then
314
+ local repo_info rev_parse_exit_code
315
+ repo_info=" $( git rev-parse --git-dir --is-inside-git-dir \
316
+ --is-bare-repository --is-inside-work-tree \
317
+ --short HEAD 2> /dev/null) "
318
+ rev_parse_exit_code=" $? "
319
+
320
+ if [ -z " $repo_info " ]; then
340
321
if [ $pcmode = yes ]; then
341
322
# In PC mode PS1 always needs to be set
342
323
PS1=" $ps1pc_start$ps1pc_end "
343
324
fi
325
+ return
326
+ fi
327
+
328
+ local short_sha
329
+ if [ " $rev_parse_exit_code " = " 0" ]; then
330
+ short_sha=" ${repo_info##* $' \n ' } "
331
+ repo_info=" ${repo_info% $' \n ' * } "
332
+ fi
333
+ local inside_worktree=" ${repo_info##* $' \n ' } "
334
+ repo_info=" ${repo_info% $' \n ' * } "
335
+ local bare_repo=" ${repo_info##* $' \n ' } "
336
+ repo_info=" ${repo_info% $' \n ' * } "
337
+ local inside_gitdir=" ${repo_info##* $' \n ' } "
338
+ local g=" ${repo_info% $' \n ' * } "
339
+
340
+ local r=" "
341
+ local b=" "
342
+ local step=" "
343
+ local total=" "
344
+ if [ -d " $g /rebase-merge" ]; then
345
+ read b 2> /dev/null < " $g /rebase-merge/head-name"
346
+ read step 2> /dev/null < " $g /rebase-merge/msgnum"
347
+ read total 2> /dev/null < " $g /rebase-merge/end"
348
+ if [ -f " $g /rebase-merge/interactive" ]; then
349
+ r=" |REBASE-i"
350
+ else
351
+ r=" |REBASE-m"
352
+ fi
344
353
else
345
- local r=" "
346
- local b=" "
347
- local step=" "
348
- local total=" "
349
- if [ -d " $g /rebase-merge" ]; then
350
- b=" $( cat " $g /rebase-merge/head-name" 2> /dev/null) "
351
- step=$( cat " $g /rebase-merge/msgnum" 2> /dev/null)
352
- total=$( cat " $g /rebase-merge/end" 2> /dev/null)
353
- if [ -f " $g /rebase-merge/interactive" ]; then
354
- r=" |REBASE-i"
354
+ if [ -d " $g /rebase-apply" ]; then
355
+ read step 2> /dev/null < " $g /rebase-apply/next"
356
+ read total 2> /dev/null < " $g /rebase-apply/last"
357
+ if [ -f " $g /rebase-apply/rebasing" ]; then
358
+ read b 2> /dev/null < " $g /rebase-apply/head-name"
359
+ r=" |REBASE"
360
+ elif [ -f " $g /rebase-apply/applying" ]; then
361
+ r=" |AM"
355
362
else
356
- r=" |REBASE-m "
363
+ r=" |AM/ REBASE"
357
364
fi
365
+ elif [ -f " $g /MERGE_HEAD" ]; then
366
+ r=" |MERGING"
367
+ elif [ -f " $g /CHERRY_PICK_HEAD" ]; then
368
+ r=" |CHERRY-PICKING"
369
+ elif [ -f " $g /REVERT_HEAD" ]; then
370
+ r=" |REVERTING"
371
+ elif [ -f " $g /BISECT_LOG" ]; then
372
+ r=" |BISECTING"
373
+ fi
374
+
375
+ if [ -n " $b " ]; then
376
+ :
377
+ elif [ -h " $g /HEAD" ]; then
378
+ # symlink symbolic ref
379
+ b=" $( git symbolic-ref HEAD 2> /dev/null) "
358
380
else
359
- if [ -d " $g /rebase-apply" ]; then
360
- step=$( cat " $g /rebase-apply/next" 2> /dev/null)
361
- total=$( cat " $g /rebase-apply/last" 2> /dev/null)
362
- if [ -f " $g /rebase-apply/rebasing" ]; then
363
- b=" $( cat " $g /rebase-apply/head-name" 2> /dev/null) "
364
- r=" |REBASE"
365
- elif [ -f " $g /rebase-apply/applying" ]; then
366
- r=" |AM"
367
- else
368
- r=" |AM/REBASE"
381
+ local head=" "
382
+ if ! read head 2> /dev/null < " $g /HEAD" ; then
383
+ if [ $pcmode = yes ]; then
384
+ PS1=" $ps1pc_start$ps1pc_end "
369
385
fi
370
- elif [ -f " $g /MERGE_HEAD" ]; then
371
- r=" |MERGING"
372
- elif [ -f " $g /CHERRY_PICK_HEAD" ]; then
373
- r=" |CHERRY-PICKING"
374
- elif [ -f " $g /REVERT_HEAD" ]; then
375
- r=" |REVERTING"
376
- elif [ -f " $g /BISECT_LOG" ]; then
377
- r=" |BISECTING"
386
+ return
378
387
fi
379
-
380
- test -n " $b " ||
381
- b= " $( git symbolic-ref HEAD 2> /dev/null ) " || {
388
+ # is it a symbolic ref?
389
+ b= " ${head # ref : } "
390
+ if [ " $head " = " $b " ] ; then
382
391
detached=yes
383
392
b=" $(
384
393
case " ${GIT_PS1_DESCRIBE_STYLE-} " in
@@ -392,70 +401,74 @@ __git_ps1 ()
392
401
git describe --tags --exact-match HEAD ;;
393
402
esac 2> /dev/null) " ||
394
403
395
- b=" $( cut -c1-7 " $g /HEAD" 2> /dev/null) ..." ||
396
- b=" unknown"
404
+ b=" $short_sha ..."
397
405
b=" ($b )"
398
- }
406
+ fi
399
407
fi
408
+ fi
400
409
401
- if [ -n " $step " ] && [ -n " $total " ]; then
402
- r=" $r $step /$total "
403
- fi
410
+ if [ -n " $step " ] && [ -n " $total " ]; then
411
+ r=" $r $step /$total "
412
+ fi
404
413
405
- local w=" "
406
- local i=" "
407
- local s=" "
408
- local u=" "
409
- local c=" "
410
- local p=" "
414
+ local w=" "
415
+ local i=" "
416
+ local s=" "
417
+ local u=" "
418
+ local c=" "
419
+ local p=" "
411
420
412
- if [ " true" = " $( git rev-parse --is-inside-git-dir 2> /dev/null) " ]; then
413
- if [ " true" = " $( git rev-parse --is-bare-repository 2> /dev/null) " ]; then
414
- c=" BARE:"
421
+ if [ " true" = " $inside_gitdir " ]; then
422
+ if [ " true" = " $bare_repo " ]; then
423
+ c=" BARE:"
424
+ else
425
+ b=" GIT_DIR!"
426
+ fi
427
+ elif [ " true" = " $inside_worktree " ]; then
428
+ if [ -n " ${GIT_PS1_SHOWDIRTYSTATE-} " ] &&
429
+ [ " $( git config --bool bash.showDirtyState) " != " false" ]
430
+ then
431
+ git diff --no-ext-diff --quiet --exit-code || w=" *"
432
+ if [ -n " $short_sha " ]; then
433
+ git diff-index --cached --quiet HEAD -- || i=" +"
415
434
else
416
- b=" GIT_DIR!"
417
- fi
418
- elif [ " true" = " $( git rev-parse --is-inside-work-tree 2> /dev/null) " ]; then
419
- if [ -n " ${GIT_PS1_SHOWDIRTYSTATE-} " ] &&
420
- [ " $( git config --bool bash.showDirtyState) " != " false" ]
421
- then
422
- git diff --no-ext-diff --quiet --exit-code || w=" *"
423
- if git rev-parse --quiet --verify HEAD > /dev/null; then
424
- git diff-index --cached --quiet HEAD -- || i=" +"
425
- else
426
- i=" #"
427
- fi
428
- fi
429
- if [ -n " ${GIT_PS1_SHOWSTASHSTATE-} " ]; then
430
- git rev-parse --verify refs/stash > /dev/null 2>&1 && s=" $"
435
+ i=" #"
431
436
fi
437
+ fi
438
+ if [ -n " ${GIT_PS1_SHOWSTASHSTATE-} " ] &&
439
+ [ -r " $g /refs/stash" ]; then
440
+ s=" $"
441
+ fi
432
442
433
- if [ -n " ${GIT_PS1_SHOWUNTRACKEDFILES-} " ] &&
434
- [ " $( git config --bool bash.showUntrackedFiles) " != " false" ] &&
435
- [ -n " $( git ls-files --others --exclude-standard) " ]
436
- then
437
- u=" %${ZSH_VERSION+% } "
438
- fi
443
+ if [ -n " ${GIT_PS1_SHOWUNTRACKEDFILES-} " ] &&
444
+ [ " $( git config --bool bash.showUntrackedFiles) " != " false" ] &&
445
+ git ls-files --others --exclude-standard --error-unmatch -- ' * ' > /dev/null 2> /dev/null
446
+ then
447
+ u=" %${ZSH_VERSION+% } "
448
+ fi
439
449
440
- if [ -n " ${GIT_PS1_SHOWUPSTREAM-} " ]; then
441
- __git_ps1_show_upstream
442
- fi
450
+ if [ -n " ${GIT_PS1_SHOWUPSTREAM-} " ]; then
451
+ __git_ps1_show_upstream
443
452
fi
453
+ fi
444
454
445
- local z=" ${GIT_PS1_STATESEPARATOR-" " } "
446
- local f=" $w$i$s$u "
447
- if [ $pcmode = yes ]; then
448
- local gitstring=
449
- if [ -n " ${GIT_PS1_SHOWCOLORHINTS-} " ]; then
450
- __git_ps1_colorize_gitstring
451
- else
452
- gitstring=" $c ${b## refs/ heads/ }${f: +$z$f } $r$p "
453
- fi
455
+ local z=" ${GIT_PS1_STATESEPARATOR-" " } "
456
+ local f=" $w$i$s$u "
457
+ if [ $pcmode = yes ]; then
458
+ local gitstring=
459
+ if [ -n " ${GIT_PS1_SHOWCOLORHINTS-} " ]; then
460
+ __git_ps1_colorize_gitstring
461
+ else
462
+ gitstring=" $c ${b## refs/ heads/ }${f: +$z$f } $r$p "
463
+ fi
464
+ if [[ -n ${ZSH_VERSION-} ]]; then
454
465
gitstring=$( printf -- " $printf_format " " $gitstring " )
455
- PS1=" $ps1pc_start$gitstring$ps1pc_end "
456
466
else
457
- # NO color option unless in PROMPT_COMMAND mode
458
- printf -- " $printf_format " " $c ${b## refs/ heads/ }${f: +$z$f } $r$p "
467
+ printf -v gitstring -- " $printf_format " " $gitstring "
459
468
fi
469
+ PS1=" $ps1pc_start$gitstring$ps1pc_end "
470
+ else
471
+ # NO color option unless in PROMPT_COMMAND mode
472
+ printf -- " $printf_format " " $c ${b## refs/ heads/ }${f: +$z$f } $r$p "
460
473
fi
461
474
}
0 commit comments