diff options
author | Junio C Hamano <gitster@pobox.com> | 2013-07-01 12:41:37 -0700 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2013-07-01 12:41:37 -0700 |
commit | 693502087e3a3190ffb11886989d52079e05412d (patch) | |
tree | a82fa02b33d76fc7231751c7a0fba59ef02f6a30 | |
parent | 0d07e98e741b50dbb4b98d561f7aeb48fb6a7bbc (diff) | |
parent | a694258457e51f20e92854075914c8d3a4593367 (diff) | |
download | git-693502087e3a3190ffb11886989d52079e05412d.tar.gz |
Merge branch 'sg/bash-prompt'
* sg/bash-prompt:
bash prompt: mention that PROMPT_COMMAND mode is faster
bash prompt: avoid command substitution when finalizing gitstring
bash prompt: avoid command substitution when checking for untracked files
bash prompt: use bash builtins to check stash state
bash prompt: use bash builtins to check for unborn branch for dirty state
bash prompt: combine 'git rev-parse' for detached head
bash prompt: combine 'git rev-parse' executions in the main code path
bash prompt: use bash builtins to find out current branch
bash prompt: use bash builtins to find out rebase state
bash prompt: run 'git rev-parse --git-dir' directly instead of __gitdir()
bash prompt: return early from __git_ps1() when not in a git repository
bash prompt: print unique detached HEAD abbreviated object name
bash prompt: add a test for symbolic link symbolic refs
completion, bash prompt: move __gitdir() tests to completion test suite
bash prompt: use 'write_script' helper in interactive rebase test
bash prompt: fix redirection coding style in tests
-rw-r--r-- | contrib/completion/git-completion.bash | 2 | ||||
-rw-r--r-- | contrib/completion/git-prompt.sh | 241 | ||||
-rwxr-xr-x | t/t9902-completion.sh | 134 | ||||
-rwxr-xr-x | t/t9903-bash-prompt.sh | 323 |
4 files changed, 367 insertions, 333 deletions
diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash index 6c3bafeea5..ebc40d4845 100644 --- a/contrib/completion/git-completion.bash +++ b/contrib/completion/git-completion.bash @@ -33,8 +33,6 @@ esac # returns location of .git repo __gitdir () { - # Note: this function is duplicated in git-prompt.sh - # When updating it, make sure you update the other one to match. if [ -z "${1-}" ]; then if [ -n "${__git_dir-}" ]; then echo "$__git_dir" diff --git a/contrib/completion/git-prompt.sh b/contrib/completion/git-prompt.sh index 07a6218d10..daed6a1d03 100644 --- a/contrib/completion/git-prompt.sh +++ b/contrib/completion/git-prompt.sh @@ -15,11 +15,11 @@ # Bash: PS1='[\u@\h \W$(__git_ps1 " (%s)")]\$ ' # ZSH: PS1='[%n@%m %c$(__git_ps1 " (%s)")]\$ ' # the optional argument will be used as format string. -# 3b) Alternatively, if you are using bash, __git_ps1 can be -# used for PROMPT_COMMAND with two parameters, <pre> and -# <post>, which are strings you would put in $PS1 before -# and after the status string generated by the git-prompt -# machinery. e.g. +# 3b) Alternatively, for a slighly faster prompt, if you are +# using bash, __git_ps1 can be used for PROMPT_COMMAND +# with two parameters, <pre> and <post>, which are strings +# you would put in $PS1 before and after the status string +# generated by the git-prompt machinery. e.g. # Bash: PROMPT_COMMAND='__git_ps1 "\u@\h:\w" "\\\$ "' # ZSH: precmd () { __git_ps1 "%n" ":%~$ " "|%s" } # will show username, at-sign, host, colon, cwd, then @@ -80,30 +80,6 @@ # GIT_PS1_SHOWCOLORHINTS to a nonempty value. The colors are based on # the colored output of "git status -sb". -# __gitdir accepts 0 or 1 arguments (i.e., location) -# returns location of .git repo -__gitdir () -{ - # Note: this function is duplicated in git-completion.bash - # When updating it, make sure you update the other one to match. - if [ -z "${1-}" ]; then - if [ -n "${__git_dir-}" ]; then - echo "$__git_dir" - elif [ -n "${GIT_DIR-}" ]; then - test -d "${GIT_DIR-}" || return 1 - echo "$GIT_DIR" - elif [ -d .git ]; then - echo .git - else - git rev-parse --git-dir 2>/dev/null - fi - elif [ -d "$1/.git" ]; then - echo "$1/.git" - else - echo "$1" - fi -} - # stores the divergence from upstream in $p # used by GIT_PS1_SHOWUPSTREAM __git_ps1_show_upstream () @@ -335,50 +311,83 @@ __git_ps1 () ;; esac - local g="$(__gitdir)" - if [ -z "$g" ]; then + local repo_info rev_parse_exit_code + repo_info="$(git rev-parse --git-dir --is-inside-git-dir \ + --is-bare-repository --is-inside-work-tree \ + --short HEAD 2>/dev/null)" + rev_parse_exit_code="$?" + + if [ -z "$repo_info" ]; then if [ $pcmode = yes ]; then #In PC mode PS1 always needs to be set PS1="$ps1pc_start$ps1pc_end" fi + return + fi + + local short_sha + if [ "$rev_parse_exit_code" = "0" ]; then + short_sha="${repo_info##*$'\n'}" + repo_info="${repo_info%$'\n'*}" + fi + local inside_worktree="${repo_info##*$'\n'}" + repo_info="${repo_info%$'\n'*}" + local bare_repo="${repo_info##*$'\n'}" + repo_info="${repo_info%$'\n'*}" + local inside_gitdir="${repo_info##*$'\n'}" + local g="${repo_info%$'\n'*}" + + local r="" + local b="" + local step="" + local total="" + if [ -d "$g/rebase-merge" ]; then + read b 2>/dev/null <"$g/rebase-merge/head-name" + read step 2>/dev/null <"$g/rebase-merge/msgnum" + read total 2>/dev/null <"$g/rebase-merge/end" + if [ -f "$g/rebase-merge/interactive" ]; then + r="|REBASE-i" + else + r="|REBASE-m" + fi else - local r="" - local b="" - local step="" - local total="" - if [ -d "$g/rebase-merge" ]; then - b="$(cat "$g/rebase-merge/head-name" 2>/dev/null)" - step=$(cat "$g/rebase-merge/msgnum" 2>/dev/null) - total=$(cat "$g/rebase-merge/end" 2>/dev/null) - if [ -f "$g/rebase-merge/interactive" ]; then - r="|REBASE-i" + if [ -d "$g/rebase-apply" ]; then + read step 2>/dev/null <"$g/rebase-apply/next" + read total 2>/dev/null <"$g/rebase-apply/last" + if [ -f "$g/rebase-apply/rebasing" ]; then + read b 2>/dev/null <"$g/rebase-apply/head-name" + r="|REBASE" + elif [ -f "$g/rebase-apply/applying" ]; then + r="|AM" else - r="|REBASE-m" + r="|AM/REBASE" fi + elif [ -f "$g/MERGE_HEAD" ]; then + r="|MERGING" + elif [ -f "$g/CHERRY_PICK_HEAD" ]; then + r="|CHERRY-PICKING" + elif [ -f "$g/REVERT_HEAD" ]; then + r="|REVERTING" + elif [ -f "$g/BISECT_LOG" ]; then + r="|BISECTING" + fi + + if [ -n "$b" ]; then + : + elif [ -h "$g/HEAD" ]; then + # symlink symbolic ref + b="$(git symbolic-ref HEAD 2>/dev/null)" else - if [ -d "$g/rebase-apply" ]; then - step=$(cat "$g/rebase-apply/next" 2>/dev/null) - total=$(cat "$g/rebase-apply/last" 2>/dev/null) - if [ -f "$g/rebase-apply/rebasing" ]; then - b="$(cat "$g/rebase-apply/head-name" 2>/dev/null)" - r="|REBASE" - elif [ -f "$g/rebase-apply/applying" ]; then - r="|AM" - else - r="|AM/REBASE" + local head="" + if ! read head 2>/dev/null <"$g/HEAD"; then + if [ $pcmode = yes ]; then + PS1="$ps1pc_start$ps1pc_end" fi - elif [ -f "$g/MERGE_HEAD" ]; then - r="|MERGING" - elif [ -f "$g/CHERRY_PICK_HEAD" ]; then - r="|CHERRY-PICKING" - elif [ -f "$g/REVERT_HEAD" ]; then - r="|REVERTING" - elif [ -f "$g/BISECT_LOG" ]; then - r="|BISECTING" + return fi - - test -n "$b" || - b="$(git symbolic-ref HEAD 2>/dev/null)" || { + # is it a symbolic ref? + b="${head#ref: }" + if [ "$head" = "$b" ]; then detached=yes b="$( case "${GIT_PS1_DESCRIBE_STYLE-}" in @@ -392,70 +401,74 @@ __git_ps1 () git describe --tags --exact-match HEAD ;; esac 2>/dev/null)" || - b="$(cut -c1-7 "$g/HEAD" 2>/dev/null)..." || - b="unknown" + b="$short_sha..." b="($b)" - } + fi fi + fi - if [ -n "$step" ] && [ -n "$total" ]; then - r="$r $step/$total" - fi + if [ -n "$step" ] && [ -n "$total" ]; then + r="$r $step/$total" + fi - local w="" - local i="" - local s="" - local u="" - local c="" - local p="" + local w="" + local i="" + local s="" + local u="" + local c="" + local p="" - if [ "true" = "$(git rev-parse --is-inside-git-dir 2>/dev/null)" ]; then - if [ "true" = "$(git rev-parse --is-bare-repository 2>/dev/null)" ]; then - c="BARE:" + if [ "true" = "$inside_gitdir" ]; then + if [ "true" = "$bare_repo" ]; then + c="BARE:" + else + b="GIT_DIR!" + fi + elif [ "true" = "$inside_worktree" ]; then + if [ -n "${GIT_PS1_SHOWDIRTYSTATE-}" ] && + [ "$(git config --bool bash.showDirtyState)" != "false" ] + then + git diff --no-ext-diff --quiet --exit-code || w="*" + if [ -n "$short_sha" ]; then + git diff-index --cached --quiet HEAD -- || i="+" else - b="GIT_DIR!" - fi - elif [ "true" = "$(git rev-parse --is-inside-work-tree 2>/dev/null)" ]; then - if [ -n "${GIT_PS1_SHOWDIRTYSTATE-}" ] && - [ "$(git config --bool bash.showDirtyState)" != "false" ] - then - git diff --no-ext-diff --quiet --exit-code || w="*" - if git rev-parse --quiet --verify HEAD >/dev/null; then - git diff-index --cached --quiet HEAD -- || i="+" - else - i="#" - fi - fi - if [ -n "${GIT_PS1_SHOWSTASHSTATE-}" ]; then - git rev-parse --verify refs/stash >/dev/null 2>&1 && s="$" + i="#" fi + fi + if [ -n "${GIT_PS1_SHOWSTASHSTATE-}" ] && + [ -r "$g/refs/stash" ]; then + s="$" + fi - if [ -n "${GIT_PS1_SHOWUNTRACKEDFILES-}" ] && - [ "$(git config --bool bash.showUntrackedFiles)" != "false" ] && - [ -n "$(git ls-files --others --exclude-standard)" ] - then - u="%${ZSH_VERSION+%}" - fi + if [ -n "${GIT_PS1_SHOWUNTRACKEDFILES-}" ] && + [ "$(git config --bool bash.showUntrackedFiles)" != "false" ] && + git ls-files --others --exclude-standard --error-unmatch -- '*' >/dev/null 2>/dev/null + then + u="%${ZSH_VERSION+%}" + fi - if [ -n "${GIT_PS1_SHOWUPSTREAM-}" ]; then - __git_ps1_show_upstream - fi + if [ -n "${GIT_PS1_SHOWUPSTREAM-}" ]; then + __git_ps1_show_upstream fi + fi - local z="${GIT_PS1_STATESEPARATOR-" "}" - local f="$w$i$s$u" - if [ $pcmode = yes ]; then - local gitstring= - if [ -n "${GIT_PS1_SHOWCOLORHINTS-}" ]; then - __git_ps1_colorize_gitstring - else - gitstring="$c${b##refs/heads/}${f:+$z$f}$r$p" - fi + local z="${GIT_PS1_STATESEPARATOR-" "}" + local f="$w$i$s$u" + if [ $pcmode = yes ]; then + local gitstring= + if [ -n "${GIT_PS1_SHOWCOLORHINTS-}" ]; then + __git_ps1_colorize_gitstring + else + gitstring="$c${b##refs/heads/}${f:+$z$f}$r$p" + fi + if [[ -n ${ZSH_VERSION-} ]]; then gitstring=$(printf -- "$printf_format" "$gitstring") - PS1="$ps1pc_start$gitstring$ps1pc_end" else - # NO color option unless in PROMPT_COMMAND mode - printf -- "$printf_format" "$c${b##refs/heads/}${f:+$z$f}$r$p" + printf -v gitstring -- "$printf_format" "$gitstring" fi + PS1="$ps1pc_start$gitstring$ps1pc_end" + else + # NO color option unless in PROMPT_COMMAND mode + printf -- "$printf_format" "$c${b##refs/heads/}${f:+$z$f}$r$p" fi } diff --git a/t/t9902-completion.sh b/t/t9902-completion.sh index 81a1657efb..5469dee8d1 100755 --- a/t/t9902-completion.sh +++ b/t/t9902-completion.sh @@ -122,6 +122,140 @@ test_gitcomp_nl () invalid_variable_name='${foo.bar}' +actual="$TRASH_DIRECTORY/actual" + +test_expect_success 'setup for __gitdir tests' ' + mkdir -p subdir/subsubdir && + git init otherrepo +' + +test_expect_success '__gitdir - from command line (through $__git_dir)' ' + echo "$TRASH_DIRECTORY/otherrepo/.git" >expected && + ( + __git_dir="$TRASH_DIRECTORY/otherrepo/.git" && + __gitdir >"$actual" + ) && + test_cmp expected "$actual" +' + +test_expect_success '__gitdir - repo as argument' ' + echo "otherrepo/.git" >expected && + __gitdir "otherrepo" >"$actual" && + test_cmp expected "$actual" +' + +test_expect_success '__gitdir - remote as argument' ' + echo "remote" >expected && + __gitdir "remote" >"$actual" && + test_cmp expected "$actual" +' + +test_expect_success '__gitdir - .git directory in cwd' ' + echo ".git" >expected && + __gitdir >"$actual" && + test_cmp expected "$actual" +' + +test_expect_success '__gitdir - .git directory in parent' ' + echo "$(pwd -P)/.git" >expected && + ( + cd subdir/subsubdir && + __gitdir >"$actual" + ) && + test_cmp expected "$actual" +' + +test_expect_success '__gitdir - cwd is a .git directory' ' + echo "." >expected && + ( + cd .git && + __gitdir >"$actual" + ) && + test_cmp expected "$actual" +' + +test_expect_success '__gitdir - parent is a .git directory' ' + echo "$(pwd -P)/.git" >expected && + ( + cd .git/refs/heads && + __gitdir >"$actual" + ) && + test_cmp expected "$actual" +' + +test_expect_success '__gitdir - $GIT_DIR set while .git directory in cwd' ' + echo "$TRASH_DIRECTORY/otherrepo/.git" >expected && + ( + GIT_DIR="$TRASH_DIRECTORY/otherrepo/.git" && + export GIT_DIR && + __gitdir >"$actual" + ) && + test_cmp expected "$actual" +' + +test_expect_success '__gitdir - $GIT_DIR set while .git directory in parent' ' + echo "$TRASH_DIRECTORY/otherrepo/.git" >expected && + ( + GIT_DIR="$TRASH_DIRECTORY/otherrepo/.git" && + export GIT_DIR && + cd subdir && + __gitdir >"$actual" + ) && + test_cmp expected "$actual" +' + +test_expect_success '__gitdir - non-existing $GIT_DIR' ' + ( + GIT_DIR="$TRASH_DIRECTORY/non-existing" && + export GIT_DIR && + test_must_fail __gitdir + ) +' + +test_expect_success '__gitdir - gitfile in cwd' ' + echo "$(pwd -P)/otherrepo/.git" >expected && + echo "gitdir: $TRASH_DIRECTORY/otherrepo/.git" >subdir/.git && + test_when_finished "rm -f subdir/.git" && + ( + cd subdir && + __gitdir >"$actual" + ) && + test_cmp expected "$actual" +' + +test_expect_success '__gitdir - gitfile in parent' ' + echo "$(pwd -P)/otherrepo/.git" >expected && + echo "gitdir: $TRASH_DIRECTORY/otherrepo/.git" >subdir/.git && + test_when_finished "rm -f subdir/.git" && + ( + cd subdir/subsubdir && + __gitdir >"$actual" + ) && + test_cmp expected "$actual" +' + +test_expect_success SYMLINKS '__gitdir - resulting path avoids symlinks' ' + echo "$(pwd -P)/otherrepo/.git" >expected && + mkdir otherrepo/dir && + test_when_finished "rm -rf otherrepo/dir" && + ln -s otherrepo/dir link && + test_when_finished "rm -f link" && + ( + cd link && + __gitdir >"$actual" + ) && + test_cmp expected "$actual" +' + +test_expect_success '__gitdir - not a git repository' ' + ( + cd subdir/subsubdir && + GIT_CEILING_DIRECTORIES="$TRASH_DIRECTORY" && + export GIT_CEILING_DIRECTORIES && + test_must_fail __gitdir + ) +' + test_expect_success '__gitcomp - trailing space - options' ' test_gitcomp "--re" "--dry-run --reuse-message= --reedit-message= --reset-author" <<-EOF diff --git a/t/t9903-bash-prompt.sh b/t/t9903-bash-prompt.sh index 15521cc4f9..c05458cbe6 100755 --- a/t/t9903-bash-prompt.sh +++ b/t/t9903-bash-prompt.sh @@ -12,526 +12,415 @@ test_description='test git-specific bash prompt functions' actual="$TRASH_DIRECTORY/actual" test_expect_success 'setup for prompt tests' ' - mkdir -p subdir/subsubdir && git init otherrepo && - echo 1 > file && + echo 1 >file && git add file && test_tick && git commit -m initial && git tag -a -m msg1 t1 && git checkout -b b1 && - echo 2 > file && + echo 2 >file && git commit -m "second b1" file && - echo 3 > file && + echo 3 >file && git commit -m "third b1" file && git tag -a -m msg2 t2 && git checkout -b b2 master && - echo 0 > file && + echo 0 >file && git commit -m "second b2" file && - echo 00 > file && + echo 00 >file && git commit -m "another b2" file && - echo 000 > file && + echo 000 >file && git commit -m "yet another b2" file && git checkout master ' -test_expect_success 'gitdir - from command line (through $__git_dir)' ' - echo "$TRASH_DIRECTORY/otherrepo/.git" > expected && - ( - __git_dir="$TRASH_DIRECTORY/otherrepo/.git" && - __gitdir > "$actual" - ) && - test_cmp expected "$actual" -' - -test_expect_success 'gitdir - repo as argument' ' - echo "otherrepo/.git" > expected && - __gitdir "otherrepo" > "$actual" && - test_cmp expected "$actual" -' - -test_expect_success 'gitdir - remote as argument' ' - echo "remote" > expected && - __gitdir "remote" > "$actual" && - test_cmp expected "$actual" -' - -test_expect_success 'gitdir - .git directory in cwd' ' - echo ".git" > expected && - __gitdir > "$actual" && - test_cmp expected "$actual" -' - -test_expect_success 'gitdir - .git directory in parent' ' - echo "$(pwd -P)/.git" > expected && - ( - cd subdir/subsubdir && - __gitdir > "$actual" - ) && - test_cmp expected "$actual" -' - -test_expect_success 'gitdir - cwd is a .git directory' ' - echo "." > expected && - ( - cd .git && - __gitdir > "$actual" - ) && - test_cmp expected "$actual" -' - -test_expect_success 'gitdir - parent is a .git directory' ' - echo "$(pwd -P)/.git" > expected && - ( - cd .git/refs/heads && - __gitdir > "$actual" - ) && - test_cmp expected "$actual" -' - -test_expect_success 'gitdir - $GIT_DIR set while .git directory in cwd' ' - echo "$TRASH_DIRECTORY/otherrepo/.git" > expected && - ( - GIT_DIR="$TRASH_DIRECTORY/otherrepo/.git" && - export GIT_DIR && - __gitdir > "$actual" - ) && - test_cmp expected "$actual" -' - -test_expect_success 'gitdir - $GIT_DIR set while .git directory in parent' ' - echo "$TRASH_DIRECTORY/otherrepo/.git" > expected && - ( - GIT_DIR="$TRASH_DIRECTORY/otherrepo/.git" && - export GIT_DIR && - cd subdir && - __gitdir > "$actual" - ) && - test_cmp expected "$actual" -' - -test_expect_success 'gitdir - non-existing $GIT_DIR' ' - ( - GIT_DIR="$TRASH_DIRECTORY/non-existing" && - export GIT_DIR && - test_must_fail __gitdir - ) -' - -test_expect_success 'gitdir - gitfile in cwd' ' - echo "$(pwd -P)/otherrepo/.git" > expected && - echo "gitdir: $TRASH_DIRECTORY/otherrepo/.git" > subdir/.git && - test_when_finished "rm -f subdir/.git" && - ( - cd subdir && - __gitdir > "$actual" - ) && - test_cmp expected "$actual" -' - -test_expect_success 'gitdir - gitfile in parent' ' - echo "$(pwd -P)/otherrepo/.git" > expected && - echo "gitdir: $TRASH_DIRECTORY/otherrepo/.git" > subdir/.git && - test_when_finished "rm -f subdir/.git" && - ( - cd subdir/subsubdir && - __gitdir > "$actual" - ) && +test_expect_success 'prompt - branch name' ' + printf " (master)" >expected && + __git_ps1 >"$actual" && test_cmp expected "$actual" ' -test_expect_success SYMLINKS 'gitdir - resulting path avoids symlinks' ' - echo "$(pwd -P)/otherrepo/.git" > expected && - mkdir otherrepo/dir && - test_when_finished "rm -rf otherrepo/dir" && - ln -s otherrepo/dir link && - test_when_finished "rm -f link" && - ( - cd link && - __gitdir > "$actual" - ) && +test_expect_success SYMLINKS 'prompt - branch name - symlink symref' ' + printf " (master)" >expected && + test_when_finished "git checkout master" && + test_config core.preferSymlinkRefs true && + git checkout master && + __git_ps1 >"$actual" && test_cmp expected "$actual" ' -test_expect_success 'gitdir - not a git repository' ' - ( - cd subdir/subsubdir && - GIT_CEILING_DIRECTORIES="$TRASH_DIRECTORY" && - export GIT_CEILING_DIRECTORIES && - test_must_fail __gitdir - ) -' - -test_expect_success 'prompt - branch name' ' - printf " (master)" > expected && - __git_ps1 > "$actual" && +test_expect_success 'prompt - unborn branch' ' + printf " (unborn)" >expected && + git checkout --orphan unborn && + test_when_finished "git checkout master" && + __git_ps1 >"$actual" && test_cmp expected "$actual" ' test_expect_success 'prompt - detached head' ' - printf " ((%s...))" $(git log -1 --format="%h" b1^) > expected && + printf " ((%s...))" $(git log -1 --format="%h" --abbrev=13 b1^) >expected && + test_config core.abbrev 13 && git checkout b1^ && test_when_finished "git checkout master" && - __git_ps1 > "$actual" && + __git_ps1 >"$actual" && test_cmp expected "$actual" ' test_expect_success 'prompt - describe detached head - contains' ' - printf " ((t2~1))" > expected && + printf " ((t2~1))" >expected && git checkout b1^ && test_when_finished "git checkout master" && ( GIT_PS1_DESCRIBE_STYLE=contains && - __git_ps1 > "$actual" + __git_ps1 >"$actual" ) && test_cmp expected "$actual" ' test_expect_success 'prompt - describe detached head - branch' ' - printf " ((b1~1))" > expected && + printf " ((b1~1))" >expected && git checkout b1^ && test_when_finished "git checkout master" && ( GIT_PS1_DESCRIBE_STYLE=branch && - __git_ps1 > "$actual" + __git_ps1 >"$actual" ) && test_cmp expected "$actual" ' test_expect_success 'prompt - describe detached head - describe' ' - printf " ((t1-1-g%s))" $(git log -1 --format="%h" b1^) > expected && + printf " ((t1-1-g%s))" $(git log -1 --format="%h" b1^) >expected && git checkout b1^ && test_when_finished "git checkout master" && ( GIT_PS1_DESCRIBE_STYLE=describe && - __git_ps1 > "$actual" + __git_ps1 >"$actual" ) && test_cmp expected "$actual" ' test_expect_success 'prompt - describe detached head - default' ' - printf " ((t2))" > expected && + printf " ((t2))" >expected && git checkout --detach b1 && test_when_finished "git checkout master" && - __git_ps1 > "$actual" && + __git_ps1 >"$actual" && test_cmp expected "$actual" ' test_expect_success 'prompt - inside .git directory' ' - printf " (GIT_DIR!)" > expected && + printf " (GIT_DIR!)" >expected && ( cd .git && - __git_ps1 > "$actual" + __git_ps1 >"$actual" ) && test_cmp expected "$actual" ' test_expect_success 'prompt - deep inside .git directory' ' - printf " (GIT_DIR!)" > expected && + printf " (GIT_DIR!)" >expected && ( cd .git/refs/heads && - __git_ps1 > "$actual" + __git_ps1 >"$actual" ) && test_cmp expected "$actual" ' test_expect_success 'prompt - inside bare repository' ' - printf " (BARE:master)" > expected && + printf " (BARE:master)" >expected && git init --bare bare.git && test_when_finished "rm -rf bare.git" && ( cd bare.git && - __git_ps1 > "$actual" + __git_ps1 >"$actual" ) && test_cmp expected "$actual" ' test_expect_success 'prompt - interactive rebase' ' - printf " (b1|REBASE-i 2/3)" > expected - echo "#!$SHELL_PATH" >fake_editor.sh && - cat >>fake_editor.sh <<\EOF && -echo "exec echo" > "$1" -echo "edit $(git log -1 --format="%h")" >> "$1" -echo "exec echo" >> "$1" -EOF + printf " (b1|REBASE-i 2/3)" >expected + write_script fake_editor.sh <<-\EOF && + echo "exec echo" >"$1" + echo "edit $(git log -1 --format="%h")" >>"$1" + echo "exec echo" >>"$1" + EOF test_when_finished "rm -f fake_editor.sh" && - chmod a+x fake_editor.sh && test_set_editor "$TRASH_DIRECTORY/fake_editor.sh" && git checkout b1 && test_when_finished "git checkout master" && git rebase -i HEAD^ && test_when_finished "git rebase --abort" - __git_ps1 > "$actual" && + __git_ps1 >"$actual" && test_cmp expected "$actual" ' test_expect_success 'prompt - rebase merge' ' - printf " (b2|REBASE-m 1/3)" > expected && + printf " (b2|REBASE-m 1/3)" >expected && git checkout b2 && test_when_finished "git checkout master" && test_must_fail git rebase --merge b1 b2 && test_when_finished "git rebase --abort" && - __git_ps1 > "$actual" && + __git_ps1 >"$actual" && test_cmp expected "$actual" ' test_expect_success 'prompt - rebase' ' - printf " (b2|REBASE 1/3)" > expected && + printf " (b2|REBASE 1/3)" >expected && git checkout b2 && test_when_finished "git checkout master" && test_must_fail git rebase b1 b2 && test_when_finished "git rebase --abort" && - __git_ps1 > "$actual" && + __git_ps1 >"$actual" && test_cmp expected "$actual" ' test_expect_success 'prompt - merge' ' - printf " (b1|MERGING)" > expected && + printf " (b1|MERGING)" >expected && git checkout b1 && test_when_finished "git checkout master" && test_must_fail git merge b2 && test_when_finished "git reset --hard" && - __git_ps1 > "$actual" && + __git_ps1 >"$actual" && test_cmp expected "$actual" ' test_expect_success 'prompt - cherry-pick' ' - printf " (master|CHERRY-PICKING)" > expected && + printf " (master|CHERRY-PICKING)" >expected && test_must_fail git cherry-pick b1 && test_when_finished "git reset --hard" && - __git_ps1 > "$actual" && + __git_ps1 >"$actual" && test_cmp expected "$actual" ' test_expect_success 'prompt - bisect' ' - printf " (master|BISECTING)" > expected && + printf " (master|BISECTING)" >expected && git bisect start && test_when_finished "git bisect reset" && - __git_ps1 > "$actual" && + __git_ps1 >"$actual" && test_cmp expected "$actual" ' test_expect_success 'prompt - dirty status indicator - clean' ' - printf " (master)" > expected && + printf " (master)" >expected && ( GIT_PS1_SHOWDIRTYSTATE=y && - __git_ps1 > "$actual" + __git_ps1 >"$actual" ) && test_cmp expected "$actual" ' test_expect_success 'prompt - dirty status indicator - dirty worktree' ' - printf " (master *)" > expected && - echo "dirty" > file && + printf " (master *)" >expected && + echo "dirty" >file && test_when_finished "git reset --hard" && ( GIT_PS1_SHOWDIRTYSTATE=y && - __git_ps1 > "$actual" + __git_ps1 >"$actual" ) && test_cmp expected "$actual" ' test_expect_success 'prompt - dirty status indicator - dirty index' ' - printf " (master +)" > expected && - echo "dirty" > file && + printf " (master +)" >expected && + echo "dirty" >file && test_when_finished "git reset --hard" && git add -u && ( GIT_PS1_SHOWDIRTYSTATE=y && - __git_ps1 > "$actual" + __git_ps1 >"$actual" ) && test_cmp expected "$actual" ' test_expect_success 'prompt - dirty status indicator - dirty index and worktree' ' - printf " (master *+)" > expected && - echo "dirty index" > file && + printf " (master *+)" >expected && + echo "dirty index" >file && test_when_finished "git reset --hard" && git add -u && - echo "dirty worktree" > file && + echo "dirty worktree" >file && ( GIT_PS1_SHOWDIRTYSTATE=y && - __git_ps1 > "$actual" + __git_ps1 >"$actual" ) && test_cmp expected "$actual" ' test_expect_success 'prompt - dirty status indicator - before root commit' ' - printf " (master #)" > expected && + printf " (master #)" >expected && ( GIT_PS1_SHOWDIRTYSTATE=y && cd otherrepo && - __git_ps1 > "$actual" + __git_ps1 >"$actual" ) && test_cmp expected "$actual" ' test_expect_success 'prompt - dirty status indicator - shell variable unset with config disabled' ' - printf " (master)" > expected && - echo "dirty" > file && + printf " (master)" >expected && + echo "dirty" >file && test_when_finished "git reset --hard" && test_config bash.showDirtyState false && ( sane_unset GIT_PS1_SHOWDIRTYSTATE && - __git_ps1 > "$actual" + __git_ps1 >"$actual" ) && test_cmp expected "$actual" ' test_expect_success 'prompt - dirty status indicator - shell variable unset with config enabled' ' - printf " (master)" > expected && - echo "dirty" > file && + printf " (master)" >expected && + echo "dirty" >file && test_when_finished "git reset --hard" && test_config bash.showDirtyState true && ( sane_unset GIT_PS1_SHOWDIRTYSTATE && - __git_ps1 > "$actual" + __git_ps1 >"$actual" ) && test_cmp expected "$actual" ' test_expect_success 'prompt - dirty status indicator - shell variable set with config disabled' ' - printf " (master)" > expected && - echo "dirty" > file && + printf " (master)" >expected && + echo "dirty" >file && test_when_finished "git reset --hard" && test_config bash.showDirtyState false && ( GIT_PS1_SHOWDIRTYSTATE=y && - __git_ps1 > "$actual" + __git_ps1 >"$actual" ) && test_cmp expected "$actual" ' test_expect_success 'prompt - dirty status indicator - shell variable set with config enabled' ' - printf " (master *)" > expected && - echo "dirty" > file && + printf " (master *)" >expected && + echo "dirty" >file && test_when_finished "git reset --hard" && test_config bash.showDirtyState true && ( GIT_PS1_SHOWDIRTYSTATE=y && - __git_ps1 > "$actual" + __git_ps1 >"$actual" ) && test_cmp expected "$actual" ' test_expect_success 'prompt - dirty status indicator - not shown inside .git directory' ' - printf " (GIT_DIR!)" > expected && - echo "dirty" > file && + printf " (GIT_DIR!)" >expected && + echo "dirty" >file && test_when_finished "git reset --hard" && ( GIT_PS1_SHOWDIRTYSTATE=y && cd .git && - __git_ps1 > "$actual" + __git_ps1 >"$actual" ) && test_cmp expected "$actual" ' test_expect_success 'prompt - stash status indicator - no stash' ' - printf " (master)" > expected && + printf " (master)" >expected && ( GIT_PS1_SHOWSTASHSTATE=y && - __git_ps1 > "$actual" + __git_ps1 >"$actual" ) && test_cmp expected "$actual" ' test_expect_success 'prompt - stash status indicator - stash' ' - printf " (master $)" > expected && + printf " (master $)" >expected && echo 2 >file && git stash && test_when_finished "git stash drop" && + git pack-refs --all && ( GIT_PS1_SHOWSTASHSTATE=y && - __git_ps1 > "$actual" + __git_ps1 >"$actual" ) && test_cmp expected "$actual" ' test_expect_success 'prompt - stash status indicator - not shown inside .git directory' ' - printf " (GIT_DIR!)" > expected && + printf " (GIT_DIR!)" >expected && echo 2 >file && git stash && test_when_finished "git stash drop" && ( GIT_PS1_SHOWSTASHSTATE=y && cd .git && - __git_ps1 > "$actual" + __git_ps1 >"$actual" ) && test_cmp expected "$actual" ' test_expect_success 'prompt - untracked files status indicator - no untracked files' ' - printf " (master)" > expected && + printf " (master)" >expected && ( GIT_PS1_SHOWUNTRACKEDFILES=y && cd otherrepo && - __git_ps1 > "$actual" + __git_ps1 >"$actual" ) && test_cmp expected "$actual" ' test_expect_success 'prompt - untracked files status indicator - untracked files' ' - printf " (master %%)" > expected && + printf " (master %%)" >expected && ( GIT_PS1_SHOWUNTRACKEDFILES=y && - __git_ps1 > "$actual" + __git_ps1 >"$actual" ) && test_cmp expected "$actual" ' test_expect_success 'prompt - untracked files status indicator - shell variable unset with config disabled' ' - printf " (master)" > expected && + printf " (master)" >expected && test_config bash.showUntrackedFiles false && ( sane_unset GIT_PS1_SHOWUNTRACKEDFILES && - __git_ps1 > "$actual" + __git_ps1 >"$actual" ) && test_cmp expected "$actual" ' test_expect_success 'prompt - untracked files status indicator - shell variable unset with config enabled' ' - printf " (master)" > expected && + printf " (master)" >expected && test_config bash.showUntrackedFiles true && ( sane_unset GIT_PS1_SHOWUNTRACKEDFILES && - __git_ps1 > "$actual" + __git_ps1 >"$actual" ) && test_cmp expected "$actual" ' test_expect_success 'prompt - untracked files status indicator - shell variable set with config disabled' ' - printf " (master)" > expected && + printf " (master)" >expected && test_config bash.showUntrackedFiles false && ( GIT_PS1_SHOWUNTRACKEDFILES=y && - __git_ps1 > "$actual" + __git_ps1 >"$actual" ) && test_cmp expected "$actual" ' test_expect_success 'prompt - untracked files status indicator - shell variable set with config enabled' ' - printf " (master %%)" > expected && + printf " (master %%)" >expected && test_config bash.showUntrackedFiles true && ( GIT_PS1_SHOWUNTRACKEDFILES=y && - __git_ps1 > "$actual" + __git_ps1 >"$actual" ) && test_cmp expected "$actual" ' test_expect_success 'prompt - untracked files status indicator - not shown inside .git directory' ' - printf " (GIT_DIR!)" > expected && + printf " (GIT_DIR!)" >expected && ( GIT_PS1_SHOWUNTRACKEDFILES=y && cd .git && - __git_ps1 > "$actual" + __git_ps1 >"$actual" ) && test_cmp expected "$actual" ' test_expect_success 'prompt - format string starting with dash' ' - printf -- "-master" > expected && - __git_ps1 "-%s" > "$actual" && + printf -- "-master" >expected && + __git_ps1 "-%s" >"$actual" && test_cmp expected "$actual" ' |