summaryrefslogtreecommitdiff
path: root/contrib/completion/git-prompt.sh
AgeCommit message (Collapse)AuthorFilesLines
2020-06-22git-prompt: include sparsity state as wellLibravatar Elijah Newren1-2/+20
git-prompt includes the current branch, a bunch of single character mini-state displayers, and some much longer in-progress state notifications. The current branch is always shown. The single character mini-state displayers are all off by default (they are not self explanatory) but each has an environment variable for turning it on. The in-progress state notifications provide no configuration options for turning them off, and can be up to 15 characters long (e.g. "|REBASE (12/18)" or "|CHERRY-PICKING"). The single character mini-state tends to be used for things like "Do you have any stashes in refs/stash?" or "Are you ahead or behind of upstream?". These are things which users can take advantage of but do not affect most normal git operations. The in-progress states, by contrast, suggest the user needs to interact differently and may also prevent some normal operations from succeeding (e.g. git switch may show an error instead of switching branches). Sparsity is like the in-progress states in that it suggests a fundamental different interaction with the repository (many of the files from the repository are not present in your working copy!). A few commits ago added sparsity information to wt_longstatus_print_state(), grouping it with other in-progress state displays. We do similarly here with the prompt and show the extra state, by default, with an extra |SPARSE This state can be present simultaneously with the in-progress states, in which case it will appear before the other states; for example, (branchname|SPARSE|REBASE 6/10) The reason for showing the "|SPARSE" substring before other states is to emphasize those other states. Sparsity is probably not going to change much within a repository, while temporary operations will. So we want the state changes related to temporary operations to be listed last, to make them appear closer to where the user types and make them more likely to be noticed. The fact that sparsity isn't just cached metadata or additional information is what leads us to show it more similarly to the in-progress states, but the fact that sparsity is not transient like the in-progress states might cause some users to want an abbreviated notification of sparsity state or perhaps even be able to turn it off. Allow GIT_PS1_COMPRESSSPARSESTATE to be set to request that it be shortened to a single character ('?'), and GIT_PS1_OMITSPARSESTATE to be set to request that sparsity state be omitted from the prompt entirely. Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-06-22git-prompt: document how in-progress operations affect the promptLibravatar Elijah Newren1-0/+4
Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-02-16git-prompt: change the prompt for interactive-based rebasesLibravatar Elijah Newren1-5/+1
In the past, we had different prompts for different types of rebases: REBASE: for am-based rebases REBASE-m: for merge-based rebases REBASE-i: for interactive-based rebases It's not clear why this distinction was necessary or helpful; when the prompt was added in commit e75201963f67 ("Improve bash prompt to detect various states like an unfinished merge", 2007-09-30), it simply added these three different types. Perhaps there was a useful purpose back then, but there have been some changes: * The merge backend was deleted after being implemented on top of the interactive backend, causing the prompt for merge-based rebases to change from REBASE-m to REBASE-i. * The interactive backend is used for multiple different types of non-interactive rebases, so the "-i" part of the prompt doesn't really mean what it used to. * Rebase backends have gained more abilities and have a great deal of overlap, sometimes making it hard to distinguish them. * Behavioral differences between the backends have also been ironed out. * We want to change the default backend from am to interactive, which means people would get "REBASE-i" by default if we didn't change the prompt, and only if they specified --am or --whitespace or -C would they get the "REBASE" prompt. * In the future, we plan to have "--whitespace", "-C", and even "--am" run the interactive backend once it can handle everything the am-backend can. For all these reasons, make the prompt for any type of rebase just be "REBASE". Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-07-01git-prompt: improve cherry-pick/revert detectionLibravatar Phillip Wood1-4/+33
If the user commits or resets a conflict resolution in the middle of a sequence of cherry-picks or reverts then CHERRY_PICK_HEAD/REVERT_HEAD will be removed and so in the absence of those files we need to check .git/sequencer/todo to see if there is a cherry-pick or revert in progress. Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-12-06git-prompt: fix reading files with windows line endingsLibravatar Robert Abel1-1/+1
If any of the files read by __git_eread have \r\n line endings, read will only strip \n, leaving \r. This results in an ugly prompt, where instead of user@pc MINGW64 /path/to/repo (BARE:master) the last parenthesis is printed over the beginning of the prompt like )ser@pc MINGW64 /path/to/repo (BARE:master This patch fixes the issue by changing the internal field separator variable IFS to $'\r\n' before using the read builtin command. Note that ANSI-C Quoting/POSIX Quoting ($'...') is supported by bash as well as zsh, which are the current targets of git-prompt, cf. contrib/completion/git-prompt.sh. Signed-off-by: Robert Abel <rabel@robertabel.eu> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-12-06git-prompt: make __git_eread intended use explicitLibravatar Robert Abel1-3/+4
__git_eread is used to read a single line of a given file (if it exists) into a single variable stripping the EOL. This patch removes the unused capability to split file contents into tokens by passing multiple variable names. Add a comment and explicitly use $2 instead of misleading $@ as argument to the read builtin command. Signed-off-by: Robert Abel <rabel@robertabel.eu> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-03-15git-prompt: add a describe style for any tagsLibravatar Michael J Gruber1-0/+3
git-prompt has various describe styles, among them "describe" (by annotated tags) and "default" (by exact match with any tag). Add a mode "tag" that describes by any tag, annotated or not. Signed-off-by: Michael J Gruber <git@drmicha.warpmail.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-06-27Merge branch 'vs/prompt-avoid-unset-variable'Libravatar Junio C Hamano1-3/+3
The git-prompt scriptlet (in contrib/) was not friendly with those who uses "set -u", which has been fixed. * vs/prompt-avoid-unset-variable: git-prompt.sh: Don't error on null ${ZSH,BASH}_VERSION, $short_sha
2016-06-06git-prompt.sh: Don't error on null ${ZSH,BASH}_VERSION, $short_shaLibravatar Ville Skyttä1-3/+3
When the shell is in "nounset" or "set -u" mode, referencing unset or null variables results in an error. Protect $ZSH_VERSION and $BASH_VERSION against that, and initialize $short_sha before use. Signed-off-by: Ville Skyttä <ville.skytta@iki.fi> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-11-24bash prompt: indicate dirty index even on orphan branchesLibravatar SZEDER Gábor1-3/+2
__git_ps1() doesn't indicate dirty index while on an orphan branch. To check the dirtiness of the index, __git_ps1() runs 'git diff-index --cached ... HEAD', which doesn't work on an orphan branch, because HEAD doesn't point to a valid commit. Run 'git diff ... --cached' instead, as it does the right thing both on valid and invalid HEAD, i.e. compares the index to the existing HEAD in the former case and to the empty tree in the latter. This fixes the two failing tests added in the first commit of this series. The dirtiness of the worktree is already checked with 'git diff' and is displayed correctly even on an orphan branch. Signed-off-by: SZEDER Gábor <szeder@ira.uka.de> Signed-off-by: Jeff King <peff@peff.net>
2015-11-24bash prompt: remove a redundant 'git diff' optionLibravatar SZEDER Gábor1-1/+1
To get the dirty state indicator __git_ps1() runs 'git diff' with '--quiet --exit-code' options. '--quiet' already implies '--exit-code', so the latter is unnecessary and can be removed. Signed-off-by: SZEDER Gábor <szeder@ira.uka.de> Signed-off-by: Jeff King <peff@peff.net>
2015-07-20bash prompt: faster untracked status indicator with untracked directoriesLibravatar SZEDER Gábor1-1/+1
If the untracked status indicator is enabled, __git_ps1() looks for untracked files by running 'git ls-files'. This can be perceptibly slow in case of an untracked directory containing lot of files, because it lists all files found in the untracked directory only to be redirected into /dev/null right away (this is the actual command run by __git_ps1()): $ ls untracked-dir/ |wc -l 100000 $ time git ls-files --others --exclude-standard --error-unmatch \ -- ':/*' >/dev/null 2>/dev/null real 0m0.955s user 0m0.936s sys 0m0.016s Eliminate this delay by additionally passing the '--directory --no-empty-directory' options to 'git ls-files' to show only the name of non-empty untracked directories instead of all their content: $ time git ls-files --others --exclude-standard --directory \ --no-empty-directory --error-unmatch -- ':/*' >/dev/null 2>/dev/null real 0m0.010s user 0m0.008s sys 0m0.000s This follows suit of ea95c7b8f5 (completion: improve untracked directory filtering for filename completion, 2013-09-18). Signed-off-by: SZEDER Gábor <szeder@ira.uka.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-07-15Merge branch 'jc/prompt-document-ps1-state-separator' into maintLibravatar Junio C Hamano1-0/+4
Docfix. * jc/prompt-document-ps1-state-separator: git-prompt.sh: document GIT_PS1_STATESEPARATOR
2015-07-01Merge branch 'jc/prompt-document-ps1-state-separator'Libravatar Junio C Hamano1-0/+4
Docfix. * jc/prompt-document-ps1-state-separator: git-prompt.sh: document GIT_PS1_STATESEPARATOR
2015-06-10git-prompt.sh: document GIT_PS1_STATESEPARATORLibravatar Joe Cridge1-0/+4
The environment variable GIT_PS1_STATESEPARATOR can be used to set the separator between the branch name and the state symbols in the prompt. At present the variable is not mentioned in the inline documentation which makes it difficult for the casual user to identify. Signed-off-by: Joe Cridge <joe.cridge@me.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-03-25Merge branch 'ct/prompt-untracked-fix'Libravatar Junio C Hamano1-1/+1
The prompt script (in contrib/) did not show the untracked sign when working in a subdirectory without any untracked files. * ct/prompt-untracked-fix: git prompt: use toplevel to find untracked files
2015-03-15git prompt: use toplevel to find untracked filesLibravatar Cody A Taylor1-1/+1
The __git_ps1() prompt function would not show an untracked state when all the untracked files are outside the current working directory. Signed-off-by: Cody A Taylor <codemister99@yahoo.com> Helped-by: SZEDER Gábor <szeder@ira.uka.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-01-14Merge branch 'tf/prompt-preserve-exit-status'Libravatar Junio C Hamano1-5/+5
Using the exit status of the last command in the prompt, e.g. PS1='$(__git_ps1) $? ', did not work well because the helper function stomped on the exit status. * tf/prompt-preserve-exit-status: git-prompt: preserve value of $? in all cases
2015-01-14Merge branch 'rh/hide-prompt-in-ignored-directory'Libravatar Junio C Hamano1-7/+17
* rh/hide-prompt-in-ignored-directory: git-prompt.sh: allow to hide prompt for ignored pwd git-prompt.sh: if pc mode, immediately set PS1 to a plain prompt
2015-01-14git-prompt: preserve value of $? in all casesLibravatar Tony Finch1-4/+4
Signed-off-by: Tony Finch <dot@dotat.at> Reviewed-by: SZEDER Gábor <szeder@ira.uka.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-01-07Merge branch 'tf/prompt-preserve-exit-status'Libravatar Junio C Hamano1-0/+4
Using the exit status of the last command in the prompt, e.g. PS1='$(__git_ps1) $? ', did not work well because the helper function stomped on the exit status. * tf/prompt-preserve-exit-status: git-prompt: preserve value of $? inside shell prompt
2015-01-07git-prompt.sh: allow to hide prompt for ignored pwdLibravatar Jess Austin1-0/+13
Optionally set __git_ps1 to display nothing when present working directory is ignored, triggered by the new environment variable GIT_PS1_HIDE_IF_PWD_IGNORED. This environment variable may be overridden on any repository by setting bash.hideIfPwdIgnored to "false". In the absence of GIT_PS1_HIDE_IF_PWD_IGNORED this change has no effect. Many people manage e.g. dotfiles in their home directory with git. This causes the prompt generated by __git_ps1 to refer to that "top level" repo while working in any descendant directory. That can be distracting, so this patch helps one shut off that noise. Signed-off-by: Jess Austin <jess.austin@gmail.com> Signed-off-by: Richard Hansen <rhansen@bbn.com> Reviewed-by: Richard Hansen <rhansen@bbn.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-01-07git-prompt.sh: if pc mode, immediately set PS1 to a plain promptLibravatar Richard Hansen1-7/+4
At the beginning of __git_ps1, right after determining that the function is running in pc mode, set PS1 to a plain (undecorated) prompt. This makes it possible to simply return early without having to set PS1 if the prompt should not be decorated. Signed-off-by: Richard Hansen <rhansen@bbn.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-12-22Merge branch 'jg/prompt-localize-temporary'Libravatar Junio C Hamano1-1/+1
"git-prompt" (in contrib/) used a variable from the global scope, possibly contaminating end-user's namespace. * jg/prompt-localize-temporary: git-prompt.sh: make $f local to __git_eread()
2014-12-22git-prompt: preserve value of $? inside shell promptLibravatar Tony Finch1-0/+4
If you have a prompt which displays the command exit status, __git_ps1 without this change corrupts it, although it has the correct value in the parent shell: ~/src/git (master) 0 $ set | grep ^PS1 PS1='\w$(__git_ps1) $? \$ ' ~/src/git (master) 0 $ false ~/src/git (master) 0 $ echo $? 1 ~/src/git (master) 0 $ There is a slightly ugly workaround: ~/src/git (master) 0 $ set | grep ^PS1 PS1='\w$(x=$?; __git_ps1; exit $x) $? \$ ' ~/src/git (master) 0 $ false ~/src/git (master) 1 $ This change makes the workaround unnecessary. Signed-off-by: Tony Finch <dot@dotat.at> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-12-12git-prompt.sh: make $f local to __git_eread()Libravatar Justin Guenther1-1/+1
This function uses (non-local) $f to store the value of its first parameter. This can interfere with the user's environment. Signed-off-by: Justin Guenther <jguenther@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-08-25git-prompt: do not look for refs/stash in $GIT_DIRLibravatar Jeff King1-1/+2
Since dd0b72c (bash prompt: use bash builtins to check stash state, 2011-04-01), git-prompt checks whether we have a stash by looking for $GIT_DIR/refs/stash. Generally external programs should never do this, because they would miss packed-refs. That commit claims that packed-refs does not pack refs/stash, but that is not quite true. It does pack the ref, but due to a bug, fails to prune the ref. When we fix that bug, we would want to be doing the right thing here. Signed-off-by: Jeff King <peff@peff.net> Reviewed-by: Michael Haggerty <mhagger@alum.mit.edu> Reviewed-by: Ronnie Sahlberg <sahlberg@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-05-19Merge branch 'rh/prompt-pcmode-avoid-eval-on-refname'Libravatar Junio C Hamano1-17/+39
* rh/prompt-pcmode-avoid-eval-on-refname: git-prompt.sh: don't assume the shell expands the value of PS1
2014-05-19git-prompt.sh: don't assume the shell expands the value of PS1Libravatar Richard Hansen1-17/+39
Not all shells subject the prompt string to parameter expansion. Test whether the shell will expand the value of PS1, and use the result to control whether raw ref names are included directly in PS1. This fixes a regression introduced in commit 8976500 ("git-prompt.sh: don't put unsanitized branch names in $PS1"): zsh does not expand PS1 by default, but that commit assumed it did. The bug resulted in prompts containing the literal string '${__git_ps1_branch_name}' instead of the actual branch name. Reported-by: Caleb Thompson <caleb@calebthompson.io> Signed-off-by: Richard Hansen <rhansen@bbn.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-05-13Merge branch 'fc/prompt-zsh-read-from-file'Libravatar Junio C Hamano1-8/+8
* fc/prompt-zsh-read-from-file: contrib: completion: fix 'eread()' namespace
2014-05-13contrib: completion: fix 'eread()' namespaceLibravatar Felipe Contreras1-8/+8
Otherwise it might collide with a function of the same name in the user's environment. Suggested-by: SZEDER Gábor <szeder@ira.uka.de> Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-05-02Merge branch 'rh/prompt-pcmode-avoid-eval-on-refname'Libravatar Junio C Hamano1-2/+32
* rh/prompt-pcmode-avoid-eval-on-refname: git-prompt.sh: don't put unsanitized branch names in $PS1
2014-04-22git-prompt.sh: don't put unsanitized branch names in $PS1Libravatar Richard Hansen1-2/+32
Both bash and zsh subject the value of PS1 to parameter expansion, command substitution, and arithmetic expansion. Rather than include the raw, unescaped branch name in PS1 when running in two- or three-argument mode, construct PS1 to reference a variable that holds the branch name. Because the shells do not recursively expand, this avoids arbitrary code execution by specially-crafted branch names such as '$(IFS=_;cmd=sudo_rm_-rf_/;$cmd)'. Signed-off-by: Richard Hansen <rhansen@bbn.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-04-14prompt: fix missing file errors in zshLibravatar Felipe Contreras1-7/+14
zsh seems to have a bug while redirecting the stderr of the 'read' command: % read foo 2>/dev/null <foo zsh: no such file or directory: foo Which causes errors to be displayed when certain files are missing. Let's add a convenience function to manually check if the file is readable before calling "read". Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-10-28Merge branch 'sg/prompt-svn-remote-fix'Libravatar Junio C Hamano1-1/+1
Bash portability fix. * sg/prompt-svn-remote-fix: bash prompt: don't use '+=' operator in show upstream code path
2013-10-15bash prompt: don't use '+=' operator in show upstream code pathLibravatar SZEDER Gábor1-1/+1
The '+=' operator is not supported by old Bash versions (3.0) we still care about. Signed-off-by: SZEDER Gábor <szeder@ira.uka.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-10-14git-prompt.sh: optionally show upstream branch nameLibravatar Julien Carsique1-1/+6
When working with multiple remotes, it is common to switch the upstream from a remote to another. Doing so, the prompt may not be the expected one. Providing an option to display tracking information sounds useful. Add a "name" option to GIT_PS1_SHOWUPSTREAM which will show the upstream abbrev name. This option is ignored if "verbose" is false. Signed-off-by: Julien Carsique <julien.carsique@gmail.com> Improved-by: SZEDER Gábor <szeder@ira.uka.de> Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
2013-08-22contrib/git-prompt.sh: handle missing 'printf -v' more gracefullyLibravatar Brandon Casey1-1/+5
Old Bash (3.0) which is distributed with RHEL 4.X and other ancient platforms that are still in wide use, do not have a printf that supports -v. Neither does Zsh (which is already handled in the code). As suggested by Junio, let's test whether printf supports the -v option and store the result. Then later, we can use it to determine whether 'printf -v' can be used, or whether printf must be called in a subshell. Signed-off-by: Brandon Casey <drafnel@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-07-01Merge branch 'ed/color-prompt'Libravatar Junio C Hamano1-70/+41
Code clean-up for in-prompt status script (in contrib/). * ed/color-prompt: git-prompt.sh: add missing information in comments git-prompt.sh: do not print duplicate clean color code t9903: remove redundant tests git-prompt.sh: refactor colored prompt code t9903: add tests for git-prompt pcmode
2013-06-26git-prompt.sh: add missing information in commentsLibravatar Eduardo R. D'Avila1-11/+15
Mention that the command below is needed for prompt in ZSH with PS1: setopt PROMPT_SUBST Rephrase some parts that mention only the "current branch name" being displayed in the prompt. Replace it by stating that the "repository status" is displayed. Make it clear that colored prompt is only available in PROMPT_COMMAND/precmd mode. With-suggestions-by: SZEDER Gábor <szeder@ira.uka.de> Signed-off-by: Eduardo R. D'Avila <erdavila@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-06-26git-prompt.sh: do not print duplicate clean color codeLibravatar Eduardo R. D'Avila1-1/+1
Do not print a duplicate clean color code when there is no other indicators other than the current branch in colored prompt. Acked-by: SZEDER Gábor <szeder@ira.uka.de> Signed-off-by: Eduardo R. D'Avila <erdavila@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-06-26git-prompt.sh: refactor colored prompt codeLibravatar Eduardo R. D'Avila1-59/+26
__git_ps1_colorize_gitstring() sets color codes and builds the prompt gitstring. It has duplicated code to handle color codes for bash and zsh shells. __git_ps1() also has duplicated logic to build the prompt gitstring. Remove duplication of logic to build gitstring in __git_ps1_colorize_gitstring() and __git_ps1(). Leave in __git_ps1_colorize_gitstring() only logic to set color codes. Signed-off-by: Eduardo R. D'Avila <erdavila@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-06-24bash prompt: mention that PROMPT_COMMAND mode is fasterLibravatar SZEDER Gábor1-5/+5
__git_ps1() is usually added to the prompt inside a command substitution, imposing the overhead of fork()ing a subshell. Using __git_ps1() for $PROMPT_COMMAND is slightly faster, because it avoids that command substitution. Mention this in the comments about setting up the git prompt. The whole series speeds up the bash prompt on Windows/MSysGit considerably. Here are some timing results in three scenarios, each repeated 10 times: At the top of the work tree, before: $ time for i in {0..9} ; do prompt="$(__git_ps1)" ; done real 0m1.716s user 0m0.301s sys 0m0.772s After: real 0m0.687s user 0m0.075s sys 0m0.396s After, from $PROMPT_COMMAND: $ time for i in {0..9} ; do __git_ps1 '\h:\w' '$ ' ; done real 0m0.546s user 0m0.075s sys 0m0.181s At the top of the work tree, detached head, before: real 0m2.574s user 0m0.376s sys 0m1.207s After: real 0m1.139s user 0m0.151s sys 0m0.500s After, from $PROMPT_COMMAND: real 0m1.030s user 0m0.245s sys 0m0.336s In a subdirectory, during rebase, stash status indicator enabled, before: real 0m3.557s user 0m0.495s sys 0m1.767s After: real 0m0.717s user 0m0.120s sys 0m0.300s After, from $PROMPT_COMMAND: real 0m0.577s user 0m0.047s sys 0m0.258s On Linux the speedup ratio is comparable to Windows, but overall it was about an order of magnitude faster to begin with. The last case from above, repeated 100 times, before: $ time for i in {0..99} ; do prompt="$(__git_ps1)" ; done real 0m2.806s user 0m0.180s sys 0m0.264s After: real 0m0.857s user 0m0.020s sys 0m0.028s Signed-off-by: SZEDER Gábor <szeder@ira.uka.de>
2013-06-24bash prompt: avoid command substitution when finalizing gitstringLibravatar SZEDER Gábor1-1/+5
Before setting $PS1, __git_ps1() uses a command substitution to redirect the output from a printf into a variable. Spare the overhead of fork()ing a subshell by using 'printf -v <var>' to directly assign the output to that variable. zsh's printf doesn't support the '-v <var>' option, so stick with the command substitution when under zsh. Signed-off-by: SZEDER Gábor <szeder@ira.uka.de>
2013-06-24bash prompt: avoid command substitution when checking for untracked filesLibravatar SZEDER Gábor1-1/+1
When enabled, the bash prompt can indicate the presence of untracked files with a '%' sign. __git_ps1() checks for untracked files by running the '$(git ls-files --others --exclude-standard)' command substitution, and displays the indicator when there is no output. Avoid this command substitution by additionally passing '--error-unmatch *', and checking the command's return value. Signed-off-by: SZEDER Gábor <szeder@ira.uka.de>
2013-06-24bash prompt: use bash builtins to check stash stateLibravatar SZEDER Gábor1-2/+3
When the environment variable $GIT_PS1_SHOWSTASHSTATE is set __git_ps1() checks the presence of stashes by running 'git rev-parse --verify refs/stash'. This command not only checks that the 'refs/stash' ref exists but also, well, verifies that it's a valid ref. However, we don't need to be that thorough for the bash prompt. We can omit that verification and only check whether 'refs/stash' exists or not. Since 'git pack-refs' never packs 'refs/stash', it's a matter of checking the existence of a ref file. Perform this check using only bash builtins to spare the overhead of fork()+exec()ing a git process. Also run 'git pack-refs --all' in the corresponding test to document that the prompt script depends on 'git pack-refs' not packing 'refs/stash' and to catch possible breakages should this behavior ever change. Signed-off-by: SZEDER Gábor <szeder@ira.uka.de>
2013-06-24bash prompt: use bash builtins to check for unborn branch for dirty stateLibravatar SZEDER Gábor1-1/+1
When the dirty work tree and index status indicator is enabled, __git_ps1() checks for changes in the index by running 'git diff-index --cached --quiet HEAD --' and looking at its exit code. However, that makes sense only when HEAD points to a valid commit: on an unborn branch the failure of said command would be caused by the invalid HEAD, not by changes in the index. Therefore, __git_ps1() first checks for a valid HEAD by running 'git rev-parse --quiet --verify HEAD'. Since the previous patch we implicitly check HEAD's validity by running 'git rev-parse ... --short HEAD', making the dirty status indicator's 'git rev-parse' check redundant. It's sufficient to check for non-emptyness of the variable holding the abbreviated commit object name, thereby sparing the overhead of fork()+exec()ing a git process. Signed-off-by: SZEDER Gábor <szeder@ira.uka.de>
2013-06-24bash prompt: combine 'git rev-parse' for detached headLibravatar SZEDER Gábor1-4/+12
When describing a detached HEAD according to the $GIT_PS1_DESCRIBE environment variable fails, __git_ps1() now runs the '$(git rev-parse --short HEAD)' command substitution to get the abbreviated detached HEAD commit object name. This imposes the overhead of fork()ing a subshell and fork()+exec()ing a git process. Avoid this overhead by combining this command substitution with the "main" 'git rev-parse' execution for getting the path to the .git directory & co. This means that we'll look for the abbreviated commit object name even when it's not necessary, because we're on a branch or the detached HEAD can be described. It doesn't matter, however, because once 'git rev-parse' is up and running to fulfill all those other queries, the additional overhead of looking for the abbreviated commit object name is not measurable because it's lost in the noise. There is a caveat, however, when we are on an unborn branch, because in that case HEAD doesn't point to a valid commit, hence the query for the abbreviated commit object name fails. Therefore, '--short HEAD' must be the last options to 'git rev-parse' in order to get all the other necessary information for the prompt even on an unborn branch. Furthermore, in that case, and in that case only, 'git rev-parse' doesn't output the last line containing the abbreviated commit object name, obviously, so we have to take care to only parse it if 'git rev-parse' exited without any error. Although there are tests already excercising __git_ps1() on unborn branches, they all do so implicitly. Add a test that checks this explicitly. Signed-off-by: SZEDER Gábor <szeder@ira.uka.de>
2013-06-24bash prompt: combine 'git rev-parse' executions in the main code pathLibravatar SZEDER Gábor1-5/+13
There are a couple of '$(git rev-parse --<opt>)' command substitutions in __git_ps1() and three of them are executed in the main code path: - the first to get the path to the .git directory ('--git-dir'), - the second to check whether we're inside the .git directory ('--is-inside-git-dir'), - and the last, depending on the results of the second, either * to check whether it's a bare repo ('--is-bare-repository'), or * to check whether inside a work tree ('--is-inside-work-tree'). Naturally, this imposes the overhead of fork()ing three subshells and fork()+exec()ing three git commands. Combine these four 'git rev-parse' queries into a single one and use bash parameter expansions to parse the combined output, i.e. to separate the path to the .git directory from the true/false of '--is-inside-git-dir', etc. This way we can eliminate two of the three subshells and git commands. Signed-off-by: SZEDER Gábor <szeder@ira.uka.de>
2013-06-24bash prompt: use bash builtins to find out current branchLibravatar SZEDER Gábor1-18/+33
__git_ps1() runs the '$(git symbolic-ref HEAD)' command substitution to find out whether we are on a branch and to find out the name of that branch. This imposes the overhead of fork()ing a subshell and fork()+exec()ing a git process. Since HEAD is in most cases a single-line file and the symbolic ref format is quite simple to recognize and parse, read and parse it using only bash builtins, thereby sparing all that fork()+exec() overhead. Don't display the git prompt if reading HEAD fails, because a readable HEAD is required for a git repository. HEAD can also be a symlink symbolic ref (due to 'core.preferSymlinkRefs'), so use bash builtins for reading HEAD only when HEAD is not a symlink. Signed-off-by: SZEDER Gábor <szeder@ira.uka.de>