Use proper argument parsing for :Gcommit

This commit is contained in:
Tim Pope 2019-07-07 05:40:02 -04:00
parent e7f272a36c
commit 73b7e5e23f
2 changed files with 39 additions and 20 deletions

View File

@ -2848,13 +2848,22 @@ function! s:CommitCommand(line1, line2, range, count, bang, mods, reg, arg, args
else else
let command = 'env GIT_EDITOR=false ' let command = 'env GIT_EDITOR=false '
endif endif
if len(a:args) if type(a:arg) == type([])
let [args, after] = s:ShellExpandChain(a:arg, tree) let [argv, after] = [a:arg, '']
else else
let [args, after] = [a:arg, ''] let [argv, after] = s:SplitExpandChain(a:arg, tree)
endif endif
let command .= s:UserCommand(dir) . ' commit ' . args let i = 0
if a:arg =~# '\%(^\| \)-\%(-interactive\|p\|-patch\)\>' && &shell !~# 'csh' while get(argv, i, '--') !=# '--'
if argv[i] =~# '^-[apzsneiovq].'
call insert(argv, argv[i][0:1])
let argv[i+1] = '-' . argv[i+1][2:-1]
else
let i += 1
endif
endwhile
let command .= s:UserCommand(dir) . ' commit ' . s:shellesc(argv)
if s:HasOpt(argv, '-i', '--interactive', '-p', '--patch') && &shell !~# 'csh'
let errorfile = tempname() let errorfile = tempname()
noautocmd execute '!'.command.' 2> '.errorfile noautocmd execute '!'.command.' 2> '.errorfile
let errors = readfile(errorfile) let errors = readfile(errorfile)
@ -2884,21 +2893,34 @@ function! s:CommitCommand(line1, line2, range, count, bang, mods, reg, arg, args
else else
let error = get(errors,-2,get(errors,-1,'!')) let error = get(errors,-2,get(errors,-1,'!'))
if error =~# 'false''\=\.$' if error =~# 'false''\=\.$'
let args = s:gsub(args,'%(%(^| )-- )@<!%(^| )@<=%(-[esp]|--edit|--interactive|--patch|--signoff)%($| )','') let i = 0
let args = s:gsub(args,'%(%(^| )-- )@<!%(^| )@<=%(-c|--reedit-message|--reuse-message|-F|--file|-m|--message)%(\s+|\=)%(''[^'']*''|"%(\\.|[^"])*"|\\.|\S)*','') while get(argv, i, '--') !=# '--'
let args = s:sub(args, '\ze -- |$', ' --no-edit --no-interactive --no-signoff') if argv[i] =~# '^\%(-[eips]\|-[CcFm].\+\|--edit\|--interactive\|--patch\|--signoff\|--reedit-message=.*\|--reuse-message=.*\|--file=.*\|--message=.*\)$'
let args = '-F '.s:shellesc(msgfile).' '.args call remove(argv, i)
if args !~# '\%(^\| \)--cleanup\>' elseif argv[i] =~# '^\%(-[CcFm]\|--reedit-message\|--reuse-message\|--file\|--message\)$'
let args = '--cleanup=strip '.args call remove(argv, i, i + 1)
else
if argv[i] =~# '^--cleanup\>'
let cleanup = 1
endif
let i += 1
endif
endwhile
call insert(argv, '--no-signoff', i)
call insert(argv, '--no-interactive', i)
call insert(argv, '--no-edit', i)
if !exists('cleanup')
call insert(argv, '--cleanup=strip')
endif endif
call extend(argv, ['-F', msgfile], 'keep')
if bufname('%') == '' && line('$') == 1 && getline(1) == '' && !&modified if bufname('%') == '' && line('$') == 1 && getline(1) == '' && !&modified
execute mods . 'keepalt edit' s:fnameescape(msgfile) execute mods . 'keepalt edit' s:fnameescape(msgfile)
elseif a:arg =~# '\%(^\| \)-\w*v' || mods =~# '\<tab\>' elseif s:HasOpt(argv, '-v') || mods =~# '\<tab\>'
execute mods . 'keepalt -tabedit' s:fnameescape(msgfile) execute mods . 'keepalt -tabedit' s:fnameescape(msgfile)
else else
execute mods . 'keepalt split' s:fnameescape(msgfile) execute mods . 'keepalt split' s:fnameescape(msgfile)
endif endif
let b:fugitive_commit_arguments = args let b:fugitive_commit_arguments = argv
setlocal bufhidden=wipe filetype=gitcommit setlocal bufhidden=wipe filetype=gitcommit
return '1' . after return '1' . after
elseif error ==# '!' elseif error ==# '!'
@ -2933,7 +2955,7 @@ function! s:FinishCommit() abort
let buf = +expand('<abuf>') let buf = +expand('<abuf>')
let args = getbufvar(buf, 'fugitive_commit_arguments') let args = getbufvar(buf, 'fugitive_commit_arguments')
if !empty(args) if !empty(args)
call setbufvar(buf, 'fugitive_commit_arguments', '') call setbufvar(buf, 'fugitive_commit_arguments', [])
if getbufvar(buf, 'fugitive_commit_rebase') if getbufvar(buf, 'fugitive_commit_rebase')
call setbufvar(buf, 'fugitive_commit_rebase', 0) call setbufvar(buf, 'fugitive_commit_rebase', 0)
let s:rebase_continue = s:Dir(buf) let s:rebase_continue = s:Dir(buf)
@ -3622,7 +3644,7 @@ endfunction
augroup fugitive_commit augroup fugitive_commit
autocmd! autocmd!
autocmd VimLeavePre,BufDelete COMMIT_EDITMSG execute s:sub(s:FinishCommit(), '^echoerr (.*)', 'echohl ErrorMsg|echo \1|echohl NONE') autocmd VimLeavePre,BufDelete COMMIT_EDITMSG execute substitute(s:FinishCommit(), '\C^echoerr \(''[^'']*''\)*', 'redraw|echohl ErrorMsg|echo \1|echohl NONE', '')
augroup END augroup END
" Section: :Gpush, :Gfetch " Section: :Gpush, :Gfetch

View File

@ -39,11 +39,8 @@ that are part of Git repositories).
given would skip the invocation of an editor (e.g., given would skip the invocation of an editor (e.g.,
-m), a split window will be used to obtain a commit -m), a split window will be used to obtain a commit
message, or a new tab if -v is given. Write and close message, or a new tab if -v is given. Write and close
that window (:wq or |:Gwrite|) to finish the commit. the window (:wq) to finish the commit. To cancel, use
Unlike when running the actual git-commit command, it an empty message.
is possible (but unadvisable) to alter the index with
commands like git-add and git-reset while a commit
message is pending.
*fugitive-:Gmerge* *fugitive-:Gmerge*
:Gmerge [args] Calls git-merge and loads errors and conflicted files :Gmerge [args] Calls git-merge and loads errors and conflicted files