From a56eac7a71a774a4d97bb9456f36b8eb495329d5 Mon Sep 17 00:00:00 2001 From: Hong Date: Mon, 10 Oct 2016 13:24:30 -0700 Subject: Use OSTYPE instead of uname whenever possible for better speed. (#5496) --- plugins/gitfast/git-completion.bash | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'plugins/gitfast') diff --git a/plugins/gitfast/git-completion.bash b/plugins/gitfast/git-completion.bash index e3918c87e..8ce6b5c5f 100644 --- a/plugins/gitfast/git-completion.bash +++ b/plugins/gitfast/git-completion.bash @@ -2771,6 +2771,6 @@ __git_complete gitk __gitk_main # when the user has tab-completed the executable name and consequently # included the '.exe' suffix. # -if [ Cygwin = "$(uname -o 2>/dev/null)" ]; then +if [[ "$OSTYPE" = cygwin* ]]; then __git_complete git.exe __git_main fi -- cgit v1.2.3-70-g09d2 From a0c1eb32306734085ed26e2447f1050768b95d24 Mon Sep 17 00:00:00 2001 From: Forrest Wolf Date: Sat, 6 Oct 2018 12:12:45 -0400 Subject: Add README.md to the gitfast plugin (#7241) * Create gitfast readme * Add list of gitfast aliases --- plugins/gitfast/README.md | 138 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 138 insertions(+) create mode 100644 plugins/gitfast/README.md (limited to 'plugins/gitfast') diff --git a/plugins/gitfast/README.md b/plugins/gitfast/README.md new file mode 100644 index 000000000..c3073709e --- /dev/null +++ b/plugins/gitfast/README.md @@ -0,0 +1,138 @@ +# Gitfast plugin + +This plugin adds completion for Git, using the zsh completion from git.git folks, which is much faster than the official one from zsh. A lot of zsh-specific features are not supported, like descriptions for every argument, but everything the bash completion has, this one does too (as it is using it behind the scenes). Not only is it faster, it should be more robust, and updated regularly to the latest git upstream version.. + +To use it, add `gitfast` to the plugins array in your zshrc file: + +```zsh +plugins=(... gitfast) +``` + +## Aliases + +| Alias | Command | +| -------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | +| g | `git` | +| ga | `git add` | +| gaa | `git add --all` | +| gapa | `git add --patch` | +| gau | `git add --update` | +| gb | `git branch` | +| gba | `git branch -a` | +| gbd | `git branch -d` | +| gbda | `git branch --no-color --merged | command grep -vE "^(\*|\s*(master|develop|dev)\s*$)" | command xargs -n 1 git branch -d` | +| gbl | `git blame -b -w` | +| gbnm | `git branch --no-merged` | +| gbr | `git branch --remote` | +| gbs | `git bisect` | +| gbsb | `git bisect bad` | +| gbsg | `git bisect good` | +| gbsr | `git bisect reset` | +| gbss | `git bisect start` | +| gc | `git commit -v` | +| gc! | `git commit -v --amend` | +| gca | `git commit -v -a` | +| gca! | `git commit -v -a --amend` | +| gcam | `git commit -a -m` | +| gcan! | `git commit -v -a --no-edit --amend` | +| gcans! | `git commit -v -a -s --no-edit --amend` | +| gcb | `git checkout -b` | +| gcd | `git checkout develop` | +| gcf | `git config --list` | +| gcl | `git clone --recursive` | +| gclean | `git clean -fd` | +| gcm | `git checkout master` | +| gcmsg | `git commit -m` | +| gcn! | `git commit -v --no-edit --amend` | +| gco | `git checkout` | +| gcount | `git shortlog -sn` | +| gcp | `git cherry-pick` | +| gcpa | `git cherry-pick --abort` | +| gcpc | `git cherry-pick --continue` | +| gcs | `git commit -S` | +| gcsm | `git commit -s -m` | +| gd | `git diff` | +| gdca | `git diff --cached` | +| gdct | `` git describe --tags `git rev-list --tags --max-count=1` `` | +| gdt | `git diff-tree --no-commit-id --name-only -r` | +| gdw | `git diff --word-diff` | +| gf | `git fetch` | +| gfa | `git fetch --all --prune` | +| gfo | `git fetch origin` | +| gg | `git gui citool` | +| gga | `git gui citool --amend` | +| ggpull | `git pull origin $(git_current_branch)` | +| ggpur | `ggu` | +| ggpush | `git push origin $(git_current_branch)` | +| ggsup | `git branch --set-upstream-to=origin/$(git_current_branch)` | +| ghh | `git help` | +| gignore | `git update-index --assume-unchanged` | +| gignored | `git ls-files -v | grep "^[[:lower:]]"` | +| git-svn-dcommit-push | `git svn dcommit && git push github master:svntrunk` | +| gk | `\gitk --all --branches` | +| gke | `\gitk --all $(git log -g --pretty=%h)` | +| gl | `git pull` | +| glg | `git log --stat` | +| glgg | `git log --graph` | +| glgga | `git log --graph --decorate --all` | +| glgm | `git log --graph --max-count=10` | +| glgp | `git log --stat -p` | +| glo | `git log --oneline --decorate` | +| glog | `git log --oneline --decorate --graph` | +| gloga | `git log --oneline --decorate --graph --all` | +| glol | `git log --graph --pretty='\''%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset'\'' --abbrev-commit` | +| glola | `git log --graph --pretty='\''%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset'\'' --abbrev-commit --all` | +| glp | `_git_log_prettily` | +| glum | `git pull upstream master` | +| gm | `git merge` | +| gmom | `git merge origin/master` | +| gmt | `git mergetool --no-prompt` | +| gmtvim | `git mergetool --no-prompt --tool=vimdiff` | +| gmum | `git merge upstream/master` | +| gp | `git push` | +| gpd | `git push --dry-run` | +| gpoat | `git push origin --all && git push origin --tags` | +| gpristine | `git reset --hard && git clean -dfx` | +| gpsup | `git push --set-upstream origin $(git_current_branch)` | +| gpu | `git push upstream` | +| gpv | `git push -v` | +| gr | `git remote` | +| gra | `git remote add` | +| grb | `git rebase` | +| grba | `git rebase --abort` | +| grbc | `git rebase --continue` | +| grbi | `git rebase -i` | +| grbm | `git rebase master` | +| grbs | `git rebase --skip` | +| grh | `git reset HEAD` | +| grhh | `git reset HEAD --hard` | +| grmv | `git remote rename` | +| grrm | `git remote remove` | +| grset | `git remote set-url` | +| grt | `cd $(git rev-parse --show-toplevel || echo ".")` | +| gru | `git reset --` | +| grup | `git remote update` | +| grv | `git remote -v` | +| gsb | `git status -sb` | +| gsd | `git svn dcommit` | +| gsi | `git submodule init` | +| gsps | `git show --pretty=short --show-signature` | +| gsr | `git svn rebase` | +| gss | `git status -s` | +| gst | `git status` | +| gsta | `git stash save` | +| gstaa | `git stash apply` | +| gstc | `git stash clear` | +| gstd | `git stash drop` | +| gstl | `git stash list` | +| gstp | `git stash pop` | +| gsts | `git stash show --text` | +| gsu | `git submodule update` | +| gts | `git tag -s` | +| gtv | `git tag | sort -V` | +| gunignore | `git update-index --no-assume-unchanged` | +| gunwip | `git log -n 1 | grep -q -c "\-\-wip\-\-" && git reset HEAD~1` | +| gup | `git pull --rebase` | +| gupv | `git pull --rebase -v` | +| gwch | `git whatchanged -p --abbrev-commit --pretty=medium` | +| gwip | `git add -A; git rm $(git ls-files --deleted) 2> /dev/null; git commit --no-verify -m "--wip-- [skip ci]"` | -- cgit v1.2.3-70-g09d2 From 8c95c2b6cb339379dda5e39a0eef795cab1dae7a Mon Sep 17 00:00:00 2001 From: Marc Cornellà Date: Mon, 8 Apr 2019 20:06:17 +0200 Subject: gitfast: update plugin (#7152) * Stop loading git plugin * Update completion and git-prompt to v2.10 * Update completion to v2.14 --- plugins/gitfast/_git | 11 +- plugins/gitfast/git-completion.bash | 913 ++++++++++++++++++++++++++++-------- plugins/gitfast/git-prompt.sh | 9 +- plugins/gitfast/gitfast.plugin.zsh | 7 +- 4 files changed, 747 insertions(+), 193 deletions(-) (limited to 'plugins/gitfast') diff --git a/plugins/gitfast/_git b/plugins/gitfast/_git index 6d1b4ecc7..78a6dbb3d 100644 --- a/plugins/gitfast/_git +++ b/plugins/gitfast/_git @@ -9,7 +9,7 @@ # # If your script is somewhere else, you can configure it on your ~/.zshrc: # -# zstyle ':completion:*:*:git:*' script ~/.git-completion.sh +# zstyle ':completion:*:*:git:*' script ~/.git-completion.zsh # # The recommended way to install this script is to copy to '~/.zsh/_git', and # then add the following to your ~/.zshrc file: @@ -67,6 +67,15 @@ __gitcomp () esac } +__gitcomp_direct () +{ + emulate -L zsh + + local IFS=$'\n' + compset -P '*[=:]' + compadd -Q -- ${=1} && _ret=0 +} + __gitcomp_nl () { emulate -L zsh diff --git a/plugins/gitfast/git-completion.bash b/plugins/gitfast/git-completion.bash index 8ce6b5c5f..d93441747 100644 --- a/plugins/gitfast/git-completion.bash +++ b/plugins/gitfast/git-completion.bash @@ -28,27 +28,55 @@ # completion style. For example '!f() { : git commit ; ... }; f' will # tell the completion to use commit completion. This also works with aliases # of form "!sh -c '...'". For example, "!sh -c ': git commit ; ... '". +# +# You can set the following environment variables to influence the behavior of +# the completion routines: +# +# GIT_COMPLETION_CHECKOUT_NO_GUESS +# +# When set to "1", do not include "DWIM" suggestions in git-checkout +# completion (e.g., completing "foo" when "origin/foo" exists). case "$COMP_WORDBREAKS" in *:*) : great ;; *) COMP_WORDBREAKS="$COMP_WORDBREAKS:" esac +# Discovers the path to the git repository taking any '--git-dir=' and +# '-C ' options into account and stores it in the $__git_repo_path +# variable. +__git_find_repo_path () +{ + if [ -n "$__git_repo_path" ]; then + # we already know where it is + return + fi + + if [ -n "${__git_C_args-}" ]; then + __git_repo_path="$(git "${__git_C_args[@]}" \ + ${__git_dir:+--git-dir="$__git_dir"} \ + rev-parse --absolute-git-dir 2>/dev/null)" + elif [ -n "${__git_dir-}" ]; then + test -d "$__git_dir" && + __git_repo_path="$__git_dir" + elif [ -n "${GIT_DIR-}" ]; then + test -d "${GIT_DIR-}" && + __git_repo_path="$GIT_DIR" + elif [ -d .git ]; then + __git_repo_path=.git + else + __git_repo_path="$(git rev-parse --git-dir 2>/dev/null)" + fi +} + +# Deprecated: use __git_find_repo_path() and $__git_repo_path instead # __gitdir accepts 0 or 1 arguments (i.e., location) # returns location of .git repo __gitdir () { if [ -z "${1-}" ]; then - if [ -n "${__git_dir-}" ]; then - echo "$__git_dir" - elif [ -n "${GIT_DIR-}" ]; then - test -d "${GIT_DIR-}" || return 1 - echo "$GIT_DIR" - elif [ -d .git ]; then - echo .git - else - git rev-parse --git-dir 2>/dev/null - fi + __git_find_repo_path || return 1 + echo "$__git_repo_path" elif [ -d "$1/.git" ]; then echo "$1/.git" else @@ -56,6 +84,14 @@ __gitdir () fi } +# Runs git with all the options given as argument, respecting any +# '--git-dir=' and '-C ' options present on the command line +__git () +{ + git ${__git_C_args:+"${__git_C_args[@]}"} \ + ${__git_dir:+--git-dir="$__git_dir"} "$@" 2>/dev/null +} + # The following function is based on code from: # # bash_completion - programmable completion functions for bash 3.2+ @@ -185,6 +221,20 @@ _get_comp_words_by_ref () } fi +# Fills the COMPREPLY array with prefiltered words without any additional +# processing. +# Callers must take care of providing only words that match the current word +# to be completed and adding any prefix and/or suffix (trailing space!), if +# necessary. +# 1: List of newline-separated matching completion words, complete with +# prefix and suffix. +__gitcomp_direct () +{ + local IFS=$'\n' + + COMPREPLY=($1) +} + __gitcompappend () { local x i=${#COMPREPLY[@]} @@ -283,11 +333,11 @@ __gitcomp_file () __git_ls_files_helper () { if [ "$2" == "--committable" ]; then - git -C "$1" diff-index --name-only --relative HEAD + __git -C "$1" diff-index --name-only --relative HEAD else # NOTE: $2 is not quoted in order to support multiple options - git -C "$1" ls-files --exclude-standard $2 - fi 2>/dev/null + __git -C "$1" ls-files --exclude-standard $2 + fi } @@ -299,99 +349,195 @@ __git_ls_files_helper () # slash. __git_index_files () { - local dir="$(__gitdir)" root="${2-.}" file + local root="${2-.}" file - if [ -d "$dir" ]; then - __git_ls_files_helper "$root" "$1" | - while read -r file; do - case "$file" in - ?*/*) echo "${file%%/*}" ;; - *) echo "$file" ;; - esac - done | sort | uniq - fi + __git_ls_files_helper "$root" "$1" | + while read -r file; do + case "$file" in + ?*/*) echo "${file%%/*}" ;; + *) echo "$file" ;; + esac + done | sort | uniq } +# Lists branches from the local repository. +# 1: A prefix to be added to each listed branch (optional). +# 2: List only branches matching this word (optional; list all branches if +# unset or empty). +# 3: A suffix to be appended to each listed branch (optional). __git_heads () { - local dir="$(__gitdir)" - if [ -d "$dir" ]; then - git --git-dir="$dir" for-each-ref --format='%(refname:short)' \ - refs/heads - return - fi + local pfx="${1-}" cur_="${2-}" sfx="${3-}" + + __git for-each-ref --format="${pfx//\%/%%}%(refname:strip=2)$sfx" \ + "refs/heads/$cur_*" "refs/heads/$cur_*/**" } +# Lists tags from the local repository. +# Accepts the same positional parameters as __git_heads() above. __git_tags () { - local dir="$(__gitdir)" - if [ -d "$dir" ]; then - git --git-dir="$dir" for-each-ref --format='%(refname:short)' \ - refs/tags - return - fi + local pfx="${1-}" cur_="${2-}" sfx="${3-}" + + __git for-each-ref --format="${pfx//\%/%%}%(refname:strip=2)$sfx" \ + "refs/tags/$cur_*" "refs/tags/$cur_*/**" } -# __git_refs accepts 0, 1 (to pass to __gitdir), or 2 arguments -# presence of 2nd argument means use the guess heuristic employed -# by checkout for tracking branches +# Lists refs from the local (by default) or from a remote repository. +# It accepts 0, 1 or 2 arguments: +# 1: The remote to list refs from (optional; ignored, if set but empty). +# Can be the name of a configured remote, a path, or a URL. +# 2: In addition to local refs, list unique branches from refs/remotes/ for +# 'git checkout's tracking DWIMery (optional; ignored, if set but empty). +# 3: A prefix to be added to each listed ref (optional). +# 4: List only refs matching this word (optional; list all refs if unset or +# empty). +# 5: A suffix to be appended to each listed ref (optional; ignored, if set +# but empty). +# +# Use __git_complete_refs() instead. __git_refs () { - local i hash dir="$(__gitdir "${1-}")" track="${2-}" + local i hash dir track="${2-}" + local list_refs_from=path remote="${1-}" local format refs - if [ -d "$dir" ]; then - case "$cur" in + local pfx="${3-}" cur_="${4-$cur}" sfx="${5-}" + local match="${4-}" + local fer_pfx="${pfx//\%/%%}" # "escape" for-each-ref format specifiers + + __git_find_repo_path + dir="$__git_repo_path" + + if [ -z "$remote" ]; then + if [ -z "$dir" ]; then + return + fi + else + if __git_is_configured_remote "$remote"; then + # configured remote takes precedence over a + # local directory with the same name + list_refs_from=remote + elif [ -d "$remote/.git" ]; then + dir="$remote/.git" + elif [ -d "$remote" ]; then + dir="$remote" + else + list_refs_from=url + fi + fi + + if [ "$list_refs_from" = path ]; then + if [[ "$cur_" == ^* ]]; then + pfx="$pfx^" + fer_pfx="$fer_pfx^" + cur_=${cur_#^} + match=${match#^} + fi + case "$cur_" in refs|refs/*) format="refname" - refs="${cur%/*}" + refs=("$match*" "$match*/**") track="" ;; *) for i in HEAD FETCH_HEAD ORIG_HEAD MERGE_HEAD; do - if [ -e "$dir/$i" ]; then echo $i; fi + case "$i" in + $match*) + if [ -e "$dir/$i" ]; then + echo "$pfx$i$sfx" + fi + ;; + esac done - format="refname:short" - refs="refs/tags refs/heads refs/remotes" + format="refname:strip=2" + refs=("refs/tags/$match*" "refs/tags/$match*/**" + "refs/heads/$match*" "refs/heads/$match*/**" + "refs/remotes/$match*" "refs/remotes/$match*/**") ;; esac - git --git-dir="$dir" for-each-ref --format="%($format)" \ - $refs + __git_dir="$dir" __git for-each-ref --format="$fer_pfx%($format)$sfx" \ + "${refs[@]}" if [ -n "$track" ]; then # employ the heuristic used by git checkout # Try to find a remote branch that matches the completion word # but only output if the branch name is unique - local ref entry - git --git-dir="$dir" for-each-ref --shell --format="ref=%(refname:short)" \ - "refs/remotes/" | \ - while read -r entry; do - eval "$entry" - ref="${ref#*/}" - if [[ "$ref" == "$cur"* ]]; then - echo "$ref" - fi - done | sort | uniq -u + __git for-each-ref --format="$fer_pfx%(refname:strip=3)$sfx" \ + --sort="refname:strip=3" \ + "refs/remotes/*/$match*" "refs/remotes/*/$match*/**" | \ + uniq -u fi return fi - case "$cur" in + case "$cur_" in refs|refs/*) - git ls-remote "$dir" "$cur*" 2>/dev/null | \ + __git ls-remote "$remote" "$match*" | \ while read -r hash i; do case "$i" in *^{}) ;; - *) echo "$i" ;; + *) echo "$pfx$i$sfx" ;; esac done ;; *) - echo "HEAD" - git for-each-ref --format="%(refname:short)" -- \ - "refs/remotes/$dir/" 2>/dev/null | sed -e "s#^$dir/##" + if [ "$list_refs_from" = remote ]; then + case "HEAD" in + $match*) echo "${pfx}HEAD$sfx" ;; + esac + __git for-each-ref --format="$fer_pfx%(refname:strip=3)$sfx" \ + "refs/remotes/$remote/$match*" \ + "refs/remotes/$remote/$match*/**" + else + local query_symref + case "HEAD" in + $match*) query_symref="HEAD" ;; + esac + __git ls-remote "$remote" $query_symref \ + "refs/tags/$match*" "refs/heads/$match*" \ + "refs/remotes/$match*" | + while read -r hash i; do + case "$i" in + *^{}) ;; + refs/*) echo "$pfx${i#refs/*/}$sfx" ;; + *) echo "$pfx$i$sfx" ;; # symbolic refs + esac + done + fi ;; esac } +# Completes refs, short and long, local and remote, symbolic and pseudo. +# +# Usage: __git_complete_refs [