From 078ffa61971dbcbb85875179fab7adc3104284f8 Mon Sep 17 00:00:00 2001 From: Tim Pope Date: Sun, 2 Jun 2019 16:19:09 -0400 Subject: [PATCH] Don't assume b:git_dir is an actual directory This is a quick first pass. There may be others hiding. References https://github.com/tpope/vim-fugitive/issues/776 --- autoload/fugitive.vim | 68 ++++++++++++++++++++++--------------------- 1 file changed, 35 insertions(+), 33 deletions(-) diff --git a/autoload/fugitive.vim b/autoload/fugitive.vim index 6112c5a..898eba5 100644 --- a/autoload/fugitive.vim +++ b/autoload/fugitive.vim @@ -323,10 +323,10 @@ endfunction function! fugitive#Head(...) abort let dir = a:0 > 1 ? a:2 : s:Dir() - if empty(dir) || !filereadable(dir . '/HEAD') + if empty(dir) || !filereadable(fugitive#Find('.git/HEAD', dir)) return '' endif - let head = readfile(dir . '/HEAD')[0] + let head = readfile(fugitive#Find('.git/HEAD', dir))[0] if head =~# '^ref: ' return substitute(head, '\C^ref: \%(refs/\%(heads/\|remotes/\|tags/\)\=\)\=', '', '') elseif head =~# '^\x\{40\}$' @@ -561,6 +561,7 @@ function! s:Owner(path, ...) abort if empty(dir) return '' endif + let actualdir = fugitive#Find('.git/', dir) let [pdir, commit, file] = s:DirCommitFile(a:path) if s:cpath(dir, pdir) if commit =~# '^\x\{40\}$' @@ -568,9 +569,9 @@ function! s:Owner(path, ...) abort elseif commit ==# '2' return 'HEAD^{}' endif - if filereadable(dir . '/MERGE_HEAD') + if filereadable(actualdir . 'MERGE_HEAD') let merge_head = 'MERGE_HEAD' - elseif filereadable(dir . '/REBASE_HEAD') + elseif filereadable(actualdir . 'REBASE_HEAD') let merge_head = 'REBASE_HEAD' else return '' @@ -582,8 +583,8 @@ function! s:Owner(path, ...) abort endif endif let path = fnamemodify(a:path, ':p') - if s:cpath(dir . '/', path[0 : len(dir)]) && a:path =~# 'HEAD$' - return strpart(path, len(dir) + 1) + if s:cpath(actualdir, strpart(path, 0, len(actualdir))) && a:path =~# 'HEAD$' + return strpart(path, len(actualdir)) endif let refs = fugitive#CommonDir(dir) . '/refs' if s:cpath(refs . '/', path[0 : len(refs)]) && path !~# '[\/]$' @@ -697,7 +698,7 @@ function! fugitive#Find(object, ...) abort let f = base . f[3:-1] elseif cdir !=# dir && ( \ f =~# '^/\%(config\|hooks\|info\|logs/refs\|objects\|refs\|worktrees\)\%(/\|$\)' || - \ f !~# '^/logs$\|/\w*HEAD$' && getftime(dir . f) < 0 && getftime(cdir . f) >= 0) + \ f !~# '^/\%(index$\|index\.lock$\|\w*MSG$\|\w*HEAD$\|logs/\w*HEAD$\|logs$\|rebase-\w\+\)\%(/\|$\)' && getftime(dir . f) < 0 && getftime(cdir . f) >= 0) let f = simplify(cdir . f) else let f = simplify(dir . f) @@ -728,7 +729,7 @@ function! fugitive#Find(object, ...) abort if $GIT_INDEX_FILE =~# '/[^/]*index[^/]*\.lock$' && s:cpath(fnamemodify($GIT_INDEX_FILE,':p')[0:strlen(dir)]) ==# s:cpath(dir . '/') && filereadable($GIT_INDEX_FILE) let f = fnamemodify($GIT_INDEX_FILE, ':p') else - let f = dir . '/index' + let f = fugitive#Find('.git/index', dir) endif elseif rev =~# '^:(\%(top\|top,literal\|literal,top\|literal\))' let f = base . '/' . matchstr(rev, ')\zs.*') @@ -889,7 +890,7 @@ let s:indexes = {} function! s:TreeInfo(dir, commit) abort if a:commit =~# '^:\=[0-3]$' let index = get(s:indexes, a:dir, []) - let newftime = getftime(a:dir . '/index') + let newftime = getftime(fugitive#Find('.git/index', a:dir)) if get(index, 0, -1) < newftime let out = system(fugitive#Prepare(a:dir, 'ls-files', '--stage', '--')) let s:indexes[a:dir] = [newftime, {'0': {}, '1': {}, '2': {}, '3': {}}] @@ -998,7 +999,7 @@ endfunction function! fugitive#filewritable(url) abort let [dir, commit, file] = s:DirCommitFile(a:url) - if commit !~# '^\d$' || !filewritable(dir . '/index') + if commit !~# '^\d$' || !filewritable(fugitive#Find('.git/index', dir)) return 0 endif return s:PathInfo(a:url)[2] ==# 'blob' ? 1 : 2 @@ -1134,7 +1135,7 @@ function! fugitive#glob(url, ...) abort let pattern = '^' . substitute(glob, '/\=\*\*/\=\|/\=\*\|[.?\$]\|^^', '\=get(s:globsubs, submatch(0), "\\" . submatch(0))', 'g')[1:-1] . '$' let results = [] for dir in dirglob =~# '[*?]' ? split(glob(dirglob), "\n") : [dirglob] - if empty(dir) || !get(g:, 'fugitive_file_api', 1) || !filereadable(dir . '/HEAD') + if empty(dir) || !get(g:, 'fugitive_file_api', 1) || !filereadable(fugitive#Find('.git/HEAD', dir)) continue endif let files = items(s:TreeInfo(dir, commit)[0]) @@ -1405,7 +1406,7 @@ function! fugitive#BufReadStatus() abort silent doautocmd BufReadPre let cmd = [fnamemodify(amatch, ':h')] setlocal noro ma nomodeline buftype=nowrite - if s:cpath(fnamemodify($GIT_INDEX_FILE !=# '' ? $GIT_INDEX_FILE : s:Dir() . '/index', ':p')) !=# s:cpath(amatch) + if s:cpath(fnamemodify($GIT_INDEX_FILE !=# '' ? $GIT_INDEX_FILE : fugitive#Find('.git/index'), ':p')) !=# s:cpath(amatch) let cmd += ['-c', 'GIT_INDEX_FILE=' . amatch] endif let cmd += ['status', '--porcelain', '-bz'] @@ -1688,7 +1689,7 @@ function! fugitive#BufReadCmd(...) abort let error = b:fugitive_type unlet b:fugitive_type if rev =~# '^:\d:' - let &l:readonly = !filewritable(dir . '/index') + let &l:readonly = !filewritable(fugitive#Find('.git/index', dir)) return 'silent doautocmd BufNewFile' else setlocal readonly nomodifiable @@ -1758,7 +1759,7 @@ function! fugitive#BufReadCmd(...) abort keepjumps call setpos('.',pos) setlocal nomodified noswapfile let modifiable = rev =~# '^:.:' && b:fugitive_type !=# 'tree' - let &l:readonly = !modifiable || !filewritable(dir . '/index') + let &l:readonly = !modifiable || !filewritable(fugitive#Find('.git/index', dir)) if &bufhidden ==# '' setlocal bufhidden=delete endif @@ -2652,7 +2653,7 @@ function! s:CommitCommand(line1, line2, range, count, bang, mods, reg, arg, args let mods = s:gsub(a:mods ==# '' ? '' : a:mods, '', '-tab') let dir = a:0 ? a:1 : s:Dir() let tree = s:Tree(dir) - let msgfile = dir . '/COMMIT_EDITMSG' + let msgfile = fugitive#Find('.git/COMMIT_EDITMSG', dir) let outfile = tempname() let errorfile = tempname() try @@ -2836,7 +2837,7 @@ let s:rebase_abbrevs = { \ } function! s:RebaseEdit(cmd, dir) abort - let rebase_todo = s:fnameescape(a:dir . '/rebase-merge/git-rebase-todo') + let rebase_todo = s:fnameescape(fugitive#Find('.git/rebase-merge/git-rebase-todo', a:dir)) if filereadable(rebase_todo) let new = readfile(rebase_todo) @@ -2877,21 +2878,21 @@ function! s:Merge(cmd, bang, mods, args, ...) abort return '' endif return s:RebaseEdit(mods . 'split', dir) - elseif a:cmd =~# '^rebase' && ' '.a:args =~# ' --edit-todo' && filereadable(dir . '/rebase-merge/git-rebase-todo') + elseif a:cmd =~# '^rebase' && ' '.a:args =~# ' --edit-todo' && filereadable(fugitive#Find('.git/rebase-merge/git-rebase-todo', dir)) return s:RebaseEdit(mods . 'split', dir) elseif a:cmd =~# '^rebase' && ' '.a:args =~# ' --continue' && !a:0 - let rdir = dir . '/rebase-merge' + let rdir = fugitive#Find('.git/rebase-merge', dir) call system(fugitive#Prepare(dir, 'diff-index', '--cached', '--quiet', 'HEAD', '--')) if v:shell_error && isdirectory(rdir) if getfsize(rdir . '/amend') <= 0 - return 'exe ' . string(mods . 'Gcommit -n -F ' . s:shellesc(dir . '/rebase-merge/message') . ' -e') . '|let b:fugitive_commit_rebase = 1' + return 'exe ' . string(mods . 'Gcommit -n -F ' . s:shellesc(rdir .'/message') . ' -e') . '|let b:fugitive_commit_rebase = 1' elseif readfile(rdir . '/amend')[0] ==# fugitive#Head(-1, dir) - return 'exe ' . string(mods . 'Gcommit --amend -n -F ' . s:shellesc(dir . '/rebase-merge/message') . ' -e') . '|let b:fugitive_commit_rebase = 1' + return 'exe ' . string(mods . 'Gcommit --amend -n -F ' . s:shellesc(rdir . '/message') . ' -e') . '|let b:fugitive_commit_rebase = 1' endif endif endif let [mp, efm] = [&l:mp, &l:efm] - let had_merge_msg = filereadable(dir . '/MERGE_MSG') + let had_merge_msg = filereadable(fugitive#Find('.git/MERGE_MSG', dir)) try let cdback = s:Cd(s:Tree(dir)) let &l:errorformat = '' @@ -2916,7 +2917,7 @@ function! s:Merge(cmd, bang, mods, args, ...) abort \ . "%+E\u51b2\u7a81 %.%#," \ . 'U%\t%f' if a:cmd =~# '^merge' && empty(a:args) && - \ (had_merge_msg || isdirectory(dir . '/rebase-apply') || + \ (had_merge_msg || isdirectory(fugitive#Find('.git/rebase-apply', dir)) || \ !empty(s:TreeChomp(dir, 'diff-files', '--diff-filter=U'))) let &l:makeprg = g:fugitive_git_executable.' diff-files --name-status --diff-filter=U' else @@ -2954,14 +2955,14 @@ function! s:Merge(cmd, bang, mods, args, ...) abort call fugitive#ReloadStatus() if empty(filter(getqflist(),'v:val.valid && v:val.type !=# "I"')) if a:cmd =~# '^rebase' && - \ filereadable(dir . '/rebase-merge/amend') && - \ filereadable(dir . '/rebase-merge/done') && - \ get(readfile(dir . '/rebase-merge/done'), -1, '') =~# '^[^e]' + \ filereadable(fugitive#Find('.git/rebase-merge/amend', dir)) && + \ filereadable(fugitive#Find('.git/rebase-merge/done', dir)) && + \ get(readfile(fugitive#Find('.git/rebase-merge/done', dir)), -1, '') =~# '^[^e]' cclose - return 'exe ' . string(mods . 'Gcommit --amend -n -F ' . s:shellesc(dir . '/rebase-merge/message') . ' -e') . '|let b:fugitive_commit_rebase = 1' - elseif !had_merge_msg && filereadable(dir . '/MERGE_MSG') + return 'exe ' . string(mods . 'Gcommit --amend -n -F ' . s:shellesc(fugitive#Find('.git/rebase-merge/message', dir)) . ' -e') . '|let b:fugitive_commit_rebase = 1' + elseif !had_merge_msg && filereadable(fugitive#Find('.git/MERGE_MSG', dir)) cclose - return mods . 'Gcommit --no-status -n -t '.s:shellesc(dir . '/MERGE_MSG') + return mods . 'Gcommit --no-status -n -t '.s:shellesc(fugitive#Find('.git/MERGE_MSG', dir)) endif endif let qflist = getqflist() @@ -4178,7 +4179,7 @@ function! s:BrowseCommand(line1, line2, range, count, bang, mods, reg, arg, args endif endif if empty(commit) - let commit = readfile(dir . '/HEAD', '', 1)[0] + let commit = readfile(fugitive#Find('.git/HEAD', dir), '', 1)[0] endif let i = 0 while commit =~# '^ref: ' && i < 10 @@ -4704,11 +4705,12 @@ function! fugitive#Init() abort endif let dir = s:Dir() if stridx(&tags, escape(dir, ', ')) == -1 - if filereadable(dir.'/tags') - let &l:tags = escape(dir.'/tags', ', ').','.&tags + let actualdir = fugitive#Find('.git/', dir) + if filereadable(actualdir . 'tags') + let &l:tags = escape(actualdir . 'tags', ', ').','.&tags endif - if &filetype !=# '' && filereadable(dir.'/'.&filetype.'.tags') - let &l:tags = escape(dir.'/'.&filetype.'.tags', ', ').','.&tags + if &filetype !=# '' && filereadable(actualdir . &filetype . '.tags') + let &l:tags = escape(actualdir . &filetype . '.tags', ', ').','.&tags endif endif try