Hi Justin, On Wed, 17 Aug 2022, Justin Donnelly via GitGitGadget wrote: > From: Justin Donnelly <justinrdonnelly@xxxxxxxxx> > > 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 <justinrdonnelly@xxxxxxxxx> > --- > Show 'CONFLICT' indicator at command prompt > > This patch adds functionality for bash/zsh to show "CONFLICT" on the > prompt in cases where there are unresolved conflicts. The feature is > only enabled after setting an environment variable. > > The conflict state is determined by running git ls-files --unmerged. In > my testing, the performance was very good. It took around 0.01 seconds > to run git ls-files --unmerged regardless of the number of conflicts, or > their depth, even on very large projects (Linux kernel). I got similar > performance running git diff --cached --quiet --diff-filter=U. > > ------------------------------------------------------------------------ > > Changes since v2: > > * There is now a single new test focused explicitly on this feature > instead of making copies of existing tests and modifying them. > > Changes since v1: > > * This feature is now disabled by default. > * Created new tests for conflict state (instead of modifying existing > tests). This iteration looks good to me. Thanks! Dscho > > Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-1302%2Fjustinrdonnelly%2Fconflict-indicator-v3 > Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1302/justinrdonnelly/conflict-indicator-v3 > Pull-Request: https://github.com/gitgitgadget/git/pull/1302 > > Range-diff vs v2: > > 1: 7154d695426 ! 1: 2ea5c403924 git-prompt: show presence of unresolved conflicts at command prompt > @@ contrib/completion/git-prompt.sh: __git_ps1 () > if [ "${__git_printf_supports_v-}" != yes ]; then > > ## t/t9903-bash-prompt.sh ## > -@@ t/t9903-bash-prompt.sh: 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" > - ' > - > -@@ t/t9903-bash-prompt.sh: 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" > - ' > - > -@@ t/t9903-bash-prompt.sh: 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" > - ' > - > -@@ t/t9903-bash-prompt.sh: 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 && > -@@ t/t9903-bash-prompt.sh: test_expect_success 'prompt - cherry-pick' ' > +@@ t/t9903-bash-prompt.sh: test_expect_success 'prompt - hide if pwd ignored - inside gitdir' ' > 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" && > ++test_expect_success 'prompt - conflict indicator' ' > ++ printf " (main|CONFLICT)" >expected && > ++ echo "stash" >file && > ++ git stash && > ++ test_when_finished "git stash drop" && > ++ echo "commit" >file && > ++ git commit -m "commit" file && > ++ test_when_finished "git reset --hard HEAD~" && > ++ test_must_fail git stash apply && > + ( > + GIT_PS1_SHOWCONFLICTSTATE="yes" && > + __git_ps1 >"$actual" > @@ t/t9903-bash-prompt.sh: test_expect_success 'prompt - cherry-pick' ' > + test_cmp expected "$actual" > +' > + > - test_expect_success 'prompt - revert' ' > - printf " (main|REVERTING)" >expected && > - test_must_fail git revert b1^ b1 && > + test_done > > > contrib/completion/git-prompt.sh | 12 +++++++++++- > t/t9903-bash-prompt.sh | 16 ++++++++++++++++ > 2 files changed, 27 insertions(+), 1 deletion(-) > > diff --git a/contrib/completion/git-prompt.sh b/contrib/completion/git-prompt.sh > index 1435548e004..57972c2845c 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 6a30f5719c3..d459fae6551 100755 > --- a/t/t9903-bash-prompt.sh > +++ b/t/t9903-bash-prompt.sh > @@ -759,4 +759,20 @@ test_expect_success 'prompt - hide if pwd ignored - inside gitdir' ' > test_cmp expected "$actual" > ' > > +test_expect_success 'prompt - conflict indicator' ' > + printf " (main|CONFLICT)" >expected && > + echo "stash" >file && > + git stash && > + test_when_finished "git stash drop" && > + echo "commit" >file && > + git commit -m "commit" file && > + test_when_finished "git reset --hard HEAD~" && > + test_must_fail git stash apply && > + ( > + GIT_PS1_SHOWCONFLICTSTATE="yes" && > + __git_ps1 >"$actual" > + ) && > + test_cmp expected "$actual" > +' > + > test_done > > base-commit: 9bf691b78cf906751e65d65ba0c6ffdcd9a5a12c > -- > gitgitgadget >