Subject: [PATCH] bash completion: Support "unpushed commits" warnings in __git_ps1

From: Andrew Sayers <[email-masked]>
Date: Sun, 06 Jun 2010 01:05:20 +0100

People working in small teams sometimes forget to push their changes, causing
general confusion.  A gentle reminder in the command prompt should help.

Users migrating from centralised version control systems are especially likely
to forget, so I've included git-svn support as a special case.  Only SVN is
supported because it's the only centralised version control system I have any
experience with.  The code is designed to make adding other version control
systems easy for anyone that's interested.

Signed-off-by: Andrew Sayers <[email-masked]>
---
 contrib/completion/git-completion.bash |   33 ++++++++++++++++++++++++++++++-
 1 files changed, 31 insertions(+), 2 deletions(-)

diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
index d3fec32..4bb0fee 100755
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -48,6 +48,12 @@
 #       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 if there're unpushed commits, then
+#       you can set GIT_PS1_SHOWUNPUSHED to a nonempty value. If
+#       there're unpushed commits, then a '!' will be shown next to
+#       the branch name.  Setting GIT_PS1_SHOWUNPUSHED=svn will look
+#       for unpushed git-svn commits.
+#
 # To submit patches:
 #
 #    *) Read Documentation/SubmittingPatches
@@ -138,6 +144,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
@@ -167,12 +174,34 @@ __git_ps1 ()
 			      u="%"
 			   fi
 			fi
+
+			if [ -n "${GIT_PS1_SHOWUNPUSHED-}" ]; then
+			   local head
+			   local upstream
+			   if [ "${GIT_PS1_SHOWUNPUSHED-}" = "svn" ]; then # git-svn upstream checking
+			      local remote_branch=$( git config --get svn-remote.svn.url | sed 's/\//\\\//g' )
+			      upstream=$( git log | sed -ne "/^    git-svn-id: / { s/^    git-svn-id: $remote_branch\/\([^@]*\).*/\1/p ; q }" )
+			   else # git upstream checking
+			      upstream="@{upstream}"
+			   fi
+
+			   if git rev-parse --quiet "$upstream" HEAD 2>/dev/null | {
+			      read upstream
+			      read head
+			      [ -n "$head" -a -n "$upstream" -a "$head" != "$upstream" ]
+			   }; then
+			       p='!'
+			   else
+			       p=
+			   fi
+			fi
+
 		fi
 
 		if [ -n "${1-}" ]; then
-			printf "$1" "$c${b##refs/heads/}$w$i$s$u$r"
+			printf "$1" "$c${b##refs/heads/}$w$i$s$u$r$p"
 		else
-			printf " (%s)" "$c${b##refs/heads/}$w$i$s$u$r"
+			printf " (%s)" "$c${b##refs/heads/}$w$i$s$u$r$p"
 		fi
 	fi
 }