From 7154d695426d752f8998c74ee4cdc46383c418e1 Mon Sep 17 00:00:00 2001 From: Justin Donnelly Date: Mon, 25 Jul 2022 18:28:24 -0400 Subject: [PATCH] git-prompt: show presence of unresolved conflicts at command prompt If GIT_PS1_SHOWCONFLICTSTATE is set to "yes", show the word "CONFLICT" on the command prompt when there are unresolved conflicts. Example prompt: (main|CONFLICT) Signed-off-by: Justin Donnelly --- contrib/completion/git-prompt.sh | 12 +++++- t/t9903-bash-prompt.sh | 70 ++++++++++++++++++++++++++++++-- 2 files changed, 77 insertions(+), 5 deletions(-) diff --git a/contrib/completion/git-prompt.sh b/contrib/completion/git-prompt.sh index 1435548e004687..57972c2845c135 100644 --- a/contrib/completion/git-prompt.sh +++ b/contrib/completion/git-prompt.sh @@ -84,6 +84,10 @@ # single '?' character by setting GIT_PS1_COMPRESSSPARSESTATE, or omitted # by setting GIT_PS1_OMITSPARSESTATE. # +# If you would like to see a notification on the prompt when there are +# unresolved conflicts, set GIT_PS1_SHOWCONFLICTSTATE to "yes". The +# prompt will include "|CONFLICT". +# # If you would like to see more information about the identity of # commits checked out as a detached HEAD, set GIT_PS1_DESCRIBE_STYLE # to one of these values: @@ -508,6 +512,12 @@ __git_ps1 () r="$r $step/$total" fi + local conflict="" # state indicator for unresolved conflicts + if [[ "${GIT_PS1_SHOWCONFLICTSTATE}" == "yes" ]] && + [[ $(git ls-files --unmerged 2>/dev/null) ]]; then + conflict="|CONFLICT" + fi + local w="" local i="" local s="" @@ -572,7 +582,7 @@ __git_ps1 () fi local f="$h$w$i$s$u$p" - local gitstring="$c$b${f:+$z$f}${sparse}$r${upstream}" + local gitstring="$c$b${f:+$z$f}${sparse}$r${upstream}${conflict}" if [ $pcmode = yes ]; then if [ "${__git_printf_supports_v-}" != yes ]; then diff --git a/t/t9903-bash-prompt.sh b/t/t9903-bash-prompt.sh index 6a30f5719c3326..47eb98893efc74 100755 --- a/t/t9903-bash-prompt.sh +++ b/t/t9903-bash-prompt.sh @@ -188,7 +188,23 @@ test_expect_success 'prompt - rebase merge' ' test_when_finished "git checkout main" && test_must_fail git rebase --merge b1 b2 && test_when_finished "git rebase --abort" && - __git_ps1 >"$actual" && + ( + sane_unset GIT_PS1_SHOWCONFLICTSTATE && + __git_ps1 >"$actual" + ) && + test_cmp expected "$actual" +' + +test_expect_success 'prompt - rebase merge conflict' ' + printf " (b2|REBASE 1/3|CONFLICT)" >expected && + git checkout b2 && + test_when_finished "git checkout main" && + test_must_fail git rebase --merge b1 b2 && + test_when_finished "git rebase --abort" && + ( + GIT_PS1_SHOWCONFLICTSTATE="yes" && + __git_ps1 >"$actual" + ) && test_cmp expected "$actual" ' @@ -198,7 +214,23 @@ test_expect_success 'prompt - rebase am' ' test_when_finished "git checkout main" && test_must_fail git rebase --apply b1 b2 && test_when_finished "git rebase --abort" && - __git_ps1 >"$actual" && + ( + sane_unset GIT_PS1_SHOWCONFLICTSTATE && + __git_ps1 >"$actual" + ) && + test_cmp expected "$actual" +' + +test_expect_success 'prompt - rebase am conflict' ' + printf " (b2|REBASE 1/3|CONFLICT)" >expected && + git checkout b2 && + test_when_finished "git checkout main" && + test_must_fail git rebase --apply b1 b2 && + test_when_finished "git rebase --abort" && + ( + GIT_PS1_SHOWCONFLICTSTATE="yes" && + __git_ps1 >"$actual" + ) && test_cmp expected "$actual" ' @@ -208,7 +240,23 @@ test_expect_success 'prompt - merge' ' test_when_finished "git checkout main" && test_must_fail git merge b2 && test_when_finished "git reset --hard" && - __git_ps1 >"$actual" && + ( + sane_unset GIT_PS1_SHOWCONFLICTSTATE && + __git_ps1 >"$actual" + ) && + test_cmp expected "$actual" +' + +test_expect_success 'prompt - merge conflict' ' + printf " (b1|MERGING|CONFLICT)" >expected && + git checkout b1 && + test_when_finished "git checkout main" && + test_must_fail git merge b2 && + test_when_finished "git reset --hard" && + ( + GIT_PS1_SHOWCONFLICTSTATE="yes" && + __git_ps1 >"$actual" + ) && test_cmp expected "$actual" ' @@ -216,7 +264,10 @@ test_expect_success 'prompt - cherry-pick' ' printf " (main|CHERRY-PICKING)" >expected && test_must_fail git cherry-pick b1 b1^ && test_when_finished "git cherry-pick --abort" && - __git_ps1 >"$actual" && + ( + sane_unset GIT_PS1_SHOWCONFLICTSTATE && + __git_ps1 >"$actual" + ) && test_cmp expected "$actual" && git reset --merge && test_must_fail git rev-parse CHERRY_PICK_HEAD && @@ -224,6 +275,17 @@ test_expect_success 'prompt - cherry-pick' ' test_cmp expected "$actual" ' +test_expect_success 'prompt - cherry-pick conflict' ' + printf " (main|CHERRY-PICKING|CONFLICT)" >expected && + test_must_fail git cherry-pick b1 b1^ && + test_when_finished "git cherry-pick --abort" && + ( + GIT_PS1_SHOWCONFLICTSTATE="yes" && + __git_ps1 >"$actual" + ) && + test_cmp expected "$actual" +' + test_expect_success 'prompt - revert' ' printf " (main|REVERTING)" >expected && test_must_fail git revert b1^ b1 &&