commit c989c1f59ea00a2fe719e37eb782a4eb95c430e9 (tree)
parent 6b18f7b75801fddb8057f5e1311c96b735467f0a
Author: Tim Pope <code@tpope.net>
Date: Mon, 20 Jan 2020 08:25:58 -0500
Replace :Grebase/:Gmerge/:Gpull with standard job runner
Diffstat:
2 files changed, 49 insertions(+), 274 deletions(-)
diff --git a/autoload/fugitive.vim b/autoload/fugitive.vim
@@ -257,6 +257,25 @@ function! s:QuickfixStream(nr, event, title, cmd, first, callback, ...) abort
endif
endfunction
+let s:common_efm = ''
+ \ . '%+Egit:%.%#,'
+ \ . '%+Eusage:%.%#,'
+ \ . '%+Eerror:%.%#,'
+ \ . '%+Efatal:%.%#,'
+ \ . '%-G%.%#%\e[K%.%#,'
+ \ . '%-G%.%#%\r%.%\+'
+
+function! fugitive#Cwindow() abort
+ if &buftype == 'quickfix'
+ cwindow
+ else
+ botright cwindow
+ if &buftype == 'quickfix'
+ wincmd p
+ endif
+ endif
+endfunction
+
" Section: Git
function! s:UserCommandList(...) abort
@@ -1630,6 +1649,20 @@ function! s:AddSection(label, lines, ...) abort
call append(line('$'), ['', a:label . (len(note) ? ': ' . note : ' (' . len(a:lines) . ')')] + s:Format(a:lines))
endfunction
+let s:rebase_abbrevs = {
+ \ 'p': 'pick',
+ \ 'r': 'reword',
+ \ 'e': 'edit',
+ \ 's': 'squash',
+ \ 'f': 'fixup',
+ \ 'x': 'exec',
+ \ 'd': 'drop',
+ \ 'l': 'label',
+ \ 't': 'reset',
+ \ 'm': 'merge',
+ \ 'b': 'break',
+ \ }
+
function! fugitive#BufReadStatus() abort
let amatch = s:Slash(expand('%:p'))
let b:fugitive_type = 'index'
@@ -3701,10 +3734,6 @@ function! s:FinishCommit() abort
let args = getbufvar(buf, 'fugitive_commit_arguments')
if !empty(args)
call setbufvar(buf, 'fugitive_commit_arguments', [])
- if getbufvar(buf, 'fugitive_commit_rebase')
- call setbufvar(buf, 'fugitive_commit_rebase', 0)
- let s:rebase_continue = [s:Dir(buf), 0]
- endif
return s:CommitSubcommand(-1, -1, 0, 0, '', args, s:Dir(buf))
endif
return ''
@@ -3724,227 +3753,6 @@ function! fugitive#PullComplete(A, L, P) abort
return s:CompleteSub('pull', a:A, a:L, a:P, function('s:CompleteRemote'))
endfunction
-function! s:RebaseSequenceAborter() abort
- return s:TempScript('echo exec false | cat - "$1" > "$1.fugitive"', 'mv "$1.fugitive" "$1"')
-endfunction
-
-function! fugitive#Cwindow() abort
- if &buftype == 'quickfix'
- cwindow
- else
- botright cwindow
- if &buftype == 'quickfix'
- wincmd p
- endif
- endif
-endfunction
-
-let s:common_efm = ''
- \ . '%+Egit:%.%#,'
- \ . '%+Eusage:%.%#,'
- \ . '%+Eerror:%.%#,'
- \ . '%+Efatal:%.%#,'
- \ . '%-G%.%#%\e[K%.%#,'
- \ . '%-G%.%#%\r%.%\+'
-
-let s:rebase_abbrevs = {
- \ 'p': 'pick',
- \ 'r': 'reword',
- \ 'e': 'edit',
- \ 's': 'squash',
- \ 'f': 'fixup',
- \ 'x': 'exec',
- \ 'd': 'drop',
- \ 'l': 'label',
- \ 't': 'reset',
- \ 'm': 'merge',
- \ 'b': 'break',
- \ }
-
-function! s:RebaseEdit(cmd, dir) abort
- let rebase_todo = s:fnameescape(fugitive#Find('.git/rebase-merge/git-rebase-todo', a:dir))
-
- if filereadable(rebase_todo)
- let new = readfile(rebase_todo)
- let sha_length = 0
- let shas = {}
-
- for i in range(len(new))
- if new[i] =~# '^\l\+\s\+[0-9a-f]\{5,\}\>'
- let sha = matchstr(new[i], '\C\<[a-f0-9]\{5,\}\>')
- if !sha_length
- let sha_length = len(s:TreeChomp(a:dir, 'rev-parse', '--short', sha))
- endif
- let shortened_sha = strpart(sha, 0, sha_length)
- let shas[shortened_sha] = sha
- let new[i] = substitute(new[i], sha, shortened_sha, '')
- endif
- endfor
- call writefile(new, rebase_todo)
- endif
- return a:cmd . ' +setlocal\ bufhidden=wipe\|' . escape('let b:fugitive_rebase_shas = ' . string(shas), ' ') . ' ' . rebase_todo
-endfunction
-
-function! s:MergeRebase(cmd, bang, mods, args, ...) abort
- let dir = a:0 ? a:1 : s:Dir()
- let args = a:args
- let mods = s:Mods(a:mods)
- if a:cmd =~# '^rebase' && s:HasOpt(args, '-i', '--interactive')
- let cmd = fugitive#Prepare(dir, '-c', 'sequence.editor=sh ' . s:RebaseSequenceAborter(), 'rebase') . ' ' . s:shellesc(args)
- let out = system(cmd)[0:-2]
- for file in ['end', 'msgnum']
- let file = fugitive#Find('.git/rebase-merge/' . file, dir)
- if !filereadable(file)
- return 'echoerr ' . string("fugitive: " . out)
- endif
- call writefile([readfile(file)[0] - 1], file)
- endfor
- call writefile([], fugitive#Find('.git/rebase-merge/done', dir))
- if a:bang
- return 'exe'
- endif
- return s:RebaseEdit(mods . 'split', dir)
- elseif a:cmd =~# '^rebase' && s:HasOpt(args, '--edit-todo') && filereadable(fugitive#Find('.git/rebase-merge/git-rebase-todo', dir))
- return s:RebaseEdit(mods . 'split', dir)
- elseif a:cmd =~# '^rebase' && s:HasOpt(args, '--continue') && !a:0
- let rdir = fugitive#Find('.git/rebase-merge', dir)
- let exec_error = s:ChompError([dir, 'diff-index', '--cached', '--quiet', 'HEAD', '--'])[1]
- if exec_error && isdirectory(rdir)
- if getfsize(rdir . '/amend') <= 0
- return 'exe ' . string(mods . 'Gcommit -n -F ' . s:fnameescape(rdir .'/message') . ' -e') . '|let b:fugitive_commit_rebase = 1'
- elseif readfile(rdir . '/amend')[0] ==# fugitive#Head(-1, dir)
- return 'exe ' . string(mods . 'Gcommit --amend -n -F ' . s:fnameescape(rdir . '/message') . ' -e') . '|let b:fugitive_commit_rebase = 1'
- endif
- endif
- endif
- let had_merge_msg = filereadable(fugitive#Find('.git/MERGE_MSG', dir))
- let argv = []
- if a:cmd ==# 'pull'
- let argv += s:AskPassArgs(dir) + ['pull', '--progress']
- else
- call add(argv, a:cmd)
- endif
- if !s:HasOpt(args, '--no-edit', '--abort', '-m') && a:cmd !=# 'rebase'
- call add(argv, '--edit')
- endif
- if a:cmd ==# 'rebase' && s:HasOpt(args, '--autosquash') && !s:HasOpt(args, '--interactive', '-i')
- call add(argv, '--interactive')
- endif
- call extend(argv, args)
-
- let [mp, efm] = [&l:mp, &l:efm]
- try
- let cdback = s:Cd(s:Tree(dir))
- let &l:errorformat = ''
- \ . '%-Gerror:%.%#false''.,'
- \ . '%-G%.%# ''git commit'' %.%#,'
- \ . '%+Emerge:%.%#,'
- \ . s:common_efm . ','
- \ . '%+ECannot %.%#: You have unstaged changes.,'
- \ . '%+ECannot %.%#: Your index contains uncommitted changes.,'
- \ . '%+EThere is no tracking information for the current branch.,'
- \ . '%+EYou are not currently on a branch. Please specify which,'
- \ . '%+I %#git rebase --continue,'
- \ . 'CONFLICT (%m): %f deleted in %.%#,'
- \ . 'CONFLICT (%m): Merge conflict in %f,'
- \ . 'CONFLICT (%m): Rename \"%f\"->%.%#,'
- \ . 'CONFLICT (%m): Rename %.%#->%f %.%#,'
- \ . 'CONFLICT (%m): There is a directory with name %f in %.%#,'
- \ . '%+ECONFLICT %.%#,'
- \ . '%+EKONFLIKT %.%#,'
- \ . '%+ECONFLIT %.%#,'
- \ . "%+EXUNG \u0110\u1ed8T %.%#,"
- \ . "%+E\u51b2\u7a81 %.%#,"
- \ . 'U%\t%f'
- let cmd = s:UserCommand(dir, argv)
- if !empty($GIT_SEQUENCE_EDITOR) || has('win32')
- let old_sequence_editor = $GIT_SEQUENCE_EDITOR
- let $GIT_SEQUENCE_EDITOR = 'true'
- else
- let cmd = 'env GIT_SEQUENCE_EDITOR=true ' . cmd
- endif
- if !empty($GIT_EDITOR) || has('win32')
- let old_editor = $GIT_EDITOR
- let $GIT_EDITOR = 'false'
- else
- let cmd = 'env GIT_EDITOR=false ' . substitute(cmd, '^env ', '', '')
- endif
- if !has('patch-8.1.0334') && has('terminal') && &autowrite
- let autowrite_was_set = 1
- set noautowrite
- silent! wall
- endif
- let &l:makeprg = cmd
- silent noautocmd make!
- catch /^Vim\%((\a\+)\)\=:E211/
- let err = v:exception
- finally
- if exists('autowrite_was_set')
- set autowrite
- endif
- redraw!
- let [&l:mp, &l:efm] = [mp, efm]
- if exists('old_editor')
- let $GIT_EDITOR = old_editor
- endif
- if exists('old_sequence_editor')
- let $GIT_SEQUENCE_EDITOR = old_sequence_editor
- endif
- execute cdback
- endtry
- call fugitive#ReloadStatus(dir, 1)
- if empty(filter(getqflist(),'v:val.valid && v:val.type !=# "I"'))
- if a:cmd =~# '^rebase' &&
- \ filereadable(fugitive#Find('.git/rebase-merge/done', dir)) &&
- \ get(readfile(fugitive#Find('.git/rebase-merge/done', dir)), -1, '') =~# '^[^bep]'
- cclose
- let amend = filereadable(fugitive#Find('.git/rebase-merge/amend', dir)) ? '--amend ' : ''
- return 'exe ' . string(mods . 'Gcommit ' . amend . '-n -F ' . s:fnameescape(fugitive#Find('.git/rebase-merge/message', dir)) . ' -e') . '|let b:fugitive_commit_rebase = 1'
- elseif !had_merge_msg && filereadable(fugitive#Find('.git/MERGE_MSG', dir))
- cclose
- return mods . 'Gcommit --no-status -n -t '.s:fnameescape(fugitive#Find('.git/MERGE_MSG', dir))
- endif
- endif
- let qflist = getqflist()
- let found = 0
- for e in qflist
- if !empty(e.bufnr)
- let found = 1
- let e.pattern = '^<<<<<<<'
- endif
- endfor
- call fugitive#Cwindow()
- if found
- call setqflist(qflist, 'r')
- if !a:bang
- call s:BlurStatus()
- return 'cfirst'
- endif
- endif
- return exists('err') ? 'echoerr '.string(err) : 'exe'
-endfunction
-
-function! s:RebaseClean(file) abort
- if !filereadable(a:file)
- return ''
- endif
- let old = readfile(a:file)
- let new = copy(old)
- for i in range(len(new))
- let new[i] = substitute(new[i], '^\l\>', '\=get(s:rebase_abbrevs,submatch(0),submatch(0))', '')
-
- let sha = matchstr(new[i], '\C\<[a-f0-9]\{5,\}\>')
- let rebase_shas = getbufvar(a:file, 'fugitive_rebase_shas')
- if len(sha) && type(rebase_shas) == type({}) && has_key(rebase_shas, sha)
- let new[i] = substitute(new[i], '\C\<' . sha . '\>', rebase_shas[sha], '')
- endif
- endfor
- if new !=# old
- call writefile(new, a:file)
- endif
- return ''
-endfunction
-
function! s:MergeSubcommand(line1, line2, range, bang, mods, args) abort
let dir = s:Dir()
if empty(a:args) && (
@@ -3953,44 +3761,16 @@ function! s:MergeSubcommand(line1, line2, range, bang, mods, args) abort
\ !empty(s:TreeChomp(dir, 'diff-files', '--diff-filter=U')))
return 'echohl WarningMsg|echo ":Git merge for loading conflicts is deprecated in favor of :Git mergetool"|echohl NONE|silent Git' . (a:bang ? '!' : '') . ' mergetool'
endif
- return s:MergeRebase('merge', a:bang, a:mods, a:args)
+ return {}
endfunction
function! s:RebaseSubcommand(line1, line2, range, bang, mods, args) abort
- return s:MergeRebase('rebase', a:bang, a:mods, a:args)
-endfunction
-
-function! s:PullSubcommand(line1, line2, range, bang, mods, args) abort
- return s:MergeRebase('pull', a:bang, a:mods, a:args)
-endfunction
-
-function! s:RebaseContinue(arg, ...) abort
- let [dir, edit_todo] = a:arg
- exe s:MergeRebase('rebase', 0, '', [edit_todo && getfsize(fugitive#Find('.git/rebase-merge/git-rebase-todo', dir)) <= 0 ? '--abort' : '--continue'], dir)
+ if s:HasOpt(a:args, '--autosquash') && !s:HasOpt(a:args, '-i', '--interactive')
+ return {'env': {'GIT_SEQUENCE_EDITOR': 'true'}, 'args': ['rebase', '--interactive'] + a:args}
+ endif
+ return {}
endfunction
-augroup fugitive_merge
- autocmd!
- autocmd VimLeavePre,BufDelete git-rebase-todo
- \ if type(getbufvar(+expand('<abuf>'), 'fugitive_rebase_shas')) == type({}) && getbufvar(+expand('<abuf>'), '&bufhidden') ==# 'wipe' |
- \ if exists('*job_start') |
- \ throw 'this should never be called' |
- \ endif |
- \ call s:RebaseClean(expand('<afile>')) |
- \ if getfsize(FugitiveFind('.git/rebase-merge/done', +expand('<abuf>'))) == 0 |
- \ let s:rebase_continue = [FugitiveGitDir(+expand('<abuf>')), 1] |
- \ endif |
- \ endif
- autocmd BufEnter * nested
- \ if exists('s:rebase_continue') |
- \ if has('timers') |
- \ call timer_start(0, function('s:RebaseContinue', [remove(s:, 'rebase_continue')])) |
- \ else |
- \ call s:RebaseContinue(remove(s:, 'rebase_continue')) |
- \ endif |
- \ endif
-augroup END
-
" Section: :Git difftool, :Git mergetool
function! s:ToolItems(state, from, to, offsets, text, ...) abort
diff --git a/doc/fugitive.txt b/doc/fugitive.txt
@@ -45,22 +45,6 @@ that are part of Git repositories).
:Git revert [args] A wrapper around git-revert. Similar to |:Gcommit|.
:Grevert [args]
- *:Git-merge* *:Gmerge*
-:Git merge [args] Calls git-merge and loads errors and conflicted files
-:Gmerge [args] into the |quickfix| list. Opens a |:Gcommit| style
- split window for the commit message if the merge
- succeeds. If called during a merge conflict, the
- conflicted files from the current index are loaded
- into the |quickfix| list.
-
- *:Git-pull* *:Gpull*
-:Git pull [args] Like |:Gmerge|, but for git-pull.
-:Gpull [args]
-
- *:Git-rebase* *:Grebase*
-:Git rebase [args] Like |:Gmerge|, but for git-rebase. Interactive
-:Grebase [args] rebase is experimentally supported.
-
*:Git-push* *:Gpush*
:Git push [args] Invoke git-push, load the results into the |quickfix|
:Gpush [args] list, and invoke |:cwindow| to reveal any errors.
@@ -119,6 +103,17 @@ that are part of Git repositories).
*:Git-mergetool*
:Git mergetool [args] Like |:Git-difftool|, but target merge conflicts.
+ *:Git-merge* *:Gmerge*
+:Gmerge [args] Deprecated alias for |:Git| merge. Use |:Git-mergetool|
+ to get the old behavior of loading merge conflicts
+ into the quickfix list.
+
+ *:Git-pull* *:Gpull*
+:Gpull [args] Deprecated alias for |:Git| pull.
+
+ *:Git-rebase* *:Grebase*
+:Grebase [args] Deprecated alias for |:Git| rebase.
+
*:Gclog* *:Glog*
:Gclog[!] [args] Use git-log [args] to load the commit history into the
:Glog[!] [args] |quickfix| list. Jumps to the first commit unless [!]