motiejus/dotfiles

Unnamed repository; edit this file 'description' to name the repository.
git clone https://git.jakstys.lt/motiejus/dotfiles.git
Log | Tree | Refs | README | LICENSE

commit caf2907fd82f86a02ff3c07faf26fbb1aa3c8479 (tree)
parent cc525c99df392e0dbb56d4072cd95cf035dc37e4
Author: Tim Pope <code@tpope.net>
Date:   Tue, 16 Mar 2021 16:04:17 -0400

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

Diffstat:
Mautoload/fugitive.vim | 29++++++++++++++++++++++++-----
Mdoc/fugitive.txt | 7+++----
2 files changed, 27 insertions(+), 9 deletions(-)

diff --git a/autoload/fugitive.vim b/autoload/fugitive.vim @@ -3614,6 +3614,7 @@ endfunction function! s:StageDelete(lnum1, lnum2, count) abort let restore = [] let err = '' + let did_conflict_err = 0 try for info in s:Selection(a:lnum1, a:lnum2) if empty(info.paths) @@ -3646,14 +3647,30 @@ function! s:StageDelete(lnum1, lnum2, count) abort elseif info.status ==# '?' call s:TreeChomp('clean', '-f', '--', info.paths[0]) 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 - 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]' && \ 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' - call s:TreeChomp('rm', '--', info.paths[0]) + call delete(FugitiveVimPath(info.paths[0])) elseif info.status ==# 'A' call s:TreeChomp('rm', '-f', '--', info.paths[0]) elseif info.section ==# 'Unstaged' @@ -3661,7 +3678,9 @@ function! s:StageDelete(lnum1, lnum2, count) abort else call s:TreeChomp('checkout', 'HEAD^{}', '--', info.paths[0]) 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 catch /^fugitive:/ let err .= '|echoerr ' . string(v:exception) diff --git a/doc/fugitive.txt b/doc/fugitive.txt @@ -255,10 +255,9 @@ U Unstage everything. X Discard the change under the cursor. This uses `checkout` or `clean` under the hood. A command is echoed that shows how to undo the change. Consult - `:messages` to see it again. You can use this during - a merge conflict to discard "our" changes (--theirs) - in the "Unstaged" section or discard "their" changes - (--ours) in the "Staged" section. + `:messages` to see it again. During a merge conflict, + use 2X to call `checkout --ours` or 3X to call + `checkout --theirs` . *fugitive_=* = Toggle an inline diff of the file under the cursor.