]> git.ipfire.org Git - thirdparty/git.git/blobdiff - contrib/completion/git-completion.bash
completion: list refs from remote when remote's name matches a directory
[thirdparty/git.git] / contrib / completion / git-completion.bash
index 21016bf8dfe87572fb53a05488ba05bb3c08ed97..af5ad52bb189273ed77072ba473ed0871992538a 100644 (file)
@@ -40,6 +40,7 @@ __gitdir ()
 {
        if [ -z "${1-}" ]; then
                if [ -n "${__git_dir-}" ]; then
+                       test -d "$__git_dir" || return 1
                        echo "$__git_dir"
                elif [ -n "${GIT_DIR-}" ]; then
                        test -d "${GIT_DIR-}" || return 1
@@ -282,11 +283,13 @@ __gitcomp_file ()
 # argument, and using the options specified in the second argument.
 __git_ls_files_helper ()
 {
+       local dir="$(__gitdir)"
+
        if [ "$2" == "--committable" ]; then
-               git -C "$1" diff-index --name-only --relative HEAD
+               git --git-dir="$dir" -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
+               git --git-dir="$dir" -C "$1" ls-files --exclude-standard $2
        fi 2>/dev/null
 }
 
@@ -332,14 +335,32 @@ __git_tags ()
        fi
 }
 
-# __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).
+# 2: In addition to local refs, list unique branches from refs/remotes/ for
+#    'git checkout's tracking DWIMery (optional; ignored, if set but empty).
 __git_refs ()
 {
-       local i hash dir="$(__gitdir "${1-}")" track="${2-}"
+       local i hash dir="$(__gitdir)" track="${2-}"
+       local list_refs_from=path remote="${1-}"
        local format refs pfx
-       if [ -d "$dir" ]; then
+
+       if [ -n "$remote" ]; then
+               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 ] && [ -d "$dir" ]; then
                case "$cur" in
                refs|refs/*)
                        format="refname"
@@ -376,7 +397,7 @@ __git_refs ()
        fi
        case "$cur" in
        refs|refs/*)
-               git ls-remote "$dir" "$cur*" 2>/dev/null | \
+               git --git-dir="$dir" ls-remote "$remote" "$cur*" 2>/dev/null | \
                while read -r hash i; do
                        case "$i" in
                        *^{}) ;;
@@ -386,8 +407,8 @@ __git_refs ()
                ;;
        *)
                echo "HEAD"
-               git for-each-ref --format="%(refname:short)" -- \
-                       "refs/remotes/$dir/" 2>/dev/null | sed -e "s#^$dir/##"
+               git --git-dir="$dir" for-each-ref --format="%(refname:short)" \
+                       "refs/remotes/$remote/" 2>/dev/null | sed -e "s#^$remote/##"
                ;;
        esac
 }
@@ -405,7 +426,7 @@ __git_refs2 ()
 __git_refs_remotes ()
 {
        local i hash
-       git ls-remote "$1" 'refs/heads/*' 2>/dev/null | \
+       git --git-dir="$(__gitdir)" ls-remote "$1" 'refs/heads/*' 2>/dev/null | \
        while read -r hash i; do
                echo "$i:refs/remotes/$1/${i#refs/heads/}"
        done
@@ -418,6 +439,18 @@ __git_remotes ()
        git --git-dir="$d" remote
 }
 
+# Returns true if $1 matches the name of a configured remote, false otherwise.
+__git_is_configured_remote ()
+{
+       local remote
+       for remote in $(__git_remotes); do
+               if [ "$remote" = "$1" ]; then
+                       return 0
+               fi
+       done
+       return 1
+}
+
 __git_list_merge_strategies ()
 {
        git merge -s help 2>&1 |
@@ -1183,7 +1216,7 @@ _git_commit ()
                return
        esac
 
-       if git rev-parse --verify --quiet HEAD >/dev/null; then
+       if git --git-dir="$(__gitdir)" rev-parse --verify --quiet HEAD >/dev/null; then
                __git_complete_index_file "--committable"
        else
                # This is the first commit
@@ -1206,7 +1239,7 @@ _git_describe ()
 
 __git_diff_algorithms="myers minimal patience histogram"
 
-__git_diff_submodule_formats="log short"
+__git_diff_submodule_formats="diff log short"
 
 __git_diff_common_options="--stat --numstat --shortstat --summary
                        --patch-with-stat --name-only --name-status --color
@@ -1483,7 +1516,7 @@ _git_log ()
 {
        __git_has_doubledash && return
 
-       local g="$(git rev-parse --git-dir 2>/dev/null)"
+       local g="$(__gitdir)"
        local merge=""
        if [ -f "$g/MERGE_HEAD" ]; then
                merge="--merge"
@@ -1552,7 +1585,7 @@ _git_merge ()
        case "$cur" in
        --*)
                __gitcomp "$__git_merge_options
-                       --rerere-autoupdate --no-rerere-autoupdate --abort"
+                       --rerere-autoupdate --no-rerere-autoupdate --abort --continue"
                return
        esac
        __gitcomp_nl "$(__git_refs)"
@@ -1734,10 +1767,10 @@ _git_rebase ()
 {
        local dir="$(__gitdir)"
        if [ -f "$dir"/rebase-merge/interactive ]; then
-               __gitcomp "--continue --skip --abort --edit-todo"
+               __gitcomp "--continue --skip --abort --quit --edit-todo"
                return
        elif [ -d "$dir"/rebase-apply ] || [ -d "$dir"/rebase-merge ]; then
-               __gitcomp "--continue --skip --abort"
+               __gitcomp "--continue --skip --abort --quit"
                return
        fi
        __git_complete_strategy && return