summaryrefslogtreecommitdiff
path: root/Completion/Unix/Command
diff options
context:
space:
mode:
Diffstat (limited to 'Completion/Unix/Command')
-rw-r--r--Completion/Unix/Command/_git60
1 files changed, 60 insertions, 0 deletions
diff --git a/Completion/Unix/Command/_git b/Completion/Unix/Command/_git
index 1dca28802..9e572e25d 100644
--- a/Completion/Unix/Command/_git
+++ b/Completion/Unix/Command/_git
@@ -5640,6 +5640,66 @@ __git_commit_objects_prefer_recent () {
__git_recent_commits $argument_array_names || __git_commit_objects
}
+# This function returns in $reply recently-checked-out refs' names, in order
+# from most to least recent.
+(( $+functions[__git_recent_branches__names] )) ||
+__git_recent_branches__names()
+{
+ local -a reflog
+ local reflog_subject
+ local new_head
+ local -A seen
+ reply=()
+
+ reflog=(${(ps:\0:)"$(_call_program reflog git reflog -1000 -z --grep-reflog='\^checkout:\ moving\ from\ ' --pretty='%gs' 2>/dev/null)"})
+ for reflog_subject in $reflog; do
+ new_head=${${=reflog_subject}[4]}
+
+ # Skip values added in previous iterations.
+ if (( ${+seen[$new_head]} )); then
+ continue
+ fi
+ seen[$new_head]="" # value is ignored
+
+ # Filter out hashes, to leave only ref names.
+ if [[ $new_head =~ '^[0-9a-f]{40}$' ]]; then
+ continue
+ fi
+
+ # All checks passed. Add it.
+ reply+=( $new_head )
+ done
+}
+
+(( $+functions[__git_recent_branches] )) ||
+__git_recent_branches() {
+ local -a branches descriptions
+ local branch description
+ local -a reply
+
+ __git_recent_branches__names \
+ ; for branch in $reply
+ do
+ # ### We'd want to convert all $reply to $descriptions in one shot,
+ # ### with this:
+ # ### array=("${(ps:\0:)"$(_call_program descriptions git --no-pager log --no-walk=unsorted -z --pretty=%s ${(q)reply} --)"}")
+ # ### , but git croaks if any of the positional arguments is a ref name
+ # ### that has been deleted. (So does 'git rev-parse'.)
+ # ### Hence, we resort to fetching the descriptions one-by-one.
+ # ### This would be costly if fork() is expensive.
+ description="$(_call_program description git --no-pager log --no-walk=unsorted --pretty=%s ${(q)branch} --)"
+
+ # If the ref has been deleted, $description would be empty.
+ if [[ -n "$description" ]]; then
+ branches+=$branch
+ descriptions+="${branch//:/\:}:${description}"
+ fi
+ done
+
+ _describe -V -t recent-branches "recent branches" descriptions branches
+}
+
+
(( $+functions[__git_commits] )) ||
__git_commits () {
local -a argument_array_names