rev-parse: add --prefix option
[gitweb.git] / contrib / completion / git-prompt.sh
index 899eb095c65e73cdf2263d7d39ba0c506686020a..eaf5c369aacde207cbad4c9df9574e7b26634bb7 100644 (file)
@@ -24,6 +24,8 @@
 #        will show username, at-sign, host, colon, cwd, then
 #        various status string, followed by dollar and SP, as
 #        your prompt.
+#        Optionally, you can supply a third argument with a printf
+#        format string to finetune the output of the branch status
 #
 # The argument to __git_ps1 will be displayed only if you are currently
 # in a git repository.  The %s token will be the name of the current
 #
 # If you would like to see if there're untracked files, then you can set
 # GIT_PS1_SHOWUNTRACKEDFILES to a nonempty value. If there're untracked
-# files, then a '%' will be shown next to the branch name.
+# files, then a '%' will be shown next to the branch name.  You can
+# configure this per-repository with the bash.showUntrackedFiles
+# variable, which defaults to true once GIT_PS1_SHOWUNTRACKEDFILES is
+# enabled.
 #
 # If you would like to see the difference between HEAD and its upstream,
 # set GIT_PS1_SHOWUPSTREAM="auto".  A "<" indicates you are behind, ">"
 # GIT_PS1_SHOWUPSTREAM, you can override it on a per-repository basis by
 # setting the bash.showUpstream config variable.
 #
+# 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:
+#
+#     contains      relative to newer annotated tag (v1.6.3.2~35)
+#     branch        relative to newer tag or branch (master~4)
+#     describe      relative to older annotated tag (v1.6.3.1-13-gdd42c2f)
+#     default       exactly matching tag
+#
 # If you would like a colored hint about the current dirty state, set
 # GIT_PS1_SHOWCOLORHINTS to a nonempty value. The colors are based on
 # the colored output of "git status -sb".
-#
+
 # __gitdir accepts 0 or 1 arguments (i.e., location)
 # returns location of .git repo
 __gitdir ()
@@ -213,10 +227,12 @@ __git_ps1_show_upstream ()
 # when called from PS1 using command substitution
 # in this mode it prints text to add to bash PS1 prompt (includes branch name)
 #
-# __git_ps1 requires 2 arguments when called from PROMPT_COMMAND (pc)
+# __git_ps1 requires 2 or 3 arguments when called from PROMPT_COMMAND (pc)
 # in that case it _sets_ PS1. The arguments are parts of a PS1 string.
-# when both arguments are given, the first is prepended and the second appended
+# when two arguments are given, the first is prepended and the second appended
 # to the state string when assigned to PS1.
+# The optional third parameter will be used as printf format string to further
+# customize the output of the git-status string.
 # In this mode you can request colored hints using GIT_PS1_SHOWCOLORHINTS=true
 __git_ps1 ()
 {
@@ -227,9 +243,10 @@ __git_ps1 ()
        local printf_format=' (%s)'
 
        case "$#" in
-               2)      pcmode=yes
+               2|3)    pcmode=yes
                        ps1pc_start="$1"
                        ps1pc_end="$2"
+                       printf_format="${3:-$printf_format}"
                ;;
                0|1)    printf_format="${1:-$printf_format}"
                ;;
@@ -246,14 +263,21 @@ __git_ps1 ()
        else
                local r=""
                local b=""
-               if [ -f "$g/rebase-merge/interactive" ]; then
-                       r="|REBASE-i"
-                       b="$(cat "$g/rebase-merge/head-name")"
-               elif [ -d "$g/rebase-merge" ]; then
-                       r="|REBASE-m"
+               local step=""
+               local total=""
+               if [ -d "$g/rebase-merge" ]; then
                        b="$(cat "$g/rebase-merge/head-name")"
+                       step=$(cat "$g/rebase-merge/msgnum")
+                       total=$(cat "$g/rebase-merge/end")
+                       if [ -f "$g/rebase-merge/interactive" ]; then
+                               r="|REBASE-i"
+                       else
+                               r="|REBASE-m"
+                       fi
                else
                        if [ -d "$g/rebase-apply" ]; then
+                               step=$(cat "$g/rebase-apply/next")
+                               total=$(cat "$g/rebase-apply/last")
                                if [ -f "$g/rebase-apply/rebasing" ]; then
                                        r="|REBASE"
                                elif [ -f "$g/rebase-apply/applying" ]; then
@@ -265,6 +289,8 @@ __git_ps1 ()
                                r="|MERGING"
                        elif [ -f "$g/CHERRY_PICK_HEAD" ]; then
                                r="|CHERRY-PICKING"
+                       elif [ -f "$g/REVERT_HEAD" ]; then
+                               r="|REVERTING"
                        elif [ -f "$g/BISECT_LOG" ]; then
                                r="|BISECTING"
                        fi
