git-aware-prompt icon indicating copy to clipboard operation
git-aware-prompt copied to clipboard

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

Open simonsthings opened this issue 7 years ago • 6 comments

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.

simonsthings avatar May 04 '17 12:05 simonsthings

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.

AaronDMarasco-VSI avatar May 04 '17 13:05 AaronDMarasco-VSI

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.

simonsthings avatar May 04 '17 13:05 simonsthings

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

AaronDMarasco-VSI avatar May 04 '17 13:05 AaronDMarasco-VSI

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)

simonsthings avatar May 04 '17 15:05 simonsthings

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 avatar Apr 25 '19 19:04 alanhamlett

Also, this one is faster:

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

alanhamlett avatar Apr 25 '19 23:04 alanhamlett