{
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
# 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
}
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).
+# 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).
__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 [ -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
case "$cur" in
refs|refs/*)
format="refname"
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
*^{}) ;;
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
+ echo "HEAD"
+ git --git-dir="$dir" for-each-ref --format="%(refname:short)" \
+ "refs/remotes/$remote/" 2>/dev/null | sed -e "s#^$remote/##"
+ else
+ git --git-dir="$dir" ls-remote "$remote" HEAD \
+ "refs/tags/*" "refs/heads/*" "refs/remotes/*" 2>/dev/null |
+ while read -r hash i; do
+ case "$i" in
+ *^{}) ;;
+ refs/*) echo "${i#refs/*/}" ;;
+ *) echo "$i" ;; # symbolic refs
+ esac
+ done
+ fi
;;
esac
}
__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
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 |
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
__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
{
__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"