Fastest way to get git status in bash
Not entirely your answer, but bash-completion has this built-in.
If you set the bash ENV GIT_PS1_SHOWDIRTYSTATE to a nonempty value, unstaged (*) and staged (+) changes will be shown next to the branch name. You can configure this per-repository ith the bash.showDirtyState variable, which defaults to true once GIT_PS1_SHOWDIRTYSTATE is enabled.
You can also see if currently something is stashed, by setting GIT_PS1_SHOWSTASHSTATE to a nonempty value. If something is stashed, then a '$' will be shown next to the branch name.
If you would like to see if there are untracked files, then you can set GIT_PS1_SHOWUNTRACKEDFILES to a nonempty value. If there are untracked files, then a '%' will be shown next to the branch name.
Not sure about the speed degrade when you enable this though. If you want to do the coloring:
Staged files:
if git rev-parse --quiet --verify HEAD >/dev/null; then
git diff-index --cached --quiet HEAD -- || color for staged changes
else
color unstaged changes
fi
Stashed files
git rev-parse --verify refs/stash >/dev/null 2>&1 && color for stashed files
Untracked files
if [ -n "$(git ls-files --others --exclude-standard)" ]; then
Color untrack files
fi
The above snippets come from the bash-completion script.
Note: Git 2.6+ (Q3 2015) should accelerate that __git_ps1
status:
See commit dd160d7, commit 6bfab99 (19 Jul 2015) by SZEDER Gábor (szeder
).
(Merged by Junio C Hamano -- gitster
-- in commit 461c119, 03 Aug 2015)
bash prompt: faster untracked status indicator with untracked directories
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 ea95c7b (completion: improve untracked directory filtering for filename completion, 2013-09-18, git 1.8.5).
Make sure to tuse Git 2.29 (Q4 2020), as a leakfix is available in a part of the code which influences git ls-files
.
See commit eceba53, commit dad4f23 (18 Aug 2020) by Elijah Newren (newren
).
(Merged by Junio C Hamano -- gitster
-- in commit ad00f44, 24 Aug 2020)
dir
: fix problematic API to avoid memory leaksSigned-off-by: Elijah Newren
The
dir
structure seemed to have a number of leaks and problems around it.First I noticed that
parent_hashmap
andrecursive_hashmap
were being leaked (though Peff noticed and submitted fixes before me).Then I noticed in the previous commit that
clear_directory()
was only taking responsibility for a subset of fields withindir_struct,
despite the fact that entries[] and ignored[] we allocated internally todir.c
.
That, of course, resulted in many callers either leaking or haphazardly trying to free these arrays and their contents.Digging further, I found that despite the pretty clear documentation near the top of
dir.h
that folks were supposed to callclear_directory()
when the user no longer needed thedir_struct,
there were four callers that didn't bother doing that at all.
However, two of them clearly thought about leaks since they had anUNLEAK(dir)
directive, which to me suggests that the method to free the data was too unclear.
I suspect the non-obviousness of the API and its holes led folks to avoid it, which then snowballed into further problems with theentries[]
,ignored[]
,parent_hashmap,
andrecursive_hashmap
problems.Rename
clear_directory()
todir_clear()
to be more in line with other data structures in git, and introduce adir_init()
to handle the suggested memsetting ofdir_struct
to all zeroes.
I hope that a name like"dir_clear()
" is more clear, and that the presence ofdir_init()
will provide a hint to those looking at the code that they need to look for either adir_clear()
or adir_free()
and lead them to finddir_clear()
.
That influences:
git add
git check-ignore
git clean
git grep
git ls-files
git stash
git merge