jimeh / git-aware-prompt

Display current Git branch name in your terminal prompt when in a Git working directory.
Creative Commons Zero v1.0 Universal
2.15k stars 340 forks source link

Performance improvement for large repos! (Avoid using "git status") #52

Open simonsthings opened 7 years ago

simonsthings commented 7 years ago

The function find_git_dirty() delayed prompt display by over a second when in a large repo, so I now use the plumbing commands instead of "git status". Because we don't actually need to generate a list of all the changed files just to see if the repo is dirty. Further improvements possible.

Also, there's some more verbosity to keep the command output reliable. (Errcode 128 applies e.g. when in any .git folder)

Finally, I surrounded this by the test for branch name as in find_git_branch(), to avoid output on non-git folders. Other implementation imaginable.

AaronDMarasco-VSI commented 7 years ago

I have had problems with this in large repos as well, and appreciate the improvement.

However, in the past, I've had trouble with "git rev-parse" before. I'll annotate the changeset.

simonsthings commented 7 years ago

Ah just saw that this also doesn't show dirty for untracked files. But I think there were some other pull requestes dealing with that? Might be good to have two separate indicators for this, anyway.

AaronDMarasco-VSI commented 7 years ago

Honestly, I don't want/use untracked indication. That is different than dirty.

simonsthings commented 7 years ago

Oh, oops. Well, now i've made them anyway. But people can now choose which indicator they want to use. (And the speed benefits over "git status" are still present.) (Otherwise just only use the first commit)

alanhamlett commented 5 years ago

This change is still slow for me on very large repos. Here's a function to read .git/HEAD for branch name which is extremely fast:

alanhamlett/dotfiles/bashrc#L15

find_git_branch() {
  local firstline
  local folder
  folder=`pwd`
  while [ "$folder" != "/" ] ; do
    if [[ -f "$folder/.git/HEAD" ]]; then
      break
    fi
    folder=`dirname "$folder"`
  done
  if [ "$folder" != "/" ] ; then
    read -r firstline<"$folder/.git/HEAD"
    git_branch="(${firstline/ref: refs\/heads\//})"
  else
    git_branch=""
  fi
}
alanhamlett commented 5 years ago

Also, this one is faster:

https://github.com/git/git/blob/master/contrib/completion/git-prompt.sh