From 6f06629eebfab087562767b09c40191d09628158 Mon Sep 17 00:00:00 2001 From: Michael van der Kamp Date: Sun, 17 Oct 2021 15:11:02 -0600 Subject: [PATCH 1/5] Only query requested path in stage objects --- autoload/fugitive.vim | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/autoload/fugitive.vim b/autoload/fugitive.vim index 5366c48..c63ee10 100644 --- a/autoload/fugitive.vim +++ b/autoload/fugitive.vim @@ -2075,8 +2075,29 @@ function! s:PathInfo(url) abort return [-1, '000000', '', '', -1] endif let path = substitute(file[1:-1], '/*$', '', '') - let [tree, ftime] = s:TreeInfo(dir, commit) - let entry = empty(path) ? [ftime, '040000', 'tree', '', -1] : get(tree, path, []) + + if empty(path) + let [_, ftime] = s:TreeInfo(dir, commit) + let entry = [ftime, '040000', 'tree', '', -1] + elseif commit =~# '^:\=[0-3]$' + let result = fugitive#Execute(['--literal-pathspecs', 'ls-files', '--stage', '--', path]) + let line = result.stdout[0] + if result.exit_status || empty(line) + return [-1, '000000', '', '', -1] + endif + let newftime = getftime(fugitive#Find('.git/index', dir)) + let [info, filename] = split(line, "\t") + if filename ==# path + let [mode, sha, stage] = split(info, '\s\+') + let entry = [newftime, mode, 'blob', sha, -2] + else + let entry = [newftime, '040000', 'tree', '', 0] + endif + else + let [tree, ftime] = s:TreeInfo(dir, commit) + let entry = get(tree, path, []) + endif + if empty(entry) || file =~# '/$' && entry[2] !=# 'tree' return [-1, '000000', '', '', -1] else From c7bfb8241ff02796a36abfc8caf7536143218a44 Mon Sep 17 00:00:00 2001 From: Michael van der Kamp Date: Sat, 23 Oct 2021 19:52:09 -0600 Subject: [PATCH 2/5] Extract IndexInfo() --- autoload/fugitive.vim | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/autoload/fugitive.vim b/autoload/fugitive.vim index c63ee10..cf9de64 100644 --- a/autoload/fugitive.vim +++ b/autoload/fugitive.vim @@ -2069,6 +2069,22 @@ function! s:TreeInfo(dir, commit) abort return [{}, -1] endfunction +function! s:IndexInfo(dir, commit_stage, path) abort + let result = fugitive#Execute(['--literal-pathspecs', 'ls-files', '--stage', '--', a:path]) + let line = result.stdout[0] + if result.exit_status || empty(line) + return [-1, '000000', '', '', -1] + endif + let newftime = getftime(fugitive#Find('.git/index', a:dir)) + let [info, filename] = split(line, "\t") + if filename ==# a:path + let [mode, sha, stage] = split(info, '\s\+') + return [newftime, mode, 'blob', sha, -2] + else + return [newftime, '040000', 'tree', '', 0] + endif +endfunction + function! s:PathInfo(url) abort let [dir, commit, file] = s:DirCommitFile(a:url) if empty(dir) || !get(g:, 'fugitive_file_api', 1) @@ -2080,19 +2096,7 @@ function! s:PathInfo(url) abort let [_, ftime] = s:TreeInfo(dir, commit) let entry = [ftime, '040000', 'tree', '', -1] elseif commit =~# '^:\=[0-3]$' - let result = fugitive#Execute(['--literal-pathspecs', 'ls-files', '--stage', '--', path]) - let line = result.stdout[0] - if result.exit_status || empty(line) - return [-1, '000000', '', '', -1] - endif - let newftime = getftime(fugitive#Find('.git/index', dir)) - let [info, filename] = split(line, "\t") - if filename ==# path - let [mode, sha, stage] = split(info, '\s\+') - let entry = [newftime, mode, 'blob', sha, -2] - else - let entry = [newftime, '040000', 'tree', '', 0] - endif + let entry = s:IndexInfo(dir, commit[-1:-1], path) else let [tree, ftime] = s:TreeInfo(dir, commit) let entry = get(tree, path, []) From 0101f49718033b74bec20a270688e23fd5a12f9c Mon Sep 17 00:00:00 2001 From: Michael van der Kamp Date: Sat, 23 Oct 2021 20:50:39 -0600 Subject: [PATCH 3/5] Let PathInfo decide how to fill the error entry --- autoload/fugitive.vim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/autoload/fugitive.vim b/autoload/fugitive.vim index cf9de64..0d0635f 100644 --- a/autoload/fugitive.vim +++ b/autoload/fugitive.vim @@ -2073,7 +2073,7 @@ function! s:IndexInfo(dir, commit_stage, path) abort let result = fugitive#Execute(['--literal-pathspecs', 'ls-files', '--stage', '--', a:path]) let line = result.stdout[0] if result.exit_status || empty(line) - return [-1, '000000', '', '', -1] + return [] endif let newftime = getftime(fugitive#Find('.git/index', a:dir)) let [info, filename] = split(line, "\t") From d5edbd75d88ee06e0fbfb5897a5f6aad8016f72f Mon Sep 17 00:00:00 2001 From: Michael van der Kamp Date: Sat, 23 Oct 2021 20:51:38 -0600 Subject: [PATCH 4/5] Report info for the correct stage --- autoload/fugitive.vim | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/autoload/fugitive.vim b/autoload/fugitive.vim index 0d0635f..293db85 100644 --- a/autoload/fugitive.vim +++ b/autoload/fugitive.vim @@ -2071,18 +2071,29 @@ endfunction function! s:IndexInfo(dir, commit_stage, path) abort let result = fugitive#Execute(['--literal-pathspecs', 'ls-files', '--stage', '--', a:path]) - let line = result.stdout[0] - if result.exit_status || empty(line) + if result.exit_status return [] endif let newftime = getftime(fugitive#Find('.git/index', a:dir)) - let [info, filename] = split(line, "\t") - if filename ==# a:path + for line in result.stdout[:2] + " Inspect up to the first three lines to find the correct stage + if empty(line) + break + endif + let [info, filename] = split(line, "\t") let [mode, sha, stage] = split(info, '\s\+') - return [newftime, mode, 'blob', sha, -2] - else - return [newftime, '040000', 'tree', '', 0] - endif + if filename ==# a:path + if stage != a:commit_stage + continue + endif + return [newftime, mode, 'blob', sha, -2] + else + " Not concerned about the stage of tree objects- a tree can contain + " blobs from many different stages simultaneously + return [newftime, '040000', 'tree', '', 0] + endif + endfor + return [] endfunction function! s:PathInfo(url) abort From 32e2cd9e470e0e5e20c1505b11c7019e6620bdf7 Mon Sep 17 00:00:00 2001 From: Michael van der Kamp Date: Sun, 24 Oct 2021 22:17:16 -0600 Subject: [PATCH 5/5] Cache results from git ls-files Only support stage '0' for tree objects --- autoload/fugitive.vim | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/autoload/fugitive.vim b/autoload/fugitive.vim index 293db85..29d4a08 100644 --- a/autoload/fugitive.vim +++ b/autoload/fugitive.vim @@ -2069,12 +2069,23 @@ function! s:TreeInfo(dir, commit) abort return [{}, -1] endfunction +let s:index_info = {} function! s:IndexInfo(dir, commit_stage, path) abort + let cache_key = 'cache://' . a:dir . '//' . a:path + let index = get(s:index_info, cache_key, []) + let newftime = getftime(fugitive#Find('.git/index', a:dir)) + + if get(index, 0, -1) == newftime + return get(get(index, 1, {}), a:commit_stage, []) + endif + + let indexes = {'0': [], '1': [], '2': [], '3': []} + let s:index_info[cache_key] = [newftime, indexes] + let result = fugitive#Execute(['--literal-pathspecs', 'ls-files', '--stage', '--', a:path]) if result.exit_status return [] endif - let newftime = getftime(fugitive#Find('.git/index', a:dir)) for line in result.stdout[:2] " Inspect up to the first three lines to find the correct stage if empty(line) @@ -2083,17 +2094,13 @@ function! s:IndexInfo(dir, commit_stage, path) abort let [info, filename] = split(line, "\t") let [mode, sha, stage] = split(info, '\s\+') if filename ==# a:path - if stage != a:commit_stage - continue - endif - return [newftime, mode, 'blob', sha, -2] + let indexes[stage] = [newftime, mode, 'blob', sha, -2] else - " Not concerned about the stage of tree objects- a tree can contain - " blobs from many different stages simultaneously - return [newftime, '040000', 'tree', '', 0] + " Only support stage '0' for tree objects + let indexes['0'] = [newftime, '040000', 'tree', '', 0] endif endfor - return [] + return get(indexes, a:commit_stage, []) endfunction function! s:PathInfo(url) abort