diff --git a/autoload/fugitive.vim b/autoload/fugitive.vim index a33f3c7847b3e6382be5928addd62ea338647c90..a97d6c5d226ae5a6d4e6d95347b28f9538a4f8cc 100644 --- a/autoload/fugitive.vim +++ b/autoload/fugitive.vim @@ -2183,11 +2183,22 @@ function! s:ReplaceCmd(cmd) abort endif endfunction -function! s:QueryLog(refspec) abort - let lines = s:LinesError(['log', '-n', '256', '--pretty=format:%h%x09%s', a:refspec, '--'])[0] +function! s:StatusLogCallback(result, dest) abort + let lines = a:result.stdout + if empty(lines[-1]) + call remove(lines, -1) + endif call map(lines, 'split(v:val, "\t", 1)') call map(lines, '{"type": "Log", "commit": v:val[0], "subject": join(v:val[1 : -1], "\t")}') - return lines + call add(a:dest, lines) +endfunction + +function! s:StatusLog(refspec, dest) abort + return fugitive#Execute(['log', '-n', '256', '--pretty=format:%h%x09%s', a:refspec, '--'], function('s:StatusLogCallback'), a:dest) +endfunction + +function! s:StatusDiffCallback(result, dict, key) abort + let a:dict[a:key] = a:result.stdout endfunction function! s:FormatLog(dict) abort @@ -2377,6 +2388,15 @@ function! fugitive#BufReadStatus() abort let b:fugitive_files['Unstaged'][dict.filename] = dict endfor + let jobs = [] + let diff = {'Staged': [], 'Unstaged': []} + if len(staged) + call add(jobs, fugitive#Execute(['diff', '--color=never', '--no-ext-diff', '--no-prefix', '--cached'], function('s:StatusDiffCallback'), diff, 'Staged')) + endif + if len(unstaged) + call add(jobs, fugitive#Execute(['diff', '--color=never', '--no-ext-diff', '--no-prefix'], function('s:StatusDiffCallback'), diff, 'Unstaged')) + endif + let pull_type = 'Pull' if len(pull) let rebase = FugitiveConfigGet('branch.' . branch . '.rebase', config) @@ -2412,6 +2432,24 @@ function! fugitive#BufReadStatus() abort let push = len(branch) ? (push_remote ==# '.' ? '' : push_remote . '/') . branch : '' endif + let logs = [] + if len(pull) && get(props, 'branch.ab') !~# ' -0$' + call add(logs, ['Unpulled from ' . pull]) + call add(jobs, s:StatusLog(head . '..' . pull, logs[-1])) + endif + if len(push) && push !=# pull + call add(logs, ['Unpulled from ' . push]) + call add(jobs, s:StatusLog(head . '..' . push, logs[-1])) + endif + if len(pull) && push !=# pull + call add(logs, ['Unpushed to ' . pull]) + call add(jobs, s:StatusLog(pull . '..' . head, logs[-1])) + endif + if len(push) && !(push ==# pull && get(props, 'branch.ab') =~# '^+0 ') + call add(logs, ['Unpushed to ' . push]) + call add(jobs, s:StatusLog(push . '..' . head, logs[-1])) + endif + if isdirectory(fugitive#Find('.git/rebase-merge/')) let rebasing_dir = fugitive#Find('.git/rebase-merge/') elseif isdirectory(fugitive#Find('.git/rebase-apply/')) @@ -2446,15 +2484,8 @@ function! fugitive#BufReadStatus() abort endfor endif - let diff = {'Staged': [], 'Unstaged': []} - if len(staged) - let diff['Staged'] = - \ s:LinesError(['diff', '--color=never', '--no-ext-diff', '--no-prefix', '--cached'])[0] - endif - if len(unstaged) - let diff['Unstaged'] = - \ s:LinesError(['diff', '--color=never', '--no-ext-diff', '--no-prefix'])[0] - endif + call fugitive#Wait(jobs) + let b:fugitive_diff = diff let expanded = get(b:, 'fugitive_expanded', {'Staged': {}, 'Unstaged': {}}) let b:fugitive_expanded = {'Staged': {}, 'Unstaged': {}} @@ -2482,18 +2513,9 @@ function! fugitive#BufReadStatus() abort call s:AddSection('Staged', staged) let staged_end = len(staged) ? line('$') : 0 - if len(pull) && get(props, 'branch.ab') !~# ' -0$' - call s:AddSection('Unpulled from ' . pull, s:QueryLog(head . '..' . pull)) - endif - if len(push) && push !=# pull - call s:AddSection('Unpulled from ' . push, s:QueryLog(head . '..' . push)) - endif - if len(pull) && push !=# pull - call s:AddSection('Unpushed to ' . pull, s:QueryLog(pull . '..' . head)) - endif - if len(push) && !(push ==# pull && get(props, 'branch.ab') =~# '^+0 ') - call s:AddSection('Unpushed to ' . push, s:QueryLog(push . '..' . head)) - endif + for [title, log] in logs + call s:AddSection(title, log) + endfor setlocal nomodified readonly noswapfile silent doautocmd BufReadPost