在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
开源软件名称:romkatv/gitstatus开源软件地址:https://github.com/romkatv/gitstatus开源编程语言:C++ 59.5%开源软件介绍:gitstatusgitstatus is a 10x faster alternative to Heavy lifting is done by gitstatusd -- a custom binary written in C++. It comes with Zsh and Bash bindings for integration with shell. Table of Contents
Using from ZshThe easiest way to take advantage of gitstatus from Zsh is to use a theme that's already integrated with it. For example, Powerlevel10k is a flexible and fast theme with first-class gitstatus integration. For those who wish to use gitstatus without a theme, there is gitstatus.prompt.zsh. Install it as follows: git clone --depth=1 https://github.com/romkatv/gitstatus.git ~/gitstatus
echo 'source ~/gitstatus/gitstatus.prompt.zsh' >>! ~/.zshrc Users in mainland China can use the official mirror on gitee.com for faster download. git clone --depth=1 https://gitee.com/romkatv/gitstatus.git ~/gitstatus
echo 'source ~/gitstatus/gitstatus.prompt.zsh' >>! ~/.zshrc Alternatively, if you have Homebrew installed: brew install romkatv/gitstatus/gitstatus
echo "source $(brew --prefix)/opt/gitstatus/gitstatus.prompt.zsh" >>! ~/.zshrc (If you choose this option, replace Make sure to disable your current theme if you have one. This will give you a basic yet functional prompt with git status in it. It's
over 10x faster than any alternative that can give you comparable prompt. In order
to customize it, set source ~/gitstatus/gitstatus.prompt.zsh
PROMPT='%~%# ' # left prompt: directory followed by %/# (normal/root)
RPROMPT='$GITSTATUS_PROMPT' # right prompt: git status The expansion of
If you'd like to change the format of git status, or want to have greater control over the
process of assembling source ~/gitstatus/gitstatus.plugin.zsh
function my_set_prompt() {
PROMPT='%~%# '
RPROMPT=''
if gitstatus_query MY && [[ $VCS_STATUS_RESULT == ok-sync ]]; then
RPROMPT=${${VCS_STATUS_LOCAL_BRANCH:-@${VCS_STATUS_COMMIT}}//\%/%%} # escape %
(( VCS_STATUS_NUM_STAGED )) && RPROMPT+='+'
(( VCS_STATUS_NUM_UNSTAGED )) && RPROMPT+='!'
(( VCS_STATUS_NUM_UNTRACKED )) && RPROMPT+='?'
fi
setopt no_prompt_{bang,subst} prompt_percent # enable/disable correct prompt expansions
}
gitstatus_stop 'MY' && gitstatus_start -s -1 -u -1 -c -1 -d -1 'MY'
autoload -Uz add-zsh-hook
add-zsh-hook precmd my_set_prompt This snippet is sourcing Unlike Powerlevel10k, code based on
gitstatus.prompt.zsh is communicating with gitstatusd synchronously. This
can make your prompt slow when working in a large git repository or on a slow machine. To avoid
this problem, call Using from BashThe easiest way to take advantage of gitstatus from Bash is via gitstatus.prompt.sh. Install it as follows: git clone --depth=1 https://github.com/romkatv/gitstatus.git ~/gitstatus
echo 'source ~/gitstatus/gitstatus.prompt.sh' >> ~/.bashrc Users in mainland China can use the official mirror on gitee.com for faster download. git clone --depth=1 https://gitee.com/romkatv/gitstatus.git ~/gitstatus
echo 'source ~/gitstatus/gitstatus.prompt.sh' >> ~/.bashrc Alternatively, if you have Homebrew installed: brew install romkatv/gitstatus/gitstatus
echo "source $(brew --prefix)/opt/gitstatus/gitstatus.prompt.sh" >> ~/.bashrc (If you choose this option, replace This will give you a basic yet functional prompt with git status in it. It's over 10x faster than any alternative that can give you comparable prompt. In order to customize your prompt, set source ~/gitstatus/gitstatus.prompt.sh
PS1='\w ${GITSTATUS_PROMPT}\n\$ ' # directory followed by git status and $/# (normal/root) The expansion of
If you'd like to change the format of git status, or want to have greater control over the
process of assembling source ~/gitstatus/gitstatus.plugin.sh
function my_set_prompt() {
PS1='\w'
if gitstatus_query && [[ "$VCS_STATUS_RESULT" == ok-sync ]]; then
if [[ -n "$VCS_STATUS_LOCAL_BRANCH" ]]; then
PS1+=" ${VCS_STATUS_LOCAL_BRANCH//\\/\\\\}" # escape backslash
else
PS1+=" @${VCS_STATUS_COMMIT//\\/\\\\}" # escape backslash
fi
(( VCS_STATUS_HAS_STAGED" )) && PS1+='+'
(( VCS_STATUS_HAS_UNSTAGED" )) && PS1+='!'
(( VCS_STATUS_HAS_UNTRACKED" )) && PS1+='?'
fi
PS1+='\n\$ '
shopt -u promptvars # disable expansion of '$(...)' and the like
}
gitstatus_stop && gitstatus_start
PROMPT_COMMAND=my_set_prompt This snippet is sourcing Note: Bash bindings, unlike Zsh bindings, don't support asynchronous calls. Using from other shellsIf there are no gitstatusd bindings for your shell, you'll need to get your hands dirty.
Use the existing bindings for inspiration; run How it worksgitstatusd reads requests from stdin and prints responses to stdout. Requests contain an ID and a directory. Responses contain the same ID and machine-readable git status for the directory. gitstatusd keeps some state in memory for the directories it has seen in order to serve future requests faster. Zsh bindings and Bash bindings start gitstatusd in
the background and communicate with it via pipes. Themes such as
Powerlevel10k use these bindings to put git status in
Note that gitstatus cannot be used as a drop-in replacement for BenchmarksThe following benchmark results were obtained on Intel i9-7900X running Ubuntu 18.04 in
a clean chromium repository synced to Three functionally equivalent tools for computing git status were benchmarked:
Every tool was benchmark in cold and hot conditions. For Two commands were benchmarked: StatusIn this benchmark all tools were computing the equivalent of
gitstatusd is substantially faster than the alternatives, especially on hot runs. Note that hot runs are of primary importance to the main use case of gitstatus in interactive shells. The performance of DescribeIn this benchmark all tools were computing the equivalent of
gitstatusd is once again faster than the alternatives, more so on hot runs. Why fastSince gitstatusd doesn't have to print all staged/unstaged/untracked files but only report whether there are any, it can terminate repository scan early. It can also remember which files were dirty on the previous run and check them first on the next run to avoid the scan entirely if the files are still dirty. However, the benchmarks above were performed in a clean repository where these shortcuts do not trigger. All benchmarked tools had to do the same work -- check the status of every file in the index to see if it has changed, check every directory for newly created files, etc. And yet, gitstatusd came ahead by a large margin. This section describes what it does that makes it so fast. Most of the following comparisons are done against libgit2 rather than git because of the author's familiarity with the former but not the with latter. libgit2 has clean, well-documented APIs and an elegant implementation, which makes it so much easier to work with and to analyze performance bottlenecks. Summary for the impatientUnder the benchmark conditions described above, the equivalent of libgit2's
Problem statementThe most resource-intensive part of the
This list needs to be compared to the list of files in the working directory. If any of the files
listed in the index are missing from the workdir or have different last modification time, they are
"unstaged" in gitstatusd parlance. If you run In addition, all files in the working directory for which there is no entry in the index at all are
"untracked". Single-threaded scanLet's see how (The CPU profile was created with gperftools and rendered with pprof). We can see Now let's take a look at the CPU profile of gitstatusd on the same task. The first impression is that this profile looks pruned. This isn't an artifact. The profile was generated with the same tools and the same flags as the profile of libgit2. Since both profiles were generated from the same workload, absolute numbers can be compared. We can
see that gitstatusd took 62 seconds in total compared to libgit2's 232 seconds. System calls at the
core of the algorithm are cleary visible. So, one reason gitstatusd is fast is that it has efficient diffing code -- very little time is spent
outside of kernel. However, if we look closely, we can notice that system calls in gitstatusd are
also faster than in libgit2. For example, libgit2 spent 72.07 seconds in Similarly to There is no equivalent to To summarize, here's what gitstatusd was doing when the CPU profile was captured:
Here's how the very first scan of a repository looks like in gitstatusd: (Some glibc functions are mislabel on this profile. This is a superset of the previous -- hot -- profile, with an extra MultithreadingThe diffing algorithm in gitstatusd was designed from the ground up with the intention of using it
concurrently from multiple threads. With a fast SSD, gitstatusd exhibits almost perfect scaling from multithreading. Engaging all cores allows it to produce results 12.4 times faster than in single-threaded execution. This is on Intel i9-7900X with 10 cores (20 with hyperthreading) with single-core frequency of 4.3GHz and all-core frequency of 4.0GHz. Note: PostprocessingOnce the difference between the index and the workdir is found, we have a list of candidates --
files that may be unstaged or untracked. To make the final judgement, these files need to be checked
against gitstatusd uses patched libgit2 for this step. This fork
adds several optimizations that make libgit2 faster. The patched libgit2 performs more than twice
as fast in the benchmark as the original even without changes in the user code (that is, in the
code that uses the libgit2 APIs). The fork also adds several API extensions, most notable of which
is the support for multi-threaded scans. If WARNING: Changes to libgit2 are extensive but the testing they underwent isn't. It is not recommended to use the patched libgit2 in production. Requirements
CompilingThere are prebuilt If prebuilt binaries don't work for you, you'll need to get your hands dirty. Compiling for personal usegit clone --depth=1 https://github.com/romkatv/gitstatus.git
cd gitstatus
./build -w -s -d docker Users in mainland China can use the official mirror on gitee.com for faster download. git clone --depth=1 https://gitee.com/romkatv/gitstatus.git
cd gitstatus
./build -w -s -d docker
If everything goes well, the newly built binary will appear in When you update shell bindings, they may refuse to work with the binary you've built earlier. In this case you'll need to rebuild. If you are using gitstatus through Powerlevel10k, the
instructions are the same except that you don't need to clone gitstatus. Instead, change your
current directory to Compiling for distributionIt's currently neither easy nor recommended to package and distribute gitstatus. There are no instructions you can follow that would allow you to easily update your package when new versions of gitstatus are released. This may change in the future but not soon. LicenseGNU General Public License v3.0. See LICENSE. Contributions are covered by the same license. |
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13
请发表评论