git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[RFC/PATCHv2] bash completion: Support "divergence from upstream" warnings in __git_ps1

From
ASAndrew Sayers <andrew-git@pileofstuff.org>
Date
Jun 8, 2010, 21:36 UTC
Message-ID
<4C0EB7F1.1030707@pileofstuff.org>
In-Reply-To
<201006070942.34753.trast@student.ethz.ch>

Add a notification in the command prompt specifying whether you're ahead of (>), behind (<), diverged from (<>) or at (=) your upstream. This is especially helpful in small teams that (forget to) push to each other very frequently.

Support git-svn upstream detection as a special case, as migraters from centralised version control systems are especially likely to forget to push.

Support for other types of upstream than SVN should be easy to add if anyone is so inclined.

Signed-off-by: Andrew Sayers <andrew-git@pileofstuff.org>
---
This patch includes Thomas Rast's feedback - thanks Thomas for the education :)

This patch makes unashamed use of shell arrays and substring expansion that would normally not be allowed. As Jakub Narebski mentioned, this is probably ok in a bash-specific script.

Unlike other prompt options, I've put the divergence characters on the left of the branch name. I'm really not sure about this, and I'd like to hear people's opinions.

This patch produces output like this when I have unpushed commits:
[andrew@pc myrepo >master] # my master is ahead of upstream

Intuitively, I like having a ">" when I'm ahead, although it would be more logical to have something like this:

[andrew@pc myrepo <master] # upstream less-than master

Putting the symbol on the right makes this problem go away, but looks ridiculous if you use a prompt like PS1='\W:$(__git_ps1 "(%s)")> '

myrepo:master>> # master greater-than upstream myrepo:master<> # master less-than upstream myrepo:master<>> # master and upstream have diverged

I'd rather not rely on colour prompts to clear this up - using colour as the only way to convey important information to the user rarely ends well.

Adding a "u" to the symbol could also clear this up:
[andrew@pc myrepo u<master] # upstream less-than master

Using "u<", "u=", "u>" and "<>" would mean that the prompt always used either two or zero characters, which would keep prompts lined up over time. But it would also eat horizontal space for an issue you'd stop seeing after a few minutes.

Finally, my apologies to anyone that tried to apply my previous patch - to make a long story short, it turns out I need this feature more than I realised :)

 contrib/completion/git-completion.bash |   58 +++++++++++++++++++++++++++++++-
 1 files changed, 57 insertions(+), 1 deletions(-)
diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
index 57245a8..1dc80fd 100755
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -42,6 +42,14 @@
 #       set GIT_PS1_SHOWUNTRACKEDFILES to a nonempty value. If there're
 #       untracked files, then a '%' will be shown next to the branch name.
 #
+#       If you would like to see the difference bitween HEAD and its
+#       upstream, set GIT_PS1_SHOWUPSTREAM to a nonempty value.
+#       Unpushed commits (>), unmerged commits (<), both (<>) and
+#       neither (=) will be shown on the left of the branch name.  You
+#       can enable git-svn mode by setting GIT_PS1_SHOWUPSTREAM=svn
+#       and set the value per-repository with the bash.showUpstream
+#       variable.
+#
 # To submit patches:
 #
 #    *) Read Documentation/SubmittingPatches
@@ -132,6 +140,7 @@ __git_ps1 ()
 		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
@@ -159,10 +168,57 @@ __git_ps1 ()
 			      u="%"
 			   fi
 			fi
+
+			if [ -n "${GIT_PS1_SHOWUPSTREAM-}" ]; then
+
+				# Note: 'p' is used as a temporary throughout this block,
+				# before finally being assigned its correct value
+
+				if p="$(git config --get bash.showUpstream)"
+				then
+					GIT_PS1_SHOWUPSTREAM="$p"
+				fi
+
+				local upstream
+
+				if [ "${GIT_PS1_SHOWUPSTREAM-}" = "svn" ]; then
+
+					# git-svn upstream checking
+					p="$( git config --get svn-remote.svn.url )"
+					upstream=( $( git log --first-parent -1 \
+						--grep="^git-svn-id: $p" ) )
+					upstream=${upstream[ ${#upstream[@]} - 2 ]}
+					upstream=${upstream%@*}
+					upstream=${upstream#*$p/}
+
+				else # git upstream checking
+				  upstream="@{upstream}"
+				fi
+
+				if p="$( git rev-list \
+						--left-right "$upstream"...HEAD 2>/dev/null )"
+				then
+					case "$p" in
+						\<*\>*|\>*\<* ) p="<>" ;;
+						*\<*          ) p="<"  ;;
+						*\>*          ) p=">"  ;;
+						""            ) p="="  ;;
+
+						# the following case shouldn't be possible
+						# if you see this, please report it as a bug
+						* ) p="?ERROR($p)?" ;;
+
+					esac
+				else
+					p=""
+				fi
+
+			fi
+
 		fi
 
 		local f="$w$i$s$u"
-		printf "${1:- (%s)}" "$c${b##refs/heads/}${f:+ $f}$r"
+		printf "${1:- (%s)}" "$c$p${b##refs/heads/}${f:+ $f}$r"
 	fi
 }
 
-- 
1.7.0.4
Previous: Thomas RastNext: Peter Kjellerstedt
Message 7 of 20 in “bash completion: Support "unpushed commits" warnings in __git_ps1”
  1. bash completion: Support "unpushed commits" warnings in __git_ps1Andrew Sayers, Jun 6, 2010
  2. Thomas RastJun 6, 2010
  3. Andrew SayersJun 6, 2010
  4. Jakub NarebskiJun 6, 2010
  5. Andrew SayersJun 6, 2010
  6. Thomas RastJun 7, 2010
  7. [RFC/PATCHv2] bash completion: Support "divergence from upstream" warnings in __git_ps1Andrew Sayers, Jun 8, 2010
  8. Peter KjellerstedtJun 9, 2010
  9. John TapsellJun 9, 2010
  10. Steven MichalskeJun 9, 2010
  11. Michael J GruberJun 9, 2010
  12. Michael J GruberJun 9, 2010
  13. Michael J GruberJun 9, 2010
  14. 0/2 bash completion: Support "divergence from upstream" warnings in __git_ps1Thomas Rast, Jun 10, 2010
  15. 1/2 rev-list: introduce --count optionThomas Rast, Jun 10, 2010
  16. 2/2 bash completion: Support "divergence from upstream" warnings in __git_ps1Thomas Rast, Jun 10, 2010
  17. SZEDER GáborJun 12, 2010
  18. Michael J GruberJun 10, 2010
  19. Thomas RastJun 10, 2010
  20. Thomas RastJun 6, 2010

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.