mirror of
https://github.com/fish-shell/fish-shell.git
synced 2026-05-30 19:41:15 -03:00
completions/git: extract function for adding arbitrary-revision-completion
Most Git commands take arbitrary revisions. AFAICT, we usually want the same order, e.g. list local branches before remote branches before commit IDs etc. I think there is no particular reason why this order is inconsistent between various subcommands. Let's extract a function. This standardizes the order and adds various revision-types that were missing for some subcommands.
This commit is contained in:
@@ -65,6 +65,10 @@ function __fish_git_local_branches
|
||||
__fish_git for-each-ref --format='%(refname:strip=2)%09Local Branch' --sort=-committerdate refs/heads/ 2>/dev/null
|
||||
end
|
||||
|
||||
function __fish_git_remote_branches
|
||||
__fish_git for-each-ref --format='%(refname:strip=2)%09Remote Branch' refs/remotes/ 2>/dev/null
|
||||
end
|
||||
|
||||
function __fish_git_unique_remote_branches
|
||||
# `git checkout` accepts remote branches without the remote part
|
||||
# if they are unambiguous.
|
||||
@@ -90,6 +94,12 @@ function __fish_git_heads
|
||||
end
|
||||
end
|
||||
|
||||
function __fish_git_remote_heads
|
||||
# Example of output parsed:
|
||||
# "remote.upstream.url git@github.com:fish-shell/fish-shell.git" -> "upstream\tgit@github.com:fish-shell/fish-shell.git"
|
||||
__fish_git for-each-ref --format="%(refname:strip=2)" 'refs/remotes/*/HEAD' | path dirname
|
||||
end
|
||||
|
||||
function __fish_git_refs
|
||||
__fish_git_branches
|
||||
__fish_git_tags
|
||||
@@ -102,6 +112,24 @@ function __fish_git_remotes
|
||||
__fish_git config --get-regexp 'remote\.[a-z]+\.url' | string replace -rf 'remote\.(.*)\.url (.*)' '$1\t$2'
|
||||
end
|
||||
|
||||
set -g __fish_git_recent_commits_arg
|
||||
set -g __fish_git_unqualified_unique_remote_branches false
|
||||
set -g __fish_git_filter_non_pushable ''
|
||||
|
||||
function __fish_git_add_revision_completion
|
||||
set -l c complete -f -c git $argv -n 'not contains -- -- (commandline -xpc)' -ka
|
||||
# The following dynamic, order-preserved (-k) completions will be shown in reverse order (see #9221)
|
||||
$c "(__fish_git_recent_commits $__fish_git_recent_commits_arg $__fish_git_filter_non_pushable)"
|
||||
$c "(__fish_git_tags)" -d Tag
|
||||
$c "(__fish_git_remote_heads $__fish_git_filter_non_pushable)" -d 'Remote alias'
|
||||
$c "(__fish_git_heads $__fish_git_filter_non_pushable)" -d Head
|
||||
$c "(__fish_git_remote_branches $__fish_git_filter_non_pushable)"
|
||||
if $__fish_git_unqualified_unique_remote_branches
|
||||
$c "(__fish_git_unique_remote_branches $__fish_git_filter_non_pushable)" -d 'Unique Remote Branch'
|
||||
end
|
||||
$c "(__fish_git_local_branches)" -d 'Local Branch'
|
||||
end
|
||||
|
||||
function __fish_git_files
|
||||
# A function to show various kinds of files git knows about,
|
||||
# by parsing `git status --porcelain`.
|
||||
@@ -1038,7 +1066,7 @@ complete -f -c git -n '__fish_git_using_command fetch' -l shallow-since -d 'Deep
|
||||
complete -f -c git -n '__fish_git_using_command fetch' -l shallow-exclude -d 'Deepen history of shallow clone, excluding rev'
|
||||
complete -f -c git -n '__fish_git_using_command fetch' -l unshallow -d 'Convert to a complete repository'
|
||||
complete -f -c git -n '__fish_git_using_command fetch' -l refetch -d 'Re-fetch without negotiating common commits'
|
||||
complete -f -c git -n '__fish_git_using_command fetch' -l negotiation-tip -d 'Only report commits reachable from these tips' -kxa '(__fish_git_commits; __fish_git_branches)'
|
||||
__fish_git_add_revision_completion -n '__fish_git_using_command fetch' -l negotiation-tip -d 'Only report commits reachable from these tips' -x
|
||||
complete -f -c git -n '__fish_git_using_command fetch' -l negotiate-only -d "Don't fetch, only show commits in common with the server"
|
||||
complete -f -c git -n '__fish_git_using_command fetch' -l filter -ra '(__fish_git_filters)' -d 'Request a subset of objects from server'
|
||||
|
||||
@@ -1091,11 +1119,9 @@ complete -f -c git -n "__fish_git_using_command remote" -n "__fish_seen_subcomma
|
||||
|
||||
### show
|
||||
complete -f -c git -n __fish_git_needs_command -a show -d 'Show the last commit of a branch'
|
||||
complete -f -c git -n '__fish_git_using_command show' -n 'not contains -- -- (commandline -xpc)' -ka '(__fish_git_branches)'
|
||||
complete -f -c git -n '__fish_git_using_command show' -n 'not contains -- -- (commandline -xpc)' -ka '(__fish_git_tags)' -d Tag
|
||||
complete -f -c git -n '__fish_git_using_command show' -n 'not contains -- -- (commandline -xpc)' -ka '(__fish_git_commits)'
|
||||
complete -f -c git -n '__fish_git_using_command show' -n 'not contains -- -- (commandline -xpc)' -ka '(__fish_git_complete_stashes)'
|
||||
__fish_git_add_revision_completion -n '__fish_git_using_command show'
|
||||
complete -f -c git -n __fish_git_needs_rev_files -n 'not contains -- -- (commandline -xpc)' -xa '(__fish_git_complete_rev_files)'
|
||||
complete -f -c git -n '__fish_git_using_command show' -n 'not contains -- -- (commandline -xpc)' -ka '(__fish_git_complete_stashes)'
|
||||
complete -F -c git -n '__fish_git_using_command show' -n 'contains -- -- (commandline -xpc)'
|
||||
complete -f -c git -n '__fish_git_using_command show' -l format -d 'Pretty-print the contents of the commit logs in a given format' -a '(__fish_git_show_opt format)'
|
||||
complete -f -c git -n '__fish_git_using_command show' -l abbrev-commit -d 'Show only a partial hexadecimal commit object name'
|
||||
@@ -1183,13 +1209,12 @@ complete -c git -n '__fish_git_using_command am' -l show-current-patch -a 'diff
|
||||
### checkout
|
||||
complete -F -c git -n '__fish_git_using_command checkout' -n 'contains -- -- (commandline -xpc)'
|
||||
complete -f -c git -n __fish_git_needs_command -a checkout -d 'Checkout and switch to a branch'
|
||||
begin
|
||||
set -lx __fish_git_recent_commits_arg --all
|
||||
set -lx __fish_git_unqualified_unique_remote_branches true
|
||||
__fish_git_add_revision_completion -n '__fish_git_using_command checkout'
|
||||
end
|
||||
|
||||
# The following dynamic, order-preserved (-k) completions will be shown in reverse order (see #9221)
|
||||
complete -f -c git -n '__fish_git_using_command checkout' -n 'not contains -- -- (commandline -xpc)' -ka '(__fish_git_recent_commits --all)'
|
||||
complete -f -c git -n '__fish_git_using_command checkout' -n 'not contains -- -- (commandline -xpc)' -ka '(__fish_git_tags)' -d Tag
|
||||
complete -f -c git -n '__fish_git_using_command checkout' -n 'not contains -- -- (commandline -xpc)' -ka '(__fish_git_heads)' -d Head
|
||||
complete -f -c git -n '__fish_git_using_command checkout' -n 'not contains -- -- (commandline -xpc)' -ka '(__fish_git_unique_remote_branches)' -d 'Unique Remote Branch'
|
||||
complete -f -c git -n '__fish_git_using_command checkout' -n 'not contains -- -- (commandline -xpc)' -ka '(__fish_git_branches)'
|
||||
# In the presence of changed files, `git checkout ...` assumes highest likelihood is intent to restore so this comes last (aka shown first).
|
||||
complete -f -c git -n '__fish_git_using_command checkout' -ka '(__fish_git_files modified deleted modified-staged-deleted)'
|
||||
|
||||
@@ -1426,9 +1451,7 @@ complete -x -c git -n '__fish_git_using_command daemon' -l access-hook -d 'Hook
|
||||
|
||||
### describe
|
||||
complete -c git -n __fish_git_needs_command -a describe -d 'Give an object a human readable name'
|
||||
complete -f -c git -n '__fish_git_using_command describe' -ka '(__fish_git_tags)' -d Tag
|
||||
complete -f -c git -n '__fish_git_using_command describe' -ka '(__fish_git_branches)'
|
||||
complete -f -c git -n '__fish_git_using_command describe' -ka '(__fish_git_heads)' -d Head
|
||||
__fish_git_add_revision_completion -n '__fish_git_using_command describe'
|
||||
complete -f -c git -n '__fish_git_using_command describe' -l dirty -d 'Describe the state of the working tree, append dirty if there are local changes'
|
||||
complete -f -c git -n '__fish_git_using_command describe' -l broken -d 'Describe the state of the working tree, append -broken instead of erroring'
|
||||
complete -f -c git -n '__fish_git_using_command describe' -l all -d 'Use all tags, not just annotated'
|
||||
@@ -1448,7 +1471,10 @@ complete -f -c git -n '__fish_git_using_command describe' -l first-parent -d 'Fo
|
||||
complete -c git -n __fish_git_needs_command -a diff -d 'Show changes between commits and working tree'
|
||||
complete -c git -n '__fish_git_using_command diff' -n 'not contains -- -- (commandline -xpc)' -ka '(__fish_git_ranges)'
|
||||
complete -c git -n '__fish_git_using_command diff' -n 'not contains -- -- (commandline -xpc)' -ka '(__fish_git_complete_stashes)'
|
||||
complete -c git -n '__fish_git_using_command diff' -n 'not contains -- -- (commandline -xpc)' -ka '(__fish_git_recent_commits --all)'
|
||||
begin
|
||||
set -lx __fish_git_recent_commits_arg --all
|
||||
__fish_git_add_revision_completion -n '__fish_git_using_command diff'
|
||||
end
|
||||
complete -c git -n '__fish_git_using_command diff' -l cached -d 'Show diff of changes in the index'
|
||||
complete -c git -n '__fish_git_using_command diff' -l staged -d 'Show diff of changes in the index'
|
||||
complete -c git -n '__fish_git_using_command diff' -l no-index -d 'Compare two paths on the filesystem'
|
||||
@@ -1779,7 +1805,7 @@ complete -f -c git -n '__fish_git_using_command maintenance' -l schedule -d 'Run
|
||||
|
||||
### merge
|
||||
complete -f -c git -n __fish_git_needs_command -a merge -d 'Join multiple development histories'
|
||||
complete -f -c git -n '__fish_git_using_command merge' -ka '(__fish_git_branches)'
|
||||
__fish_git_add_revision_completion -n '__fish_git_using_command merge'
|
||||
complete -f -c git -n '__fish_git_using_command merge' -l commit -d "Autocommit the merge"
|
||||
complete -f -c git -n '__fish_git_using_command merge' -l no-commit -d "Don't autocommit the merge"
|
||||
complete -f -c git -n '__fish_git_using_command merge' -s e -l edit -d 'Edit auto-generated merge message'
|
||||
@@ -1815,7 +1841,7 @@ complete -f -c git -n '__fish_git_using_command merge' -l no-autostash -d 'Do no
|
||||
|
||||
### merge-base
|
||||
complete -f -c git -n __fish_git_needs_command -a merge-base -d 'Find a common ancestor for a merge'
|
||||
complete -f -c git -n '__fish_git_using_command merge-base' -ka '(__fish_git_branches)'
|
||||
__fish_git_add_revision_completion -n '__fish_git_using_command merge-base'
|
||||
complete -f -c git -n '__fish_git_using_command merge-base' -s a -l all -d 'Output all merge bases for the commits, instead of just one'
|
||||
complete -f -c git -n '__fish_git_using_command merge-base' -l octopus -d 'Compute the best common ancestors of all supplied commits'
|
||||
complete -f -c git -n '__fish_git_using_command merge-base' -l independent -d 'Print a minimal subset of the supplied commits with the same ancestors'
|
||||
@@ -1933,9 +1959,10 @@ complete -f -c git -n '__fish_git_using_command range-diff' -l no-dual-color -d
|
||||
### push
|
||||
complete -f -c git -n __fish_git_needs_command -a push -d 'Push changes elsewhere'
|
||||
complete -f -c git -n '__fish_git_using_command push' -n 'not __fish_git_branch_for_remote' -a '(__fish_git_remotes)' -d 'Remote alias'
|
||||
complete -f -c git -n '__fish_git_using_command push' -n __fish_git_branch_for_remote -ka '(__fish_git_tags)' -d Tag
|
||||
complete -f -c git -n '__fish_git_using_command push' -n __fish_git_branch_for_remote -ka '(__fish_git_branches)'
|
||||
complete -f -c git -n '__fish_git_using_command push' -n __fish_git_branch_for_remote -ka '(__fish_git_heads)'
|
||||
begin
|
||||
set -lx __fish_git_filter_non_pushable '| string replace -r "(\t.*)?\$" ":\$1"'
|
||||
__fish_git_add_revision_completion -n '__fish_git_using_command push' -n __fish_git_branch_for_remote
|
||||
end
|
||||
# The "refspec" here is an optional "+" to signify a force-push
|
||||
complete -f -c git -n '__fish_git_using_command push' -n __fish_git_branch_for_remote -n 'string match -q "+*" -- (commandline -ct)' -ka '+(__fish_git_branches | string replace -r \t".*" "")' -d 'Force-push branch'
|
||||
# git push REMOTE :BRANCH deletes BRANCH on remote REMOTE
|
||||
@@ -1962,11 +1989,7 @@ complete -f -c git -n '__fish_git_using_command push' -l progress -d 'Force prog
|
||||
|
||||
### rebase
|
||||
complete -f -c git -n __fish_git_needs_command -a rebase -d 'Reapply commit sequence on a new base'
|
||||
complete -f -c git -n '__fish_git_using_command rebase' -a '(__fish_git_remotes)' -d 'Remote alias'
|
||||
complete -f -c git -n '__fish_git_using_command rebase' -ka '(__fish_git_branches)'
|
||||
complete -f -c git -n '__fish_git_using_command rebase' -a '(__fish_git_heads)' -d Head
|
||||
complete -f -c git -n '__fish_git_using_command rebase' -ka '(__fish_git_tags)' -d Tag -k
|
||||
complete -f -c git -n '__fish_git_using_command rebase' -a '(__fish_git_recent_commits)' -k
|
||||
__fish_git_add_revision_completion -n '__fish_git_using_command rebase'
|
||||
complete -f -c git -n '__fish_git_using_command rebase' -n __fish_git_is_rebasing -l continue -d 'Restart the rebasing process'
|
||||
complete -f -c git -n '__fish_git_using_command rebase' -n __fish_git_is_rebasing -l abort -d 'Abort the rebase operation'
|
||||
complete -f -c git -n '__fish_git_using_command rebase' -n __fish_git_is_rebasing -l edit-todo -d 'Edit the todo list'
|
||||
@@ -1991,7 +2014,7 @@ complete -f -c git -n '__fish_git_using_command rebase' -l no-autosquash -d 'No
|
||||
complete -f -c git -n '__fish_git_using_command rebase' -l autostash -d 'Before starting rebase, stash local changes, and apply stash when done'
|
||||
complete -f -c git -n '__fish_git_using_command rebase' -l no-autostash -d 'Do not stash local changes before starting rebase'
|
||||
complete -f -c git -n '__fish_git_using_command rebase' -l no-ff -d 'No fast-forward'
|
||||
complete -f -c git -n '__fish_git_using_command rebase' -l onto -d 'Rebase current branch onto given upstream or newbase' -rka '(__fish_git_branches)'
|
||||
__fish_git_add_revision_completion -n '__fish_git_using_command rebase' -l onto -d 'Rebase current branch onto given upstream or newbase' -r
|
||||
complete -f -c git -n '__fish_git_using_command rebase' -l update-refs -d 'Update any branches that point to commits being rebased'
|
||||
complete -f -c git -n '__fish_git_using_command rebase' -l no-update-refs -d 'Don\'t update any branches that point to commits being rebased'
|
||||
# This actually takes script for $SHELL, but completing that is... complicated.
|
||||
@@ -2010,7 +2033,7 @@ complete -c git -n __fish_git_needs_command -a reset -d 'Reset current HEAD to t
|
||||
complete -f -c git -n '__fish_git_using_command reset' -l hard -d 'Reset the index and the working tree'
|
||||
complete -f -c git -n '__fish_git_using_command reset' -l soft -d 'Reset head without touching the index or the working tree'
|
||||
complete -f -c git -n '__fish_git_using_command reset' -l mixed -d 'The default: reset the index but not the working tree'
|
||||
complete -c git -n '__fish_git_using_command reset' -n 'not contains -- -- (commandline -xpc)' -ka '(__fish_git_branches)'
|
||||
__fish_git_add_revision_completion -n '__fish_git_using_command reset'
|
||||
# reset can either undo changes to versioned modified files,
|
||||
# or remove files from the staging area.
|
||||
# Deleted files seem to need a "--" separator.
|
||||
@@ -2042,7 +2065,10 @@ complete -f -c git -n '__fish_git_using_command switch' -ka '(__fish_git_unique_
|
||||
complete -f -c git -n '__fish_git_using_command switch' -ka '(__fish_git_branches)'
|
||||
complete -f -c git -n '__fish_git_using_command switch' -s c -l create -d 'Create a new branch'
|
||||
complete -f -c git -n '__fish_git_using_command switch' -s C -l force-create -d 'Force create a new branch'
|
||||
complete -f -c git -n '__fish_git_using_command switch' -s d -l detach -rka '(__fish_git_recent_commits --all)'
|
||||
begin
|
||||
set -lx __fish_git_recent_commits_arg --all
|
||||
__fish_git_add_revision_completion -n '__fish_git_using_command switch' -s d -l detach -r
|
||||
end
|
||||
complete -f -c git -n '__fish_git_using_command switch' -s d -l detach -d 'Switch to a commit for inspection and discardable experiment' -rka '(__fish_git_refs)'
|
||||
complete -f -c git -n '__fish_git_using_command switch' -l guess -d 'Guess branch name from remote branch (default)'
|
||||
complete -f -c git -n '__fish_git_using_command switch' -l no-guess -d 'Do not guess branch name from remote branch'
|
||||
@@ -2067,9 +2093,7 @@ complete -f -c git -n __fish_git_needs_command -a rev-list -d 'List commits in c
|
||||
|
||||
### rev-parse
|
||||
complete -f -c git -n __fish_git_needs_command -a rev-parse -d 'Parse revision names or give repo information'
|
||||
complete -f -c git -n '__fish_git_using_command rev-parse' -ka '(__fish_git_branches)'
|
||||
complete -f -c git -n '__fish_git_using_command rev-parse' -a '(__fish_git_heads)' -d Head
|
||||
complete -c git -n '__fish_git_using_command rev-parse' -ka '(__fish_git_tags)' -d Tag
|
||||
__fish_git_add_revision_completion -n '__fish_git_using_command rev-parse'
|
||||
complete -c git -n '__fish_git_using_command rev-parse' -l abbrev-ref -d 'Output non-ambiguous short object names'
|
||||
|
||||
### revert
|
||||
@@ -2119,7 +2143,7 @@ complete -f -c git -n '__fish_git_using_command stripspace' -s c -l comment-line
|
||||
|
||||
### tag
|
||||
complete -f -c git -n __fish_git_needs_command -a tag -d 'Create, list, delete or verify a tag object signed with GPG'
|
||||
complete -f -c git -n '__fish_git_using_command tag' -n '__fish_not_contain_opt -s d' -n '__fish_not_contain_opt -s v' -n 'test (count (commandline -xpc | string match -r -v \'^-\')) -eq 3' -ka '(__fish_git_branches)'
|
||||
__fish_git_add_revision_completion -n '__fish_git_using_command tag' -n '__fish_not_contain_opt -s d' -n '__fish_not_contain_opt -s v' -n 'test (count (commandline -xpc | string match -r -v \'^-\')) -eq 3'
|
||||
complete -f -c git -n '__fish_git_using_command tag' -s a -l annotate -d 'Make an unsigned, annotated tag object'
|
||||
complete -f -c git -n '__fish_git_using_command tag' -s s -l sign -d 'Make a GPG-signed tag'
|
||||
complete -f -c git -n '__fish_git_using_command tag' -s d -l delete -d 'Remove a tag'
|
||||
@@ -2180,11 +2204,10 @@ complete -f -c git -n "__fish_git_using_command worktree" -n "not __fish_seen_su
|
||||
complete -f -c git -n '__fish_git_using_command worktree' -n '__fish_seen_subcommand_from add move remove' -s f -l force -d 'Override safeguards'
|
||||
|
||||
complete -c git -n '__fish_git_using_command worktree' -n '__fish_seen_subcommand_from add'
|
||||
complete -c git -n '__fish_git_using_command worktree' -n '__fish_seen_subcommand_from add' -ka '(__fish_git_branches)'
|
||||
complete -c git -n '__fish_git_using_command worktree' -n '__fish_seen_subcommand_from add' -ka '(__fish_git_heads)' -d Head
|
||||
complete -c git -n '__fish_git_using_command worktree' -n '__fish_seen_subcommand_from add' -ka '(__fish_git_tags)' -d Tag
|
||||
complete -c git -n '__fish_git_using_command worktree' -n '__fish_seen_subcommand_from add' -ka '(__fish_git_unique_remote_branches)' -d 'Unique Remote Branch'
|
||||
complete -c git -n '__fish_git_using_command worktree' -n '__fish_seen_subcommand_from add' -ka '(__fish_git_local_branches)'
|
||||
begin
|
||||
set -lx __fish_git_unqualified_unique_remote_branches true
|
||||
__fish_git_add_revision_completion -n '__fish_git_using_command worktree' -n '__fish_seen_subcommand_from add'
|
||||
end
|
||||
complete -x -c git -n '__fish_git_using_command worktree' -n '__fish_seen_subcommand_from add' -s b -d 'Create a new branch'
|
||||
complete -x -c git -n '__fish_git_using_command worktree' -n '__fish_seen_subcommand_from add' -s B -d 'Create a new branch even if it already exists'
|
||||
complete -f -c git -n '__fish_git_using_command worktree' -n '__fish_seen_subcommand_from add' -l detach -d 'Detach HEAD in the new working tree'
|
||||
@@ -2241,7 +2264,7 @@ complete -f -c git -n __fish_git_needs_command -a config -d 'Set and read git co
|
||||
|
||||
### format-patch
|
||||
complete -f -c git -n __fish_git_needs_command -a format-patch -d 'Generate patch series to send upstream'
|
||||
complete -f -c git -n '__fish_git_using_command format-patch' -ka '(__fish_git_branches)'
|
||||
__fish_git_add_revision_completion -n '__fish_git_using_command format-patch'
|
||||
complete -c git -n '__fish_git_using_command format-patch' -s o -l output-directory -xa '(__fish_complete_directories)'
|
||||
complete -f -c git -n '__fish_git_using_command format-patch' -s p -l no-stat -d "Generate plain patches without diffstat"
|
||||
complete -f -c git -n '__fish_git_using_command format-patch' -s s -l no-patch -d "Suppress diff output"
|
||||
@@ -2603,3 +2626,8 @@ for file in (path filter -xZ $PATH/git-* | path basename)
|
||||
complete -c git -f -n "__fish_git_using_command $cmd" -a "(__fish_git_complete_custom_command $cmd)"
|
||||
set -a __fish_git_custom_commands_completion $file
|
||||
end
|
||||
|
||||
functions --erase __fish_git_add_revision_completion
|
||||
set -eg __fish_git_recent_commits_arg
|
||||
set -eg __fish_git_unqualified_unique_remote_branches
|
||||
set -eg __fish_git_filter_non_pushable
|
||||
|
||||
Reference in New Issue
Block a user