diff --git a/share/completions/git.fish b/share/completions/git.fish index 36c83b522..79f00cca8 100644 --- a/share/completions/git.fish +++ b/share/completions/git.fish @@ -18,19 +18,14 @@ function __fish_git_recent_commits | string replace -r '(.{73}).+' '$1…' end -function __fish_git_local_branches - command git branch --no-color | string trim -c ' *' -end - -function __fish_git_remote_branches - command git branch --no-color --remote | string trim -c ' *' -end - function __fish_git_branches - # In some cases, git can end up on no branch - e.g. with a detached head - # This will result in output like `* (no branch)` or a localized `* (HEAD detached at SHA)` - # The first `string match -v` filters it out because it's not useful as a branch argument - command git branch --no-color -a $argv ^/dev/null | string match -v '\* (*)' | string match -r -v ' -> ' | string trim -c "* " | string replace -r "^remotes/" "" + command git branch --no-color -a --format='%(refname)' $argv ^/dev/null \ + # Filter out anything that's not in "refs/" notation - + # this happens mostly with a detached head ("(HEAD detached at SOMESHA)", localized). + | string replace -rf '^refs/' '' \ + # We assume anything that's not remote is a local branch. + | string replace -r '^(?!remotes/)[^/]+/(.*)' '$1\tLocal Branch' \ + | string replace -r "^remotes/(.*)" '$1\tRemote Branch' end function __fish_git_unique_remote_branches @@ -184,7 +179,8 @@ function __fish_git_ranges end set -l to (set -q both[2]; and echo $both[2]) - for from_ref in (__fish_git_refs | string match "$from") + # Remove description from the from-ref, not the to-ref. + for from_ref in (__fish_git_refs | string match "$from" | string replace -r \t'.*$' '') for to_ref in (__fish_git_refs | string match "*$to*") # if $to is empty, this correctly matches everything printf "%s..%s\n" $from_ref $to_ref end @@ -383,7 +379,7 @@ complete -f -c git -n '__fish_git_using_command log show diff-tree rev-list' -l complete -f -c git -n '__fish_git_needs_command' -a fetch -d 'Download objects and refs from another repository' # Suggest "repository", then "refspec" - this also applies to e.g. push/pull complete -f -c git -n '__fish_git_using_command fetch; and not __fish_git_branch_for_remote' -a '(__fish_git_remotes)' -d 'Remote' -complete -f -c git -n '__fish_git_using_command fetch; and __fish_git_branch_for_remote' -a '(__fish_git_branch_for_remote)' -d 'Branch' +complete -f -c git -n '__fish_git_using_command fetch; and __fish_git_branch_for_remote' -a '(__fish_git_branch_for_remote)' complete -f -c git -n '__fish_git_using_command fetch' -s q -l quiet -d 'Be quiet' complete -f -c git -n '__fish_git_using_command fetch' -s v -l verbose -d 'Be verbose' complete -f -c git -n '__fish_git_using_command fetch' -s a -l append -d 'Append ref names and object names' @@ -433,7 +429,7 @@ complete -f -c git -n "__fish_git_using_command remote; and __fish_seen_subcomma ### show complete -f -c git -n '__fish_git_needs_command' -a show -d 'Shows the last commit of a branch' -complete -f -c git -n '__fish_git_using_command show' -a '(__fish_git_branches)' -d 'Branch' +complete -f -c git -n '__fish_git_using_command show' -a '(__fish_git_branches)' complete -f -c git -n '__fish_git_using_command show' -a '(__fish_git_unique_remote_branches)' -d 'Remote branch' complete -f -c git -n '__fish_git_using_command show' -a '(__fish_git_tags)' -d 'Tag' complete -f -c git -n '__fish_git_using_command show' -a '(__fish_git_commits)' @@ -466,8 +462,7 @@ complete -f -c git -n '__fish_git_using_command add' -a '(__fish_git_files modif ### checkout complete -f -c git -n '__fish_git_needs_command' -a checkout -d 'Checkout and switch to a branch' -complete -k -f -c git -n '__fish_git_using_command checkout' -a '(__fish_git_local_branches)' -d 'Local Branch' -complete -k -f -c git -n '__fish_git_using_command checkout' -a '(__fish_git_remote_branches)' -d 'Remote Branch' +complete -k -f -c git -n '__fish_git_using_command checkout' -a '(__fish_git_branches)' complete -k -f -c git -n '__fish_git_using_command checkout' -a '(__fish_git_heads)' -d 'Head' complete -k -f -c git -n '__fish_git_using_command checkout' -a '(__fish_git_unique_remote_branches)' -d 'Remote branch' complete -k -f -c git -n '__fish_git_using_command checkout' -a '(__fish_git_tags)' -d 'Tag' @@ -492,7 +487,7 @@ complete -f -c git -n '__fish_git_needs_command' -a bisect -d 'Find the change t ### branch complete -f -c git -n '__fish_git_needs_command' -a branch -d 'List, create, or delete branches' -complete -f -c git -n '__fish_git_using_command branch' -a '(__fish_git_branches)' -d 'Branch' +complete -f -c git -n '__fish_git_using_command branch' -a '(__fish_git_branches)' complete -f -c git -n '__fish_git_using_command branch' -s d -d 'Delete branch' complete -f -c git -n '__fish_git_using_command branch' -s D -d 'Force deletion of branch' complete -f -c git -n '__fish_git_using_command branch' -s m -d 'Rename branch' @@ -506,7 +501,7 @@ complete -f -c git -n '__fish_git_using_command branch' -l no-merged -d 'List br ### cherry-pick complete -f -c git -n '__fish_git_needs_command' -a cherry-pick -d 'Apply the change introduced by an existing commit' -complete -f -c git -n '__fish_git_using_command cherry-pick' -a '(__fish_git_branches --no-merged)' -d 'Branch' +complete -f -c git -n '__fish_git_using_command cherry-pick' -a '(__fish_git_branches --no-merged)' complete -f -c git -n '__fish_git_using_command cherry-pick' -a '(__fish_git_unique_remote_branches --no-merged)' -d 'Remote branch' # TODO: Filter further complete -f -c git -n '__fish_git_using_command cherry-pick; and __fish_git_possible_commithash' -a '(__fish_git_commits)' @@ -539,7 +534,7 @@ complete -f -c git -n '__fish_git_using_command commit; and __fish_contains_opt ### diff complete -c git -n '__fish_git_needs_command' -a diff -d 'Show changes between commits, commit and working tree, etc' -complete -c git -n '__fish_git_using_command diff' -a '(__fish_git_ranges)' -d 'Branch' +complete -c git -n '__fish_git_using_command diff' -a '(__fish_git_ranges)' 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 no-index -d 'Compare two paths on the filesystem' complete -f -c git -n '__fish_git_using_command diff' -a '(__fish_git_files modified deleted)' @@ -547,7 +542,7 @@ complete -f -c git -n '__fish_git_using_command diff' -a '(__fish_git_files modi ### difftool complete -c git -n '__fish_git_needs_command' -a difftool -d 'Open diffs in a visual tool' -complete -c git -n '__fish_git_using_command difftool' -a '(__fish_git_ranges)' -d 'Branch' +complete -c git -n '__fish_git_using_command difftool' -a '(__fish_git_ranges)' complete -c git -n '__fish_git_using_command difftool' -l cached -d 'Visually show diff of changes in the index' complete -f -c git -n '__fish_git_using_command difftool' -a '(__fish_git_files modified deleted)' # TODO options @@ -564,7 +559,7 @@ complete -f -c git -n '__fish_git_needs_command' -a init -d 'Create an empty git ### log complete -c git -n '__fish_git_needs_command' -a shortlog -d 'Show commit shortlog' complete -c git -n '__fish_git_needs_command' -a log -d 'Show commit logs' -complete -c git -n '__fish_git_using_command log' -a '(__fish_git_refs) (__fish_git_ranges)' -d 'Branch' +complete -c git -n '__fish_git_using_command log' -a '(__fish_git_refs) (__fish_git_ranges)' complete -c git -n '__fish_git_using_command log' -l follow -d 'Continue listing file history beyond renames' complete -c git -n '__fish_git_using_command log' -l no-decorate -d 'Don\'t print ref names' @@ -765,7 +760,7 @@ complete -c git -n '__fish_git_using_command log' -l ita-invisible-in-index ### merge complete -f -c git -n '__fish_git_needs_command' -a merge -d 'Join two or more development histories together' -complete -f -c git -n '__fish_git_using_command merge' -a '(__fish_git_branches)' -d 'Branch' +complete -f -c git -n '__fish_git_using_command merge' -a '(__fish_git_branches)' complete -f -c git -n '__fish_git_using_command merge' -a '(__fish_git_unique_remote_branches)' -d 'Remote branch' 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" @@ -826,13 +821,13 @@ complete -f -c git -n '__fish_git_using_command pull' -l no-tags -d 'Disable aut # TODO --upload-pack complete -f -c git -n '__fish_git_using_command pull' -l progress -d 'Force progress status' complete -f -c git -n '__fish_git_using_command pull; and not __fish_git_branch_for_remote' -a '(__fish_git_remotes)' -d 'Remote alias' -complete -f -c git -n '__fish_git_using_command pull; and __fish_git_branch_for_remote' -a '(__fish_git_branch_for_remote)' -d 'Branch' +complete -f -c git -n '__fish_git_using_command pull; and __fish_git_branch_for_remote' -a '(__fish_git_branch_for_remote)' # TODO other options ### push complete -f -c git -n '__fish_git_needs_command' -a push -d 'Update remote refs along with associated objects' complete -f -c git -n '__fish_git_using_command push; and not __fish_git_branch_for_remote' -a '(__fish_git_remotes)' -d 'Remote alias' -complete -f -c git -n '__fish_git_using_command push; and __fish_git_branch_for_remote' -a '(__fish_git_branches)' -d 'Branch' +complete -f -c git -n '__fish_git_using_command push; and __fish_git_branch_for_remote' -a '(__fish_git_branches)' # The "refspec" here is an optional "+" to signify a force-push complete -f -c git -n '__fish_git_using_command push; and __fish_git_branch_for_remote; and string match -q "+*" -- (commandline -ct)' -a '+(__fish_git_branches)' -d 'Force-push branch' # git push REMOTE :BRANCH deletes BRANCH on remote REMOTE @@ -859,7 +854,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 'Forward-port local commits to the updated upstream head' 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' -a '(__fish_git_branches)' -d 'Branch' +complete -f -c git -n '__fish_git_using_command rebase' -a '(__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' -a '(__fish_git_tags)' -d 'Tag' complete -f -c git -n '__fish_git_using_command rebase' -l continue -d 'Restart the rebasing process' @@ -884,7 +879,7 @@ complete -f -c git -n '__fish_git_using_command rebase' -l no-ff -d 'No fast-for ### reset complete -c git -n '__fish_git_needs_command' -a reset -d 'Reset current HEAD to the specified state' complete -f -c git -n '__fish_git_using_command reset' -l hard -d 'Reset files in working directory' -complete -c git -n '__fish_git_using_command reset' -a '(__fish_git_branches)' -d 'Branch' +complete -c git -n '__fish_git_using_command reset' -a '(__fish_git_branches)' # reset can either undo changes to versioned modified files, # or remove files from the staging area. # TODO: Deleted files seem to need a "--" separator. @@ -920,7 +915,7 @@ complete -f -c git -n '__fish_git_using_command status' -l ignore-submodules -x ### 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; and __fish_not_contain_opt -s d; and __fish_not_contain_opt -s v; and test (count (commandline -opc | string match -r -v \'^-\')) -eq 3' -a '(__fish_git_branches)' -d 'Branch' +complete -f -c git -n '__fish_git_using_command tag; and __fish_not_contain_opt -s d; and __fish_not_contain_opt -s v; and test (count (commandline -opc | string match -r -v \'^-\')) -eq 3' -a '(__fish_git_branches)' 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' @@ -956,7 +951,7 @@ complete -f -c git -n '__fish_git_needs_command' -a config -d 'Set and read git ### 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' -a '(__fish_git_branches)' -d 'Branch' +complete -f -c git -n '__fish_git_using_command format-patch' -a '(__fish_git_branches)' 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" complete -f -c git -n '__fish_git_using_command format-patch' -l minimal -d "Spend more time to create smaller diffs"