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@xxxxxxxxxxxxxxx> --- 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 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html