@@ -289,6 +315,10 @@ __git_ps1 ()
                        }
                fi
 
+               if [ -n "$step" ] && [ -n "$total" ]; then
+                       r="$r $step/$total"
+               fi
+
                local w=""
                local i=""
                local s=""
@@ -303,24 +333,25 @@ __git_ps1 ()
                                b="GIT_DIR!"
                        fi
                elif [ "true" = "$(git rev-parse --is-inside-work-tree 2>/dev/null)" ]; then
-                       if [ -n "${GIT_PS1_SHOWDIRTYSTATE-}" ]; then
-                               if [ "$(git config --bool bash.showDirtyState)" != "false" ]; then
-                                       git diff --no-ext-diff --quiet --exit-code || w="*"
-                                       if git rev-parse --quiet --verify HEAD >/dev/null; then
-                                               git diff-index --cached --quiet HEAD -- || i="+"
-                                       else
-                                               i="#"
-                                       fi
+                       if [ -n "${GIT_PS1_SHOWDIRTYSTATE-}" ] &&
+                          [ "$(git config --bool bash.showDirtyState)" != "false" ]
+                       then
+                               git diff --no-ext-diff --quiet --exit-code || w="*"
+                               if git rev-parse --quiet --verify HEAD >/dev/null; then
+                                       git diff-index --cached --quiet HEAD -- || i="+"
+                               else
+                                       i="#"
                                fi
                        fi
                        if [ -n "${GIT_PS1_SHOWSTASHSTATE-}" ]; then
                                git rev-parse --verify refs/stash >/dev/null 2>&1 && s="$"
                        fi
 
-                       if [ -n "${GIT_PS1_SHOWUNTRACKEDFILES-}" ]; then
-                               if [ -n "$(git ls-files --others --exclude-standard)" ]; then
-                                       u="%"
-                               fi
+                       if [ -n "${GIT_PS1_SHOWUNTRACKEDFILES-}" ] &&
+                          [ "$(git config --bool bash.showUntrackedFiles)" != "false" ] &&
+                          [ -n "$(git ls-files --others --exclude-standard)" ]
+                       then
+                               u="%${ZSH_VERSION+%}"
                        fi
 
                        if [ -n "${GIT_PS1_SHOWUPSTREAM-}" ]; then
@@ -330,6 +361,7 @@ __git_ps1 ()
 
                local f="$w$i$s$u"
                if [ $pcmode = yes ]; then
+                       local gitstring=
                        if [ -n "${GIT_PS1_SHOWCOLORHINTS-}" ]; then
                                local c_red='\e[31m'
                                local c_green='\e[32m'
@@ -347,29 +379,31 @@ __git_ps1 ()
                                        branch_color="$bad_color"
                                fi
 
-                               # Setting PS1 directly with \[ and \] around colors
+                               # Setting gitstring directly with \[ and \] around colors
                                # is necessary to prevent wrapping issues!
-                               PS1="$ps1pc_start (\[$branch_color\]$branchstring\[$c_clear\]"
+                               gitstring="\[$branch_color\]$branchstring\[$c_clear\]"
 
                                if [ -n "$w$i$s$u$r$p" ]; then
-                                       PS1="$PS1 "
+                                       gitstring="$gitstring "
                                fi
                                if [ "$w" = "*" ]; then
-                                       PS1="$PS1\[$bad_color\]$w"
+                                       gitstring="$gitstring\[$bad_color\]$w"
                                fi
                                if [ -n "$i" ]; then
-                                       PS1="$PS1\[$ok_color\]$i"
+                                       gitstring="$gitstring\[$ok_color\]$i"
                                fi
                                if [ -n "$s" ]; then
-                                       PS1="$PS1\[$flags_color\]$s"
+                                       gitstring="$gitstring\[$flags_color\]$s"
                                fi
                                if [ -n "$u" ]; then
-                                       PS1="$PS1\[$bad_color\]$u"
+                                       gitstring="$gitstring\[$bad_color\]$u"
                                fi
-                               PS1="$PS1\[$c_clear\]$r$p)$ps1pc_end"
+                               gitstring="$gitstring\[$c_clear\]$r$p"
                        else
-                               PS1="$ps1pc_start ($c${b##refs/heads/}${f:+ $f}$r$p)$ps1pc_end"
+                               gitstring="$c${b##refs/heads/}${f:+ $f}$r$p"
                        fi
+                       gitstring=$(printf -- "$printf_format" "$gitstring")
+                       PS1="$ps1pc_start$gitstring$ps1pc_end"
                else
                        # NO color option unless in PROMPT_COMMAND mode
                        printf -- "$printf_format" "$c${b##refs/heads/}${f:+ $f}$r$p"