summaryrefslogtreecommitdiff
path: root/contrib
diff options
context:
space:
mode:
Diffstat (limited to 'contrib')
-rw-r--r--contrib/coccinelle/array.cocci17
-rw-r--r--contrib/coccinelle/free.cocci7
-rw-r--r--contrib/completion/.gitattributes1
-rw-r--r--contrib/completion/git-completion.bash609
-rw-r--r--contrib/completion/git-completion.zsh9
-rw-r--r--contrib/completion/git-prompt.sh3
-rwxr-xr-xcontrib/contacts/git-contacts2
-rw-r--r--contrib/diff-highlight/.gitignore2
-rw-r--r--[-rwxr-xr-x]contrib/diff-highlight/DiffHighlight.pm (renamed from contrib/diff-highlight/diff-highlight)40
-rw-r--r--contrib/diff-highlight/Makefile21
-rw-r--r--contrib/diff-highlight/README30
-rw-r--r--contrib/diff-highlight/diff-highlight.perl8
-rwxr-xr-xcontrib/git-resurrect.sh4
-rwxr-xr-xcontrib/hooks/multimail/git_multimail.py2
-rwxr-xr-xcontrib/mw-to-git/git-remote-mediawiki.perl2
-rw-r--r--contrib/mw-to-git/t/README2
-rw-r--r--contrib/persistent-https/README10
-rwxr-xr-xcontrib/rerere-train.sh54
-rw-r--r--contrib/subtree/Makefile26
-rw-r--r--contrib/workdir/.gitattributes1
20 files changed, 661 insertions, 189 deletions
diff --git a/contrib/coccinelle/array.cocci b/contrib/coccinelle/array.cocci
index 4ba98b7eaf..c61d1ca8dc 100644
--- a/contrib/coccinelle/array.cocci
+++ b/contrib/coccinelle/array.cocci
@@ -27,6 +27,23 @@ expression n;
@@
type T;
+T *dst;
+T *src;
+expression n;
+@@
+(
+- memmove(dst, src, (n) * sizeof(*dst));
++ MOVE_ARRAY(dst, src, n);
+|
+- memmove(dst, src, (n) * sizeof(*src));
++ MOVE_ARRAY(dst, src, n);
+|
+- memmove(dst, src, (n) * sizeof(T));
++ MOVE_ARRAY(dst, src, n);
+)
+
+@@
+type T;
T *ptr;
expression n;
@@
diff --git a/contrib/coccinelle/free.cocci b/contrib/coccinelle/free.cocci
index c03ba737e5..4490069df9 100644
--- a/contrib/coccinelle/free.cocci
+++ b/contrib/coccinelle/free.cocci
@@ -9,3 +9,10 @@ expression E;
@@
- if (!E)
free(E);
+
+@@
+expression E;
+@@
+- free(E);
++ FREE_AND_NULL(E);
+- E = NULL;
diff --git a/contrib/completion/.gitattributes b/contrib/completion/.gitattributes
new file mode 100644
index 0000000000..19116944c1
--- /dev/null
+++ b/contrib/completion/.gitattributes
@@ -0,0 +1 @@
+*.bash eol=lf
diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
index 41ee52991d..d934417475 100644
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/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=<path>' and
+# '-C <path>' 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=<path>' and '-C <path>' 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,100 +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 format refs pfx
- if [ -d "$dir" ]; then
- case "$cur" in
+ local i hash dir track="${2-}"
+ local list_refs_from=path remote="${1-}"
+ local format refs
+ 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=""
;;
*)
- [[ "$cur" == ^* ]] && pfx="^"
for i in HEAD FETCH_HEAD ORIG_HEAD MERGE_HEAD; do
- if [ -e "$dir/$i" ]; then echo $pfx$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="$pfx%($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 [<option>]...
+# --remote=<remote>: The remote to list refs from, can be the name of a
+# configured remote, a path, or a URL.
+# --track: List unique remote branches for 'git checkout's tracking DWIMery.
+# --pfx=<prefix>: A prefix to be added to each ref.
+# --cur=<word>: The current ref to be completed. Defaults to the current
+# word to be completed.
+# --sfx=<suffix>: A suffix to be appended to each ref instead of the default
+# space.
+__git_complete_refs ()
+{
+ local remote track pfx cur_="$cur" sfx=" "
+
+ while test $# != 0; do
+ case "$1" in
+ --remote=*) remote="${1##--remote=}" ;;
+ --track) track="yes" ;;
+ --pfx=*) pfx="${1##--pfx=}" ;;
+ --cur=*) cur_="${1##--cur=}" ;;
+ --sfx=*) sfx="${1##--sfx=}" ;;
+ *) return 1 ;;
+ esac
+ shift
+ done
+
+ __gitcomp_direct "$(__git_refs "$remote" "$track" "$pfx" "$cur_" "$sfx")"
+}
+
# __git_refs2 requires 1 argument (to pass to __git_refs)
+# Deprecated: use __git_complete_fetch_refspecs() instead.
__git_refs2 ()
{
local i
@@ -401,11 +546,29 @@ __git_refs2 ()
done
}
+# Completes refspecs for fetching from a remote repository.
+# 1: The remote repository.
+# 2: A prefix to be added to each listed refspec (optional).
+# 3: The ref to be completed as a refspec instead of the current word to be
+# completed (optional)
+# 4: A suffix to be appended to each listed refspec instead of the default
+# space (optional).
+__git_complete_fetch_refspecs ()
+{
+ local i remote="$1" pfx="${2-}" cur_="${3-$cur}" sfx="${4- }"
+
+ __gitcomp_direct "$(
+ for i in $(__git_refs "$remote" "" "" "$cur_") ; do
+ echo "$pfx$i:$i$sfx"
+ done
+ )"
+}
+
# __git_refs_remotes requires 1 argument (to pass to ls-remote)
__git_refs_remotes ()
{
local i hash
- git ls-remote "$1" 'refs/heads/*' 2>/dev/null | \
+ __git ls-remote "$1" 'refs/heads/*' | \
while read -r hash i; do
echo "$i:refs/remotes/$1/${i#refs/heads/}"
done
@@ -413,9 +576,21 @@ __git_refs_remotes ()
__git_remotes ()
{
- local d="$(__gitdir)"
- test -d "$d/remotes" && ls -1 "$d/remotes"
- git --git-dir="$d" remote
+ __git_find_repo_path
+ test -d "$__git_repo_path/remotes" && ls -1 "$__git_repo_path/remotes"
+ __git 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 ()
@@ -469,7 +644,7 @@ __git_complete_revlist_file ()
*) pfx="$ref:$pfx" ;;
esac
- __gitcomp_nl "$(git --git-dir="$(__gitdir)" ls-tree "$ls" 2>/dev/null \
+ __gitcomp_nl "$(__git ls-tree "$ls" \
| sed '/^100... blob /{
s,^.* ,,
s,$, ,
@@ -488,15 +663,15 @@ __git_complete_revlist_file ()
*...*)
pfx="${cur_%...*}..."
cur_="${cur_#*...}"
- __gitcomp_nl "$(__git_refs)" "$pfx" "$cur_"
+ __git_complete_refs --pfx="$pfx" --cur="$cur_"
;;
*..*)
pfx="${cur_%..*}.."
cur_="${cur_#*..}"
- __gitcomp_nl "$(__git_refs)" "$pfx" "$cur_"
+ __git_complete_refs --pfx="$pfx" --cur="$cur_"
;;
*)
- __gitcomp_nl "$(__git_refs)"
+ __git_complete_refs
;;
esac
}
@@ -542,6 +717,7 @@ __git_complete_remote_or_refspec ()
i="${words[c]}"
case "$i" in
--mirror) [ "$cmd" = "push" ] && no_complete_refspec=1 ;;
+ -d|--delete) [ "$cmd" = "push" ] && lhs=0 ;;
--all)
case "$cmd" in
push) no_complete_refspec=1 ;;
@@ -581,23 +757,23 @@ __git_complete_remote_or_refspec ()
case "$cmd" in
fetch)
if [ $lhs = 1 ]; then
- __gitcomp_nl "$(__git_refs2 "$remote")" "$pfx" "$cur_"
+ __git_complete_fetch_refspecs "$remote" "$pfx" "$cur_"
else
- __gitcomp_nl "$(__git_refs)" "$pfx" "$cur_"
+ __git_complete_refs --pfx="$pfx" --cur="$cur_"
fi
;;
pull|remote)
if [ $lhs = 1 ]; then
- __gitcomp_nl "$(__git_refs "$remote")" "$pfx" "$cur_"
+ __git_complete_refs --remote="$remote" --pfx="$pfx" --cur="$cur_"
else
- __gitcomp_nl "$(__git_refs)" "$pfx" "$cur_"
+ __git_complete_refs --pfx="$pfx" --cur="$cur_"
fi
;;
push)
if [ $lhs = 1 ]; then
- __gitcomp_nl "$(__git_refs)" "$pfx" "$cur_"
+ __git_complete_refs --pfx="$pfx" --cur="$cur_"
else
- __gitcomp_nl "$(__git_refs "$remote")" "$pfx" "$cur_"
+ __git_complete_refs --remote="$remote" --pfx="$pfx" --cur="$cur_"
fi
;;
esac
@@ -747,7 +923,7 @@ __git_compute_porcelain_commands ()
__git_get_config_variables ()
{
local section="$1" i IFS=$'\n'
- for i in $(git --git-dir="$(__gitdir)" config --name-only --get-regexp "^$section\..*" 2>/dev/null); do
+ for i in $(__git config --name-only --get-regexp "^$section\..*"); do
echo "${i#$section.}"
done
}
@@ -765,8 +941,7 @@ __git_aliases ()
# __git_aliased_command requires 1 argument
__git_aliased_command ()
{
- local word cmdline=$(git --git-dir="$(__gitdir)" \
- config --get "alias.$1")
+ local word cmdline=$(__git config --get "alias.$1")
for word in $cmdline; do
case "$word" in
\!gitk|gitk)
@@ -842,7 +1017,7 @@ __git_get_option_value ()
done
if [ -n "$config_key" ] && [ -z "$result" ]; then
- result="$(git --git-dir="$(__gitdir)" config "$config_key")"
+ result="$(__git config "$config_key")"
fi
echo "$result"
@@ -901,8 +1076,8 @@ __git_whitespacelist="nowarn warn error error-all fix"
_git_am ()
{
- local dir="$(__gitdir)"
- if [ -d "$dir"/rebase-apply ]; then
+ __git_find_repo_path
+ if [ -d "$__git_repo_path"/rebase-apply ]; then
__gitcomp "--skip --continue --resolved --abort"
return
fi
@@ -990,7 +1165,8 @@ _git_bisect ()
local subcommands="start bad good skip reset visualize replay log run"
local subcommand="$(__git_find_on_cmdline "$subcommands")"
if [ -z "$subcommand" ]; then
- if [ -f "$(__gitdir)"/BISECT_START ]; then
+ __git_find_repo_path
+ if [ -f "$__git_repo_path"/BISECT_START ]; then
__gitcomp "$subcommands"
else
__gitcomp "replay start"
@@ -1000,7 +1176,7 @@ _git_bisect ()
case "$subcommand" in
bad|good|reset|skip|start)
- __gitcomp_nl "$(__git_refs)"
+ __git_complete_refs
;;
*)
;;
@@ -1022,12 +1198,12 @@ _git_branch ()
case "$cur" in
--set-upstream-to=*)
- __gitcomp_nl "$(__git_refs)" "" "${cur##--set-upstream-to=}"
+ __git_complete_refs --cur="${cur##--set-upstream-to=}"
;;
--*)
__gitcomp "
--color --no-color --verbose --abbrev= --no-abbrev
- --track --no-track --contains --merged --no-merged
+ --track --no-track --contains --no-contains --merged --no-merged
--set-upstream-to= --edit-description --list
--unset-upstream --delete --move --remotes
--column --no-column --sort= --points-at
@@ -1035,9 +1211,9 @@ _git_branch ()
;;
*)
if [ $only_local_ref = "y" -a $has_r = "n" ]; then
- __gitcomp_nl "$(__git_heads)"
+ __gitcomp_direct "$(__git_heads "" "$cur" " ")"
else
- __gitcomp_nl "$(__git_refs)"
+ __git_complete_refs
fi
;;
esac
@@ -1080,24 +1256,25 @@ _git_checkout ()
*)
# check if --track, --no-track, or --no-guess was specified
# if so, disable DWIM mode
- local flags="--track --no-track --no-guess" track=1
- if [ -n "$(__git_find_on_cmdline "$flags")" ]; then
- track=''
+ local flags="--track --no-track --no-guess" track_opt="--track"
+ if [ "$GIT_COMPLETION_CHECKOUT_NO_GUESS" = "1" ] ||
+ [ -n "$(__git_find_on_cmdline "$flags")" ]; then
+ track_opt=''
fi
- __gitcomp_nl "$(__git_refs '' $track)"
+ __git_complete_refs $track_opt
;;
esac
}
_git_cherry ()
{
- __gitcomp_nl "$(__git_refs)"
+ __git_complete_refs
}
_git_cherry_pick ()
{
- local dir="$(__gitdir)"
- if [ -f "$dir"/CHERRY_PICK_HEAD ]; then
+ __git_find_repo_path
+ if [ -f "$__git_repo_path"/CHERRY_PICK_HEAD ]; then
__gitcomp "--continue --quit --abort"
return
fi
@@ -1106,7 +1283,7 @@ _git_cherry_pick ()
__gitcomp "--edit --no-commit --signoff --strategy= --mainline"
;;
*)
- __gitcomp_nl "$(__git_refs)"
+ __git_complete_refs
;;
esac
}
@@ -1142,6 +1319,7 @@ _git_clone ()
--template=
--depth
--single-branch
+ --no-tags
--branch
--recurse-submodules
--no-single-branch
@@ -1158,7 +1336,7 @@ _git_commit ()
{
case "$prev" in
-c|-C)
- __gitcomp_nl "$(__git_refs)" "" "${cur}"
+ __git_complete_refs
return
;;
esac
@@ -1171,7 +1349,7 @@ _git_commit ()
;;
--reuse-message=*|--reedit-message=*|\
--fixup=*|--squash=*)
- __gitcomp_nl "$(__git_refs)" "" "${cur#*=}"
+ __git_complete_refs --cur="${cur#*=}"
return
;;
--untracked-files=*)
@@ -1192,7 +1370,7 @@ _git_commit ()
return
esac
- if git rev-parse --verify --quiet HEAD >/dev/null; then
+ if __git rev-parse --verify --quiet HEAD >/dev/null; then
__git_complete_index_file "--committable"
else
# This is the first commit
@@ -1207,10 +1385,11 @@ _git_describe ()
__gitcomp "
--all --tags --contains --abbrev= --candidates=
--exact-match --debug --long --match --always --first-parent
+ --exclude
"
return
esac
- __gitcomp_nl "$(__git_refs)"
+ __git_complete_refs
}
__git_diff_algorithms="myers minimal patience histogram"
@@ -1361,8 +1540,43 @@ _git_gitk ()
_gitk
}
-__git_match_ctag() {
- awk "/^${1//\//\\/}/ { print \$1 }" "$2"
+# Lists matching symbol names from a tag (as in ctags) file.
+# 1: List symbol names matching this word.
+# 2: The tag file to list symbol names from.
+# 3: A prefix to be added to each listed symbol name (optional).
+# 4: A suffix to be appended to each listed symbol name (optional).
+__git_match_ctag () {
+ awk -v pfx="${3-}" -v sfx="${4-}" "
+ /^${1//\//\\/}/ { print pfx \$1 sfx }
+ " "$2"
+}
+
+# Complete symbol names from a tag file.
+# Usage: __git_complete_symbol [<option>]...
+# --tags=<file>: The tag file to list symbol names from instead of the
+# default "tags".
+# --pfx=<prefix>: A prefix to be added to each symbol name.
+# --cur=<word>: The current symbol name to be completed. Defaults to
+# the current word to be completed.
+# --sfx=<suffix>: A suffix to be appended to each symbol name instead
+# of the default space.
+__git_complete_symbol () {
+ local tags=tags pfx="" cur_="${cur-}" sfx=" "
+
+ while test $# != 0; do
+ case "$1" in
+ --tags=*) tags="${1##--tags=}" ;;
+ --pfx=*) pfx="${1##--pfx=}" ;;
+ --cur=*) cur_="${1##--cur=}" ;;
+ --sfx=*) sfx="${1##--sfx=}" ;;
+ *) return 1 ;;
+ esac
+ shift
+ done
+
+ if test -r "$tags"; then
+ __gitcomp_direct "$(__git_match_ctag "$cur_" "$tags" "$pfx" "$sfx")"
+ fi
}
_git_grep ()
@@ -1392,14 +1606,11 @@ _git_grep ()
case "$cword,$prev" in
2,*|*,-*)
- if test -r tags; then
- __gitcomp_nl "$(__git_match_ctag "$cur" tags)"
- return
- fi
+ __git_complete_symbol && return
;;
esac
- __gitcomp_nl "$(__git_refs)"
+ __git_complete_refs
}
_git_help ()
@@ -1500,12 +1711,25 @@ __git_log_date_formats="relative iso8601 rfc2822 short local default raw"
_git_log ()
{
__git_has_doubledash && return
+ __git_find_repo_path
- local g="$(git rev-parse --git-dir 2>/dev/null)"
local merge=""
- if [ -f "$g/MERGE_HEAD" ]; then
+ if [ -f "$__git_repo_path/MERGE_HEAD" ]; then
merge="--merge"
fi
+ case "$prev,$cur" in
+ -L,:*:*)
+ return # fall back to Bash filename completion
+ ;;
+ -L,:*)
+ __git_complete_symbol --cur="${cur#:}" --sfx=":"
+ return
+ ;;
+ -G,*|-S,*)
+ __git_complete_symbol
+ return
+ ;;
+ esac
case "$cur" in
--pretty=*|--format=*)
__gitcomp "$__git_log_pretty_formats $(__git_pretty_aliases)
@@ -1551,6 +1775,21 @@ _git_log ()
"
return
;;
+ -L:*:*)
+ return # fall back to Bash filename completion
+ ;;
+ -L:*)
+ __git_complete_symbol --cur="${cur#-L:}" --sfx=":"
+ return
+ ;;
+ -G*)
+ __git_complete_symbol --pfx="-G" --cur="${cur#-G}"
+ return
+ ;;
+ -S*)
+ __git_complete_symbol --pfx="-S" --cur="${cur#-S}"
+ return
+ ;;
esac
__git_complete_revlist
}
@@ -1573,7 +1812,7 @@ _git_merge ()
--rerere-autoupdate --no-rerere-autoupdate --abort --continue"
return
esac
- __gitcomp_nl "$(__git_refs)"
+ __git_complete_refs
}
_git_mergetool ()
@@ -1598,7 +1837,7 @@ _git_merge_base ()
return
;;
esac
- __gitcomp_nl "$(__git_refs)"
+ __git_complete_refs
}
_git_mv ()
@@ -1636,7 +1875,7 @@ _git_notes ()
,*)
case "$prev" in
--ref)
- __gitcomp_nl "$(__git_refs)"
+ __git_complete_refs
;;
*)
__gitcomp "$subcommands --ref"
@@ -1645,7 +1884,7 @@ _git_notes ()
;;
add,--reuse-message=*|append,--reuse-message=*|\
add,--reedit-message=*|append,--reedit-message=*)
- __gitcomp_nl "$(__git_refs)" "" "${cur#*=}"
+ __git_complete_refs --cur="${cur#*=}"
;;
add,--*|append,--*)
__gitcomp '--file= --message= --reedit-message=
@@ -1664,7 +1903,7 @@ _git_notes ()
-m|-F)
;;
*)
- __gitcomp_nl "$(__git_refs)"
+ __git_complete_refs
;;
esac
;;
@@ -1702,10 +1941,10 @@ __git_complete_force_with_lease ()
--*=)
;;
*:*)
- __gitcomp_nl "$(__git_refs)" "" "${cur_#*:}"
+ __git_complete_refs --cur="${cur_#*:}"
;;
*)
- __gitcomp_nl "$(__git_refs)" "" "$cur_"
+ __git_complete_refs --cur="$cur_"
;;
esac
}
@@ -1750,11 +1989,12 @@ _git_push ()
_git_rebase ()
{
- local dir="$(__gitdir)"
- if [ -f "$dir"/rebase-merge/interactive ]; then
+ __git_find_repo_path
+ if [ -f "$__git_repo_path"/rebase-merge/interactive ]; then
__gitcomp "--continue --skip --abort --quit --edit-todo"
return
- elif [ -d "$dir"/rebase-apply ] || [ -d "$dir"/rebase-merge ]; then
+ elif [ -d "$__git_repo_path"/rebase-apply ] || \
+ [ -d "$__git_repo_path"/rebase-merge ]; then
__gitcomp "--continue --skip --abort --quit"
return
fi
@@ -1780,7 +2020,7 @@ _git_rebase ()
return
esac
- __gitcomp_nl "$(__git_refs)"
+ __git_complete_refs
}
_git_reflog ()
@@ -1791,7 +2031,7 @@ _git_reflog ()
if [ -z "$subcommand" ]; then
__gitcomp "$subcommands"
else
- __gitcomp_nl "$(__git_refs)"
+ __git_complete_refs
fi
}
@@ -1802,9 +2042,7 @@ _git_send_email ()
{
case "$prev" in
--to|--cc|--bcc|--from)
- __gitcomp "
- $(git --git-dir="$(__gitdir)" send-email --dump-aliases 2>/dev/null)
- "
+ __gitcomp "$(__git send-email --dump-aliases)"
return
;;
esac
@@ -1834,9 +2072,7 @@ _git_send_email ()
return
;;
--to=*|--cc=*|--bcc=*|--from=*)
- __gitcomp "
- $(git --git-dir="$(__gitdir)" send-email --dump-aliases 2>/dev/null)
- " "" "${cur#--*=}"
+ __gitcomp "$(__git send-email --dump-aliases)" "" "${cur#--*=}"
return
;;
--*)
@@ -1930,7 +2166,7 @@ __git_config_get_set_variables ()
c=$((--c))
done
- git --git-dir="$(__gitdir)" config $config_file --name-only --list 2>/dev/null
+ __git config $config_file --name-only --list
}
_git_config ()
@@ -1941,7 +2177,7 @@ _git_config ()
return
;;
branch.*.merge)
- __gitcomp_nl "$(__git_refs)"
+ __git_complete_refs
return
;;
branch.*.rebase)
@@ -1965,9 +2201,8 @@ _git_config ()
remote.*.push)
local remote="${prev#remote.}"
remote="${remote%.push}"
- __gitcomp_nl "$(git --git-dir="$(__gitdir)" \
- for-each-ref --format='%(refname):%(refname)' \
- refs/heads)"
+ __gitcomp_nl "$(__git for-each-ref \
+ --format='%(refname):%(refname)' refs/heads)"
return
;;
pull.twohead|pull.octopus)
@@ -2046,7 +2281,7 @@ _git_config ()
;;
branch.*)
local pfx="${cur%.*}." cur_="${cur#*.}"
- __gitcomp_nl "$(__git_heads)" "$pfx" "$cur_" "."
+ __gitcomp_direct "$(__git_heads "$pfx" "$cur_" ".")"
__gitcomp_nl_append $'autosetupmerge\nautosetuprebase\n' "$pfx" "$cur_"
return
;;
@@ -2101,14 +2336,23 @@ _git_config ()
esac
__gitcomp "
add.ignoreErrors
+ advice.amWorkDir
advice.commitBeforeMerge
advice.detachedHead
advice.implicitIdentity
- advice.pushNonFastForward
+ advice.pushAlreadyExists
+ advice.pushFetchFirst
+ advice.pushNeedsForce
+ advice.pushNonFFCurrent
+ advice.pushNonFFMatching
+ advice.pushUpdateRejected
advice.resolveConflict
+ advice.rmHints
advice.statusHints
+ advice.statusUoption
alias.
am.keepcr
+ am.threeWay
apply.ignorewhitespace
apply.whitespace
branch.autosetupmerge
@@ -2153,19 +2397,26 @@ _git_config ()
color.status.added
color.status.changed
color.status.header
+ color.status.localBranch
color.status.nobranch
+ color.status.remoteBranch
color.status.unmerged
color.status.untracked
color.status.updated
color.ui
+ commit.cleanup
+ commit.gpgSign
commit.status
commit.template
+ commit.verbose
core.abbrev
core.askpass
core.attributesfile
core.autocrlf
core.bare
core.bigFileThreshold
+ core.checkStat
+ core.commentChar
core.compression
core.createObject
core.deltaBaseCacheLimit
@@ -2175,6 +2426,8 @@ _git_config ()
core.fileMode
core.fsyncobjectfiles
core.gitProxy
+ core.hideDotFiles
+ core.hooksPath
core.ignoreStat
core.ignorecase
core.logAllRefUpdates
@@ -2182,20 +2435,30 @@ _git_config ()
core.notesRef
core.packedGitLimit
core.packedGitWindowSize
+ core.packedRefsTimeout
core.pager
+ core.precomposeUnicode
core.preferSymlinkRefs
core.preloadindex
+ core.protectHFS
+ core.protectNTFS
core.quotepath
core.repositoryFormatVersion
core.safecrlf
core.sharedRepository
core.sparseCheckout
+ core.splitIndex
+ core.sshCommand
core.symlinks
core.trustctime
core.untrackedCache
core.warnAmbiguousRefs
core.whitespace
core.worktree
+ credential.helper
+ credential.useHttpPath
+ credential.username
+ credentialCache.ignoreSIGHUP
diff.autorefreshindex
diff.external
diff.ignoreSubmodules
@@ -2227,15 +2490,19 @@ _git_config ()
format.thread
format.to
gc.
+ gc.aggressiveDepth
gc.aggressiveWindow
gc.auto
+ gc.autoDetach
gc.autopacklimit
+ gc.logExpiry
gc.packrefs
gc.pruneexpire
gc.reflogexpire
gc.reflogexpireunreachable
gc.rerereresolved
gc.rerereunresolved
+ gc.worktreePruneExpire
gitcvs.allbinary
gitcvs.commitmsgannotation
gitcvs.dbTableNamePrefix
@@ -2374,6 +2641,8 @@ _git_config ()
sendemail.thread
sendemail.to
sendemail.validate
+ sendemail.smtpbatchsize
+ sendemail.smtprelogindelay
showbranch.default
status.relativePaths
status.showUntrackedFiles
@@ -2453,7 +2722,7 @@ _git_replace ()
return
;;
esac
- __gitcomp_nl "$(__git_refs)"
+ __git_complete_refs
}
_git_rerere ()
@@ -2477,13 +2746,13 @@ _git_reset ()
return
;;
esac
- __gitcomp_nl "$(__git_refs)"
+ __git_complete_refs
}
_git_revert ()
{
- local dir="$(__gitdir)"
- if [ -f "$dir"/REVERT_HEAD ]; then
+ __git_find_repo_path
+ if [ -f "$__git_repo_path"/REVERT_HEAD ]; then
__gitcomp "--continue --quit --abort"
return
fi
@@ -2496,7 +2765,7 @@ _git_revert ()
return
;;
esac
- __gitcomp_nl "$(__git_refs)"
+ __git_complete_refs
}
_git_rm ()
@@ -2576,7 +2845,7 @@ _git_show_branch ()
_git_stash ()
{
local save_opts='--all --keep-index --no-keep-index --quiet --patch --include-untracked'
- local subcommands='save list show apply clear drop pop create branch'
+ local subcommands='push save list show apply clear drop pop create branch'
local subcommand="$(__git_find_on_cmdline "$subcommands")"
if [ -z "$subcommand" ]; then
case "$cur" in
@@ -2591,6 +2860,9 @@ _git_stash ()
esac
else
case "$subcommand,$cur" in
+ push,--*)
+ __gitcomp "$save_opts --message"
+ ;;
save,--*)
__gitcomp "$save_opts"
;;
@@ -2604,14 +2876,14 @@ _git_stash ()
;;
branch,*)
if [ $cword -eq 3 ]; then
- __gitcomp_nl "$(__git_refs)";
+ __git_complete_refs
else
- __gitcomp_nl "$(git --git-dir="$(__gitdir)" stash list \
+ __gitcomp_nl "$(__git stash list \
| sed -n -e 's/:.*//p')"
fi
;;
show,*|apply,*|drop,*|pop,*)
- __gitcomp_nl "$(git --git-dir="$(__gitdir)" stash list \
+ __gitcomp_nl "$(__git stash list \
| sed -n -e 's/:.*//p')"
;;
*)
@@ -2771,7 +3043,7 @@ _git_tag ()
i="${words[c]}"
case "$i" in
-d|-v)
- __gitcomp_nl "$(__git_tags)"
+ __gitcomp_direct "$(__git_tags "" "$cur" " ")"
return
;;
-f)
@@ -2786,11 +3058,11 @@ _git_tag ()
;;
-*|tag)
if [ $f = 1 ]; then
- __gitcomp_nl "$(__git_tags)"
+ __gitcomp_direct "$(__git_tags "" "$cur" " ")"
fi
;;
*)
- __gitcomp_nl "$(__git_refs)"
+ __git_complete_refs
;;
esac
@@ -2799,7 +3071,7 @@ _git_tag ()
__gitcomp "
--list --delete --verify --annotate --message --file
--sign --cleanup --local-user --force --column --sort=
- --contains --points-at --merged --no-merged --create-reflog
+ --contains --no-contains --points-at --merged --no-merged --create-reflog
"
;;
esac
@@ -2838,7 +3110,8 @@ _git_worktree ()
__git_main ()
{
- local i c=1 command __git_dir
+ local i c=1 command __git_dir __git_repo_path
+ local __git_C_args C_args_count=0
while [ $c -lt $cword ]; do
i="${words[c]}"
@@ -2848,6 +3121,10 @@ __git_main ()
--bare) __git_dir="." ;;
--help) command="help"; break ;;
-c|--work-tree|--namespace) ((c++)) ;;
+ -C) __git_C_args[C_args_count++]=-C
+ ((c++))
+ __git_C_args[C_args_count++]="${words[c]}"
+ ;;
-*) ;;
*) command="$i"; break ;;
esac
@@ -2855,6 +3132,17 @@ __git_main ()
done
if [ -z "$command" ]; then
+ case "$prev" in
+ --git-dir|-C|--work-tree)
+ # these need a path argument, let's fall back to
+ # Bash filename completion
+ return
+ ;;
+ -c|--namespace)
+ # we don't support completing these options' arguments
+ return
+ ;;
+ esac
case "$cur" in
--*) __gitcomp "
--paginate
@@ -2880,13 +3168,13 @@ __git_main ()
fi
local completion_func="_git_${command//-/_}"
- declare -f $completion_func >/dev/null && $completion_func && return
+ declare -f $completion_func >/dev/null 2>/dev/null && $completion_func && return
local expansion=$(__git_aliased_command "$command")
if [ -n "$expansion" ]; then
words[1]=$expansion
completion_func="_git_${expansion//-/_}"
- declare -f $completion_func >/dev/null && $completion_func
+ declare -f $completion_func >/dev/null 2>/dev/null && $completion_func
fi
}
@@ -2894,9 +3182,11 @@ __gitk_main ()
{
__git_has_doubledash && return
- local g="$(__gitdir)"
+ local __git_repo_path
+ __git_find_repo_path
+
local merge=""
- if [ -f "$g/MERGE_HEAD" ]; then
+ if [ -f "$__git_repo_path/MERGE_HEAD" ]; then
merge="--merge"
fi
case "$cur" in
@@ -2943,6 +3233,15 @@ if [[ -n ${ZSH_VERSION-} ]]; then
esac
}
+ __gitcomp_direct ()
+ {
+ emulate -L zsh
+
+ local IFS=$'\n'
+ compset -P '*[=:]'
+ compadd -Q -- ${=1} && _ret=0
+ }
+
__gitcomp_nl ()
{
emulate -L zsh
diff --git a/contrib/completion/git-completion.zsh b/contrib/completion/git-completion.zsh
index e25541308a..c3521fbfc4 100644
--- a/contrib/completion/git-completion.zsh
+++ b/contrib/completion/git-completion.zsh
@@ -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/contrib/completion/git-prompt.sh b/contrib/completion/git-prompt.sh
index 97eacd7832..c6cbef38c2 100644
--- a/contrib/completion/git-prompt.sh
+++ b/contrib/completion/git-prompt.sh
@@ -82,6 +82,7 @@
# contains relative to newer annotated tag (v1.6.3.2~35)
# branch relative to newer tag or branch (master~4)
# describe relative to older annotated tag (v1.6.3.1-13-gdd42c2f)
+# tag relative to any older tag (v1.6.3.1-13-gdd42c2f)
# default exactly matching tag
#
# If you would like a colored hint about the current dirty state, set
@@ -443,6 +444,8 @@ __git_ps1 ()
git describe --contains HEAD ;;
(branch)
git describe --contains --all HEAD ;;
+ (tag)
+ git describe --tags HEAD ;;
(describe)
git describe HEAD ;;
(* | default)
diff --git a/contrib/contacts/git-contacts b/contrib/contacts/git-contacts
index dbe2abf277..85ad732fc0 100755
--- a/contrib/contacts/git-contacts
+++ b/contrib/contacts/git-contacts
@@ -11,7 +11,7 @@ use IPC::Open2;
my $since = '5-years-ago';
my $min_percent = 10;
-my $labels_rx = qr/Signed-off-by|Reviewed-by|Acked-by|Cc/i;
+my $labels_rx = qr/Signed-off-by|Reviewed-by|Acked-by|Cc|Reported-by/i;
my %seen;
sub format_contact {
diff --git a/contrib/diff-highlight/.gitignore b/contrib/diff-highlight/.gitignore
new file mode 100644
index 0000000000..c07454824e
--- /dev/null
+++ b/contrib/diff-highlight/.gitignore
@@ -0,0 +1,2 @@
+shebang.perl
+diff-highlight
diff --git a/contrib/diff-highlight/diff-highlight b/contrib/diff-highlight/DiffHighlight.pm
index 81bd8040e3..663992e530 100755..100644
--- a/contrib/diff-highlight/diff-highlight
+++ b/contrib/diff-highlight/DiffHighlight.pm
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+package DiffHighlight;
use 5.008;
use warnings FATAL => 'all';
@@ -29,13 +29,14 @@ my @removed;
my @added;
my $in_hunk;
-# Some scripts may not realize that SIGPIPE is being ignored when launching the
-# pager--for instance scripts written in Python.
-$SIG{PIPE} = 'DEFAULT';
+our $line_cb = sub { print @_ };
+our $flush_cb = sub { local $| = 1 };
+
+sub handle_line {
+ local $_ = shift;
-while (<>) {
if (!$in_hunk) {
- print;
+ $line_cb->($_);
$in_hunk = /^$GRAPH*$COLOR*\@\@ /;
}
elsif (/^$GRAPH*$COLOR*-/) {
@@ -49,7 +50,7 @@ while (<>) {
@removed = ();
@added = ();
- print;
+ $line_cb->($_);
$in_hunk = /^$GRAPH*$COLOR*[\@ ]/;
}
@@ -62,15 +63,22 @@ while (<>) {
# place to flush. Flushing on a blank line is a heuristic that
# happens to match git-log output.
if (!length) {
- local $| = 1;
+ $flush_cb->();
}
}
-# Flush any queued hunk (this can happen when there is no trailing context in
-# the final diff of the input).
-show_hunk(\@removed, \@added);
+sub flush {
+ # Flush any queued hunk (this can happen when there is no trailing
+ # context in the final diff of the input).
+ show_hunk(\@removed, \@added);
+}
-exit 0;
+sub highlight_stdin {
+ while (<STDIN>) {
+ handle_line($_);
+ }
+ flush();
+}
# Ideally we would feed the default as a human-readable color to
# git-config as the fallback value. But diff-highlight does
@@ -88,7 +96,7 @@ sub show_hunk {
# If one side is empty, then there is nothing to compare or highlight.
if (!@$a || !@$b) {
- print @$a, @$b;
+ $line_cb->(@$a, @$b);
return;
}
@@ -97,17 +105,17 @@ sub show_hunk {
# stupid, and only handle multi-line hunks that remove and add the same
# number of lines.
if (@$a != @$b) {
- print @$a, @$b;
+ $line_cb->(@$a, @$b);
return;
}
my @queue;
for (my $i = 0; $i < @$a; $i++) {
my ($rm, $add) = highlight_pair($a->[$i], $b->[$i]);
- print $rm;
+ $line_cb->($rm);
push @queue, $add;
}
- print @queue;
+ $line_cb->(@queue);
}
sub highlight_pair {
diff --git a/contrib/diff-highlight/Makefile b/contrib/diff-highlight/Makefile
index 9018724524..fbf5c58249 100644
--- a/contrib/diff-highlight/Makefile
+++ b/contrib/diff-highlight/Makefile
@@ -1,5 +1,20 @@
-# nothing to build
-all:
+all: diff-highlight
-test:
+PERL_PATH = /usr/bin/perl
+-include ../../config.mak
+
+PERL_PATH_SQ = $(subst ','\'',$(PERL_PATH))
+
+diff-highlight: shebang.perl DiffHighlight.pm diff-highlight.perl
+ cat $^ >$@+
+ chmod +x $@+
+ mv $@+ $@
+
+shebang.perl: FORCE
+ @echo '#!$(PERL_PATH_SQ)' >$@+
+ @cmp $@+ $@ >/dev/null 2>/dev/null || mv $@+ $@
+
+test: all
$(MAKE) -C t
+
+.PHONY: FORCE
diff --git a/contrib/diff-highlight/README b/contrib/diff-highlight/README
index 836b97a730..d4c2343175 100644
--- a/contrib/diff-highlight/README
+++ b/contrib/diff-highlight/README
@@ -99,6 +99,36 @@ newHighlight = "black #aaffaa"
---------------------------------------------
+Using diff-highlight as a module
+--------------------------------
+
+If you want to pre- or post- process the highlighted lines as part of
+another perl script, you can use the DiffHighlight module. You can
+either "require" it or just cat the module together with your script (to
+avoid run-time dependencies).
+
+Your script may set up one or more of the following variables:
+
+ - $DiffHighlight::line_cb - this should point to a function which is
+ called whenever DiffHighlight has lines (which may contain
+ highlights) to output. The default function prints each line to
+ stdout. Note that the function may be called with multiple lines.
+
+ - $DiffHighlight::flush_cb - this should point to a function which
+ flushes the output (because DiffHighlight believes it has completed
+ processing a logical chunk of input). The default function flushes
+ stdout.
+
+The script may then feed lines, one at a time, to DiffHighlight::handle_line().
+When lines are done processing, they will be fed to $line_cb. Note that
+DiffHighlight may queue up many input lines (to analyze a whole hunk)
+before calling $line_cb. After providing all lines, call
+DiffHighlight::flush() to flush any unprocessed lines.
+
+If you just want to process stdin, DiffHighlight::highlight_stdin()
+is a convenience helper which will loop and flush for you.
+
+
Bugs
----
diff --git a/contrib/diff-highlight/diff-highlight.perl b/contrib/diff-highlight/diff-highlight.perl
new file mode 100644
index 0000000000..9b3e9c1f4d
--- /dev/null
+++ b/contrib/diff-highlight/diff-highlight.perl
@@ -0,0 +1,8 @@
+package main;
+
+# Some scripts may not realize that SIGPIPE is being ignored when launching the
+# pager--for instance scripts written in Python.
+$SIG{PIPE} = 'DEFAULT';
+
+DiffHighlight::highlight_stdin();
+exit 0;
diff --git a/contrib/git-resurrect.sh b/contrib/git-resurrect.sh
index d7e97bbc76..8c171dd959 100755
--- a/contrib/git-resurrect.sh
+++ b/contrib/git-resurrect.sh
@@ -26,13 +26,13 @@ n,dry-run don't recreate the branch"
. git-sh-setup
search_reflog () {
- sed -ne 's~^\([^ ]*\) .*\tcheckout: moving from '"$1"' .*~\1~p' \
+ sed -ne 's~^\([^ ]*\) .* checkout: moving from '"$1"' .*~\1~p' \
< "$GIT_DIR"/logs/HEAD
}
search_reflog_merges () {
git rev-parse $(
- sed -ne 's~^[^ ]* \([^ ]*\) .*\tmerge '"$1"':.*~\1^2~p' \
+ sed -ne 's~^[^ ]* \([^ ]*\) .* merge '"$1"':.*~\1^2~p' \
< "$GIT_DIR"/logs/HEAD
)
}
diff --git a/contrib/hooks/multimail/git_multimail.py b/contrib/hooks/multimail/git_multimail.py
index c7f86403cf..73fdda6b14 100755
--- a/contrib/hooks/multimail/git_multimail.py
+++ b/contrib/hooks/multimail/git_multimail.py
@@ -2964,7 +2964,7 @@ class StaticRecipientsEnvironmentMixin(Environment):
class CLIRecipientsEnvironmentMixin(Environment):
- """Mixin storing recipients information comming from the
+ """Mixin storing recipients information coming from the
command-line."""
def __init__(self, cli_recipients=None, **kw):
diff --git a/contrib/mw-to-git/git-remote-mediawiki.perl b/contrib/mw-to-git/git-remote-mediawiki.perl
index 41e74fba1e..e7f857c1a2 100755
--- a/contrib/mw-to-git/git-remote-mediawiki.perl
+++ b/contrib/mw-to-git/git-remote-mediawiki.perl
@@ -857,7 +857,7 @@ sub mw_import_revids {
my $n = 0;
my $n_actual = 0;
- my $last_timestamp = 0; # Placeholer in case $rev->timestamp is undefined
+ my $last_timestamp = 0; # Placeholder in case $rev->timestamp is undefined
foreach my $pagerevid (@{$revision_ids}) {
# Count page even if we skip it, since we display
diff --git a/contrib/mw-to-git/t/README b/contrib/mw-to-git/t/README
index 03f6ee5d72..2ee34be7e4 100644
--- a/contrib/mw-to-git/t/README
+++ b/contrib/mw-to-git/t/README
@@ -121,4 +121,4 @@ How to write a new test
Please, follow the standards given by git. See git/t/README.
New file should be named as t936[0-9]-*.sh.
-Be sure to reset your wiki regulary with the function `wiki_reset`.
+Be sure to reset your wiki regularly with the function `wiki_reset`.
diff --git a/contrib/persistent-https/README b/contrib/persistent-https/README
index f784dd2e66..7c4cd8d257 100644
--- a/contrib/persistent-https/README
+++ b/contrib/persistent-https/README
@@ -35,6 +35,16 @@ to use persistent-https:
[url "persistent-http"]
insteadof = http
+You may also want to allow the use of the persistent-https helper for
+submodule URLs (since any https URLs pointing to submodules will be
+rewritten, and Git's out-of-the-box defaults forbid submodules from
+using unknown remote helpers):
+
+[protocol "persistent-https"]
+ allow = always
+[protocol "persistent-http"]
+ allow = always
+
#####################################################################
# BUILDING FROM SOURCE
diff --git a/contrib/rerere-train.sh b/contrib/rerere-train.sh
index 52ad9e41fb..eeee45dd34 100755
--- a/contrib/rerere-train.sh
+++ b/contrib/rerere-train.sh
@@ -3,10 +3,56 @@
# Prime rerere database from existing merge commits
me=rerere-train
-USAGE="$me rev-list-args"
+USAGE=$(cat <<-EOF
+usage: $me [--overwrite] <rev-list-args>
+
+ -h, --help show the help
+ -o, --overwrite overwrite any existing rerere cache
+EOF
+)
SUBDIRECTORY_OK=Yes
-OPTIONS_SPEC=
+
+overwrite=0
+
+while test $# -gt 0
+do
+ opt="$1"
+ case "$opt" in
+ -h|--help)
+ echo "$USAGE"
+ exit 0
+ ;;
+ -o|--overwrite)
+ overwrite=1
+ shift
+ break
+ ;;
+ --)
+ shift
+ break
+ ;;
+ *)
+ break
+ ;;
+ esac
+done
+
+# Overwrite or help options are not valid except as first arg
+for opt in "$@"
+do
+ case "$opt" in
+ -h|--help)
+ echo "$USAGE"
+ exit 0
+ ;;
+ -o|--overwrite)
+ echo "$USAGE"
+ exit 0
+ ;;
+ esac
+done
+
. "$(git --exec-path)/git-sh-setup"
require_work_tree
cd_to_toplevel
@@ -34,6 +80,10 @@ do
# Cleanly merges
continue
fi
+ if test $overwrite = 1
+ then
+ git rerere forget .
+ fi
if test -s "$GIT_DIR/MERGE_RR"
then
git show -s --pretty=format:"Learning from %h %s" "$commit"
diff --git a/contrib/subtree/Makefile b/contrib/subtree/Makefile
index 6afa9aafdf..5c6cc4ab2c 100644
--- a/contrib/subtree/Makefile
+++ b/contrib/subtree/Makefile
@@ -19,15 +19,27 @@ htmldir ?= $(prefix)/share/doc/git-doc
INSTALL ?= install
RM ?= rm -f
-ASCIIDOC = asciidoc
-XMLTO = xmlto
+ASCIIDOC = asciidoc
+ASCIIDOC_CONF = -f ../../Documentation/asciidoc.conf
+ASCIIDOC_HTML = xhtml11
+ASCIIDOC_DOCBOOK = docbook
+ASCIIDOC_EXTRA =
+XMLTO = xmlto
+
+ifdef USE_ASCIIDOCTOR
+ASCIIDOC = asciidoctor
+ASCIIDOC_CONF =
+ASCIIDOC_HTML = xhtml5
+ASCIIDOC_DOCBOOK = docbook45
+ASCIIDOC_EXTRA += -I../../Documentation -rasciidoctor-extensions
+ASCIIDOC_EXTRA += -alitdd='&\#x2d;&\#x2d;'
+endif
ifndef SHELL_PATH
SHELL_PATH = /bin/sh
endif
SHELL_PATH_SQ = $(subst ','\'',$(SHELL_PATH))
-ASCIIDOC_CONF = ../../Documentation/asciidoc.conf
MANPAGE_XSL = ../../Documentation/manpage-normal.xsl
GIT_SUBTREE_SH := git-subtree.sh
@@ -65,12 +77,12 @@ $(GIT_SUBTREE_DOC): $(GIT_SUBTREE_XML)
$(XMLTO) -m $(MANPAGE_XSL) man $^
$(GIT_SUBTREE_XML): $(GIT_SUBTREE_TXT)
- $(ASCIIDOC) -b docbook -d manpage -f $(ASCIIDOC_CONF) \
- -agit_version=$(GIT_VERSION) $^
+ $(ASCIIDOC) -b $(ASCIIDOC_DOCBOOK) -d manpage $(ASCIIDOC_CONF) \
+ -agit_version=$(GIT_VERSION) $(ASCIIDOC_EXTRA) $^
$(GIT_SUBTREE_HTML): $(GIT_SUBTREE_TXT)
- $(ASCIIDOC) -b xhtml11 -d manpage -f $(ASCIIDOC_CONF) \
- -agit_version=$(GIT_VERSION) $^
+ $(ASCIIDOC) -b $(ASCIIDOC_HTML) -d manpage $(ASCIIDOC_CONF) \
+ -agit_version=$(GIT_VERSION) $(ASCIIDOC_EXTRA) $^
$(GIT_SUBTREE_TEST): $(GIT_SUBTREE)
cp $< $@
diff --git a/contrib/workdir/.gitattributes b/contrib/workdir/.gitattributes
new file mode 100644
index 0000000000..1f78c5d1bd
--- /dev/null
+++ b/contrib/workdir/.gitattributes
@@ -0,0 +1 @@
+/git-new-workdir eol=lf