From d523feebe99bb93a9309ef83cbac2b71ac408c36 Mon Sep 17 00:00:00 2001 From: Tim Pope Date: Sat, 28 Aug 2021 08:34:40 -0400 Subject: [PATCH] Respect 'splitbelow' on :Gdiffsplit with argument When calling :Gdiffsplit with no argument, we always end up with the work tree version as half of the diff, and it is helpful to position that consistently. I generalized this to a consistent older versus newer ordering when given an argument, but I don't think that has proven very useful in practice. This also introduces a minor behavior change where calling the bang variant in the initial commit now loads an empty version of the buffer, rather than falling back to the work tree. --- autoload/fugitive.vim | 38 ++++++++------------------------------ doc/fugitive.txt | 9 +++++---- 2 files changed, 13 insertions(+), 34 deletions(-) diff --git a/autoload/fugitive.vim b/autoload/fugitive.vim index 3ad35c4..5948d18 100644 --- a/autoload/fugitive.vim +++ b/autoload/fugitive.vim @@ -6116,28 +6116,6 @@ function! s:diffoff_all(dir) abort diffoff! endfunction -function! s:CompareAge(mine, theirs) abort - let scores = {':0': 1, ':1': 2, ':2': 3, ':': 4, ':3': 5} - let mine = substitute(a:mine, '^:', '', '') - let theirs = substitute(a:theirs, '^:', '', '') - let my_score = get(scores, ':'.mine, 0) - let their_score = get(scores, ':'.theirs, 0) - if my_score || their_score - return my_score < their_score ? -1 : my_score != their_score - elseif mine ==# theirs - return 0 - endif - let base = s:TreeChomp('merge-base', mine, theirs) - if base ==# mine - return -1 - elseif base ==# theirs - return 1 - endif - let my_time = +s:TreeChomp('log', '--max-count=1', '--pretty=format:%at', a:mine, '--') - let their_time = +s:TreeChomp('log', '--max-count=1', '--pretty=format:%at', a:theirs, '--') - return my_time < their_time ? -1 : my_time != their_time -endfunction - function! s:IsConflicted() abort return len(@%) && !empty(s:ChompDefault('', ['ls-files', '--unmerged', '--', expand('%:p')])) endfunction @@ -6218,7 +6196,7 @@ function! fugitive#Diffsplit(autodir, keepfocus, mods, arg, args) abort let file = s:Relative() elseif arg ==# ':' exe s:DirCheck() - let file = s:Relative(':0:') + let file = len(commit) ? s:Relative() : s:Relative(s:IsConflicted() ? ':1:' : ':0:') elseif arg =~# '^:\d$' exe s:DirCheck() let file = s:Relative(arg . ':') @@ -6231,18 +6209,23 @@ function! fugitive#Diffsplit(autodir, keepfocus, mods, arg, args) abort return 'echoerr ' . string(v:exception) endtry endif - elseif exists('parents') && len(parents) - let file = parents[-1] + let mods = s:Mods(a:mods) + elseif exists('parents') + let file = get(parents, -1, s:Relative(repeat('0', 40). ':')) + let mods = s:Mods(a:mods, 'leftabove') elseif len(commit) let file = s:Relative() + let mods = s:Mods(a:mods, 'rightbelow') elseif s:IsConflicted() let file = s:Relative(':1:') + let mods = s:Mods(a:mods, 'leftabove') if get(g:, 'fugitive_legacy_commands', 1) let post = 'echohl WarningMsg|echo "Use :Gdiffsplit! for 3 way diff"|echohl NONE|' . post endif else exe s:DirCheck() let file = s:Relative(':0:') + let mods = s:Mods(a:mods, 'leftabove') endif let spec = s:Generate(file) if spec =~# '^fugitive:' && empty(s:DirCommitFile(spec)[2]) @@ -6251,11 +6234,6 @@ function! fugitive#Diffsplit(autodir, keepfocus, mods, arg, args) abort exe pre let restore = s:diff_restore() let w:fugitive_diff_restore = restore - if len(spec) && s:CompareAge(commit, s:DirCommitFile(spec)[1]) < 0 - let mods = s:Mods(mods, 'rightbelow') - else - let mods = s:Mods(mods, 'leftabove') - endif let mods = (autodir ? s:diff_modifier(2) : '') . mods if &diffopt =~# 'vertical' let diffopt = &diffopt diff --git a/doc/fugitive.txt b/doc/fugitive.txt index d939fd9..d70e7ab 100644 --- a/doc/fugitive.txt +++ b/doc/fugitive.txt @@ -184,10 +184,11 @@ that are part of Git repositories). :Gdiffsplit [object] Perform a |vimdiff| against the given file, or if a commit is given, the current file in that commit. With no argument, the version in the index or work - tree is used. The newer of the two files is placed to - the right or bottom, depending on 'diffopt' and the - width of the window relative to 'textwidth'. Use - Vim's |do| and |dp| to stage and unstage changes. + tree is used, and the work tree version is always + placed to the right or bottom. A vertical split is + used if space permits, and if 'diffopt' does not + otherwise specify. Use Vim's |do| and |dp| to stage + and unstage changes. *:Gdiffsplit!* :Gdiffsplit! Diff against any and all direct ancestors, retaining