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
This commit is contained in:
Tim Pope
2019-06-02 16:19:09 -04:00
parent 79f3be9f17
commit 078ffa6197

View File

@@ -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 ==# '<mods>' ? '' : a:mods, '<tab>', '-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