Anthony Mastrean
Anthony Mastrean

Reputation: 22394

Can I conditionally activate the Git prompt depending on the repository I'm in?

I'm using the built-in git prompt shell script to improve my Bash prompt.

. ~/git-completion.bash
. ~/git-prompt.sh

export GIT_PS1_SHOWDIRTYSTATE=1
export GIT_PS1_SHOWUNTRACKEDFILES=1
export GIT_PS1_SHOWUPSTREAM="auto"
export GIT_PS1_SHOWCOLORHINTS=1

I have this one enormous enterprise application repository (100s of thousands of files, a very deep directory tree, the .git directory is almost 2 GB). The prompt is taking a very long time to complete.

Is there some way to tell git-prompt.sh to ignore this workspace? Either by flags or in my .bashrc?

Upvotes: 6

Views: 2180

Answers (3)

Jeffery To
Jeffery To

Reputation: 11936

The built-in git prompt shell script has per-repository options you can set to speed up the prompt.

Set bash.showDirtyState to false to disable checking for changes:

$ git config --local --add bash.showDirtyState false

Set bash.showUntrackedFiles to false to stop checking for untracked files:

$ git config --local --add bash.showUntrackedFiles false

Set bash.showUpstream to the empty string to stop comparing HEAD with its upstream:

$ git config --local --add bash.showUpstream ''

Upvotes: 3

Anthony Mastrean
Anthony Mastrean

Reputation: 22394

Jubobs's answer got me thinking... I wanted to test for some condition that the large repository would satisfy. I didn't want to limit myself to one repository. And I needed this to work in all sub-directories of those repos.

I explored the git command itself. It does a bunch of work to search the directory tree for the .git folder. For example, this command will exit 0 if you're in a git repo and non-zero if not.

$ git rev-parse --git-dir &>/dev/null

That's neat, but not enough. I wanted to know if I'm in a git repo and ignoring the prompt. But, I didn't want to combine complicated conditionals. Then I thought about using a custom git config key.

$ git config --local prompt.ignore 1

I could run this test to see if it's non-empty. I should figure out how to test for 0 or empty vs. non-empty, but this is a start.

$ [[ -z $(git config prompt.ignore) ]]

That has the best features of all. I could add this to any repo. It participates in "is this a git repo?" discovery and answering the prompt ignore question, all in one!

I baked that into my .bashrc like so

function __my_ps1 {
  if [[ -z $(git config prompt.ignore) ]];
  then
    __git_ps1 "$PROMPT_PRE" "$PROMPT_POST"
  fi
}

export PROMPT_COMMAND=__my_ps1

I'm using the Git Bash prompt from the Git for Windows package and it has a pretty friendly prompt already. I wonder if I would need to provide an else branch for that prompt command in any other shell.

Upvotes: 4

jub0bs
jub0bs

Reputation: 66284

Define a conditional Git prompt

Take a look at the suggested Bash prompt definition in git-prompt.sh (but without the user and host, because they take too much space, and are irrelvant to your question):

PS1='[\W$(__git_ps1 " (%s)")]\$ '

Nothing prevents you from inserting a test in the command substitution, like so:

PS1='[\W$(if true; then __git_ps1 " (%s)"; fi)]\$ '

although this example is rather silly. Using this idea, you can define a conditional Git prompt such that,

  • if you're outside the working tree of the offending repo, the Git prompt is activated, and
  • if you're inside the repo in question, the Git prompt is deactived.

The following Bash prompt definition does exactly that:

export PS1='[\W$(if [[ ! $PWD/ = $OFFENDINGDIR/* ]]; then __git_ps1 " (%s)"; fi)]\$ '

where OFFENDINGDIR is a variable that must be assigned the path to the root directory of the offending repo.

Example

Assume that ~/projectA is the offending repo. For information, here is my default prompt definition:

PS1='\W\$ '

Very simple; no Git prompt whatsoever. Now, let's cd to the offending repository:

~$ cd projectA

# Let's check that we are indeed in a Git repo:
projectA$ git branch
* master

# Now let's set up our conditional Git prompt:
projectA$ export OFFENDINGDIR=$PWD
projectA$ export PS1='[\W$(if [[ ! $PWD/ = $OFFENDINGDIR/* ]]; then __git_ps1 " (%s)"; fi)]\$ '

# Our Bash prompt changes accordingly...
[projectA]$
# ... but notice that it contains no branch info (as desired).

# However, if we cd to another repo...
[projectA]$ cd ../projectB
[projectB (master)] $
# ... the Git prompt is there, as desired!

Upvotes: 4

Related Questions