Retool discard operation during conflict

The use of --theirs for Unstaged and --ours for Staged was based
entirely on the way conflicts were represented in git status --short,
except, that's backwards, the staged column contains our side of the
merge so discarding it should use --theirs.  I never noticed because I
don't use this feature.

Fixing this is guaranteed to burn anybody who learned the whole
behavior, so let's promote 2X and 3X to official status, and require
opting in to the flipped default.

Also, since --ours and --theirs only touch the worktree, the correct
analogous operations for deletion is *not* git rm, but rather to remove
the worktree file directly.  So let's do that, and add it to 2X and 3X
too.

Closes https://github.com/tpope/vim-fugitive/issues/1699

References https://github.com/tpope/vim-fugitive/issues/1648
This commit is contained in:
Tim Pope
2021-03-16 16:04:17 -04:00
parent cc525c99df
commit caf2907fd8
2 changed files with 27 additions and 9 deletions

View File

@@ -3614,6 +3614,7 @@ endfunction
function! s:StageDelete(lnum1, lnum2, count) abort function! s:StageDelete(lnum1, lnum2, count) abort
let restore = [] let restore = []
let err = '' let err = ''
let did_conflict_err = 0
try try
for info in s:Selection(a:lnum1, a:lnum2) for info in s:Selection(a:lnum1, a:lnum2)
if empty(info.paths) if empty(info.paths)
@@ -3646,14 +3647,30 @@ function! s:StageDelete(lnum1, lnum2, count) abort
elseif info.status ==# '?' elseif info.status ==# '?'
call s:TreeChomp('clean', '-f', '--', info.paths[0]) call s:TreeChomp('clean', '-f', '--', info.paths[0])
elseif a:count == 2 elseif a:count == 2
call s:TreeChomp('checkout', '--ours', '--', info.paths[0]) if get(b:fugitive_files['Staged'], info.filename, {'status': ''}).status ==# 'D'
call delete(FugitiveVimPath(info.paths[0]))
else
call s:TreeChomp('checkout', '--ours', '--', info.paths[0])
endif
elseif a:count == 3 elseif a:count == 3
call s:TreeChomp('checkout', '--theirs', '--', info.paths[0]) if get(b:fugitive_files['Unstaged'], info.filename, {'status': ''}).status ==# 'D'
call delete(FugitiveVimPath(info.paths[0]))
else
call s:TreeChomp('checkout', '--theirs', '--', info.paths[0])
endif
elseif info.status =~# '[ADU]' && elseif info.status =~# '[ADU]' &&
\ get(b:fugitive_files[info.section ==# 'Staged' ? 'Unstaged' : 'Staged'], info.filename, {'status': ''}).status =~# '[AU]' \ get(b:fugitive_files[info.section ==# 'Staged' ? 'Unstaged' : 'Staged'], info.filename, {'status': ''}).status =~# '[AU]'
call s:TreeChomp('checkout', info.section ==# 'Staged' ? '--ours' : '--theirs', '--', info.paths[0]) if get(g:, 'fugitive_conflict_x', 0)
call s:TreeChomp('checkout', info.section ==# 'Unstaged' ? '--ours' : '--theirs', '--', info.paths[0])
else
if !did_conflict_err
let err .= '|echoerr "Use 2X for --ours or 3X for --theirs"'
let did_conflict_err = 1
endif
continue
endif
elseif info.status ==# 'U' elseif info.status ==# 'U'
call s:TreeChomp('rm', '--', info.paths[0]) call delete(FugitiveVimPath(info.paths[0]))
elseif info.status ==# 'A' elseif info.status ==# 'A'
call s:TreeChomp('rm', '-f', '--', info.paths[0]) call s:TreeChomp('rm', '-f', '--', info.paths[0])
elseif info.section ==# 'Unstaged' elseif info.section ==# 'Unstaged'
@@ -3661,7 +3678,9 @@ function! s:StageDelete(lnum1, lnum2, count) abort
else else
call s:TreeChomp('checkout', 'HEAD^{}', '--', info.paths[0]) call s:TreeChomp('checkout', 'HEAD^{}', '--', info.paths[0])
endif endif
call add(restore, ':Gsplit ' . s:fnameescape(info.relative[0]) . '|' . undo) if len(undo)
call add(restore, ':Gsplit ' . s:fnameescape(info.relative[0]) . '|' . undo)
endif
endfor endfor
catch /^fugitive:/ catch /^fugitive:/
let err .= '|echoerr ' . string(v:exception) let err .= '|echoerr ' . string(v:exception)

View File

@@ -255,10 +255,9 @@ U Unstage everything.
X Discard the change under the cursor. This uses X Discard the change under the cursor. This uses
`checkout` or `clean` under the hood. A command is `checkout` or `clean` under the hood. A command is
echoed that shows how to undo the change. Consult echoed that shows how to undo the change. Consult
`:messages` to see it again. You can use this during `:messages` to see it again. During a merge conflict,
a merge conflict to discard "our" changes (--theirs) use 2X to call `checkout --ours` or 3X to call
in the "Unstaged" section or discard "their" changes `checkout --theirs` .
(--ours) in the "Staged" section.
*fugitive_=* *fugitive_=*
= Toggle an inline diff of the file under the cursor. = Toggle an inline diff of the file under the cursor.