mirror of
https://github.com/tpope/vim-fugitive.git
synced 2025-11-13 22:03:51 -05:00
Partially support ".git" files and symlinks without core.worktree
This is not and can never be 100% perfect. There's no way to work back from a file like info/exclude COMMIT_EDITMSG to the work tree. So core.worktree continues to be recommended. References: https://github.com/tpope/vim-fugitive/issues/1920
This commit is contained in:
@@ -1796,7 +1796,9 @@ function! fugitive#Find(object, ...) abort
|
|||||||
elseif rev ==# ':'
|
elseif rev ==# ':'
|
||||||
let fdir = simplify(FugitiveActualDir(dir) . '/')
|
let fdir = simplify(FugitiveActualDir(dir) . '/')
|
||||||
let f = fdir . 'index'
|
let f = fdir . 'index'
|
||||||
if len($GIT_INDEX_FILE)
|
if !s:cpath(dir . '/', fdir)
|
||||||
|
let f = urlprefix
|
||||||
|
elseif len($GIT_INDEX_FILE)
|
||||||
let index_dir = substitute(s:GitIndexFileEnv(), '[^/]\+$', '', '')
|
let index_dir = substitute(s:GitIndexFileEnv(), '[^/]\+$', '', '')
|
||||||
if s:cpath(index_dir, fdir)
|
if s:cpath(index_dir, fdir)
|
||||||
let f = s:GitIndexFileEnv()
|
let f = s:GitIndexFileEnv()
|
||||||
|
|||||||
@@ -270,8 +270,16 @@ function! FugitiveStatusline(...) abort
|
|||||||
return fugitive#Statusline()
|
return fugitive#Statusline()
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
let s:resolved_git_dirs = {}
|
||||||
function! FugitiveActualDir(...) abort
|
function! FugitiveActualDir(...) abort
|
||||||
return call('FugitiveGitDir', a:000)
|
let dir = call('FugitiveGitDir', a:000)
|
||||||
|
if empty(dir)
|
||||||
|
return ''
|
||||||
|
endif
|
||||||
|
if !has_key(s:resolved_git_dirs, dir)
|
||||||
|
let s:resolved_git_dirs[dir] = s:ResolveGitDir(dir)
|
||||||
|
endif
|
||||||
|
return empty(s:resolved_git_dirs[dir]) ? dir : s:resolved_git_dirs[dir]
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
let s:commondirs = {}
|
let s:commondirs = {}
|
||||||
@@ -331,12 +339,12 @@ endfunction
|
|||||||
let s:worktree_for_dir = {}
|
let s:worktree_for_dir = {}
|
||||||
let s:dir_for_worktree = {}
|
let s:dir_for_worktree = {}
|
||||||
function! s:Tree(path) abort
|
function! s:Tree(path) abort
|
||||||
let dir = a:path
|
if a:path =~# '/\.git$'
|
||||||
if dir =~# '/\.git$'
|
return len(a:path) ==# 5 ? '/' : a:path[0:-6]
|
||||||
return len(dir) ==# 5 ? '/' : dir[0:-6]
|
elseif a:path ==# ''
|
||||||
elseif dir ==# ''
|
|
||||||
return ''
|
return ''
|
||||||
endif
|
endif
|
||||||
|
let dir = FugitiveActualDir(a:path)
|
||||||
if !has_key(s:worktree_for_dir, dir)
|
if !has_key(s:worktree_for_dir, dir)
|
||||||
let s:worktree_for_dir[dir] = ''
|
let s:worktree_for_dir[dir] = ''
|
||||||
let ext_wtc_pat = 'v:val =~# "^\\s*worktreeConfig *= *\\%(true\\|yes\\|on\\|1\\) *$"'
|
let ext_wtc_pat = 'v:val =~# "^\\s*worktreeConfig *= *\\%(true\\|yes\\|on\\|1\\) *$"'
|
||||||
@@ -395,6 +403,24 @@ function! s:CeilingDirectories() abort
|
|||||||
return s:ceiling_directories + get(g:, 'ceiling_directories', [s:Slash(fnamemodify(expand('~'), ':h'))])
|
return s:ceiling_directories + get(g:, 'ceiling_directories', [s:Slash(fnamemodify(expand('~'), ':h'))])
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
function! s:ResolveGitDir(git_dir) abort
|
||||||
|
let type = getftype(a:git_dir)
|
||||||
|
if type ==# 'dir' && FugitiveIsGitDir(a:git_dir)
|
||||||
|
return a:git_dir
|
||||||
|
elseif type ==# 'link' && FugitiveIsGitDir(a:git_dir)
|
||||||
|
return resolve(a:git_dir)
|
||||||
|
elseif type !=# ''
|
||||||
|
let line = get(s:ReadFile(a:git_dir, 1), 0, '')
|
||||||
|
let file_dir = s:Slash(FugitiveVimPath(matchstr(line, '^gitdir: \zs.*')))
|
||||||
|
if file_dir !~# '^/\|^\a:\|^$' && a:git_dir =~# '/\.git$' && FugitiveIsGitDir(a:git_dir[0:-5] . file_dir)
|
||||||
|
return simplify(a:git_dir[0:-5] . file_dir)
|
||||||
|
elseif file_dir =~# '^/\|^\a:' && FugitiveIsGitDir(file_dir)
|
||||||
|
return file_dir
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
return ''
|
||||||
|
endfunction
|
||||||
|
|
||||||
function! FugitiveExtractGitDir(path) abort
|
function! FugitiveExtractGitDir(path) abort
|
||||||
if type(a:path) ==# type({})
|
if type(a:path) ==# type({})
|
||||||
return get(a:path, 'git_dir', '')
|
return get(a:path, 'git_dir', '')
|
||||||
@@ -427,20 +453,12 @@ function! FugitiveExtractGitDir(path) abort
|
|||||||
return s:dir_for_worktree[root]
|
return s:dir_for_worktree[root]
|
||||||
endif
|
endif
|
||||||
let dir = substitute(root, '[\/]$', '', '') . '/.git'
|
let dir = substitute(root, '[\/]$', '', '') . '/.git'
|
||||||
let type = getftype(dir)
|
let resolved = s:ResolveGitDir(dir)
|
||||||
if type ==# 'dir' && FugitiveIsGitDir(dir)
|
if !empty(resolved)
|
||||||
return dir
|
let s:resolved_git_dirs[dir] = resolved
|
||||||
elseif type ==# 'link' && FugitiveIsGitDir(dir)
|
return dir is# resolved || s:Tree(resolved) is# 0 ? dir : resolved
|
||||||
return resolve(dir)
|
|
||||||
elseif type !=# ''
|
|
||||||
let line = get(s:ReadFile(dir, 1), 0, '')
|
|
||||||
let file_dir = s:Slash(FugitiveVimPath(matchstr(line, '^gitdir: \zs.*')))
|
|
||||||
if file_dir !~# '^/\|^\a:\|^$' && FugitiveIsGitDir(root . '/' . file_dir)
|
|
||||||
return simplify(root . '/' . file_dir)
|
|
||||||
elseif len(file_dir) && FugitiveIsGitDir(file_dir)
|
|
||||||
return file_dir
|
|
||||||
endif
|
|
||||||
elseif FugitiveIsGitDir(root)
|
elseif FugitiveIsGitDir(root)
|
||||||
|
let s:resolved_git_dirs[root] = root
|
||||||
return root
|
return root
|
||||||
endif
|
endif
|
||||||
let previous = root
|
let previous = root
|
||||||
|
|||||||
Reference in New Issue
Block a user