Skip to contentSkip to conversation

git-prompt.sh: make '+' work for unborn branches

PATCH In review Maurice Bos 2 participants 3 messages Jun 15, 2016 2 messages not in the archive

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 git-prompt.sh: make '+' work for unborn branches

For unborn branches, it now compares the index against the empty tree. (Just like git status does.)

---
 contrib/completion/git-prompt.sh | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)
contrib/completion/git-prompt.sh +6 -4
index 7b732d2..f656838 100644
@@ -407,12 +407,14 @@ __git_ps1 ()
 		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
+			local treeish=HEAD
+			if [ -z "$short_sha" ]; then
 				i="#"
+				# the empty tree
+				treeish=4b825dc642cb6eb9a060e54bf8d69288fbee4904
 			fi
+			git diff --no-ext-diff --quiet --exit-code || w="*"
+			git diff-index --cached --quiet $treeish -- || i="$i+"
 		fi
 		if [ -n "${GIT_PS1_SHOWSTASHSTATE-}" ] &&
 		   [ -r "$g/refs/stash" ]; then
Signature · 1 line
1.8.5.rc0.23.gaa27064

A message that is not in the archive (sent off-list or not yet received): [email protected]

A message that is not in the archive (sent off-list or not yet received): CABbCQwskqZzzRXm5K3dnOfRoAcx8jpsdskngmN7f1EvY6BONgw@mail.gmail.com

#3 lore raw

I have no clue why git diff --cached isn't used instead of git diff-index. I was wondering about it, but I decided I don't know enough about git and there are probably valid reasons for doing it this way. Though, replacing it with with git diff --cached seems to have the exact same behaviour, as far as I tested. That would make the patch a little prettier, as it doesn't contain the empty tree id any more:

@@ -407,12 +407,11 @@ __git_ps1 ()

         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
+ if [ -z "$short_sha" ]; then

                 i="#"
             fi
+            git diff --no-ext-diff --quiet --exit-code || w="*"
+            git diff --no-ext-diff --quiet --exit-code --cached || i="$i+"
         fi
         if [ -n "${GIT_PS1_SHOWSTASHSTATE-}" ] &&
            [ -r "$g/refs/stash" ]; then

Unfortunately, I don't know much about git diff-files, so I don't know whether it could be used instead.

In another version I used myself, I indeed used 'git status --porcelain' and used regexes /^\w/ /^.\w/ and /\?/ on the output. It seemed to work fine, but it's a bit stupid that it lists all the files when it could stop almost directly. An --extremly-short-porcelain-or-whatever-you-would-call-this option that would just output whether any file is dirty and/or indexed or something might be useful, though maybe a bit too specific. (--summarized ?)

-Maurice-

2014-03-06 21:40 GMT+01:00 Jeff King <[email protected]>:

Quoted 27 lines · Maurice Bos
Quoted 3 lines

For unborn branches, it now compares the index against the empty tree. (Just like git status does.)

Sounds sensible, although...

contrib/completion/git-prompt.sh __git_ps1 () · line 413

Quoted 4 lines
contrib/completion/git-prompt.sh +0 -4
-                     git diff --no-ext-diff --quiet --exit-code || w="*"
-                     if [ -n "$short_sha" ]; then
-                             git diff-index --cached --quiet HEAD -- || i="+"
-                     else

I notice the old code uses "git diff" immediately above. If we used "git diff --cached" here, too, I think it already knows about this empty-tree magic.

That being said, it seems odd that we are using "git diff" in the first place, and not "git diff-files". This seems to blame all the way back to 738a94a, when the functionality was added in the first place. Am I missing some reason we can't use diff-files (maybe we want the index-refreshing side effect)?

-Peff

PS I thought at first that this could just use "git status --porcelain",
which also knows the empty-tree trick. But that command has no way to quit early on the first change.

#4 lore raw
In reply to a message not in the archive
Quoted 6 lines · Maurice Bos

I have no clue why git diff --cached isn't used instead of git diff-index. I was wondering about it, but I decided I don't know enough about git and there are probably valid reasons for doing it this way. Though, replacing it with with git diff --cached seems to have the exact same behaviour, as far as I tested. That would make the patch a little prettier, as it doesn't contain the empty tree id any more:

I think it probably goes in the wrong direction, though. The prompt code should probably be building on plumbing, not porcelain. So your original patch as-is is probably the most sensible thing (we may want to convert the first git-diff call to use plumbing, too, but that would be a separate patch).

It looks like Junio did not pick up your patch. You may want to repost it.

-Peff