mirror of
https://github.com/tpope/vim-fugitive.git
synced 2025-11-13 22:03:51 -05:00
Override GIT_INDEX_FILE when belonging to wrong repository
GIT_INDEX_FILE is typically set to index.lock when Vim is invoked by `git commit`. This effectively breaks Fugitive if you try to use it in a different repository while inside that Vim session. To remedy this, we can instead point GIT_INDEX_FILE at the index file for the relevant repository. This also retools command preparation to allow for general purpose environment variable overrides.
This commit is contained in:
@@ -410,6 +410,16 @@ function! s:PreparePathArgs(cmd, dir, literal) abort
|
|||||||
return a:cmd
|
return a:cmd
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
function! s:PrepareEnv(env, dir) abort
|
||||||
|
if len($GIT_INDEX_FILE) && len(s:Tree(a:dir)) && !has_key(a:env, 'GIT_INDEX_FILE')
|
||||||
|
let index_dir = substitute($GIT_INDEX_FILE, '[^/]\+$', '', '')
|
||||||
|
let our_dir = fugitive#Find('.git/', a:dir)
|
||||||
|
if !s:cpath(index_dir, our_dir) && !s:cpath(resolve(FugitiveVimPath(index_dir)), our_dir)
|
||||||
|
let a:env['GIT_INDEX_FILE'] = FugitiveGitPath(fugitive#Find('.git/index', a:dir))
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
let s:prepare_env = {
|
let s:prepare_env = {
|
||||||
\ 'sequence.editor': 'GIT_SEQUENCE_EDITOR',
|
\ 'sequence.editor': 'GIT_SEQUENCE_EDITOR',
|
||||||
\ 'core.editor': 'GIT_EDITOR',
|
\ 'core.editor': 'GIT_EDITOR',
|
||||||
@@ -426,6 +436,7 @@ function! fugitive#PrepareDirEnvGitFlagsArgs(...) abort
|
|||||||
if has_key(a:1, 'git')
|
if has_key(a:1, 'git')
|
||||||
let git = a:1.git
|
let git = a:1.git
|
||||||
endif
|
endif
|
||||||
|
let env = get(a:1, 'env', {})
|
||||||
else
|
else
|
||||||
let list_args = []
|
let list_args = []
|
||||||
let cmd = []
|
let cmd = []
|
||||||
@@ -437,8 +448,9 @@ function! fugitive#PrepareDirEnvGitFlagsArgs(...) abort
|
|||||||
endif
|
endif
|
||||||
endfor
|
endfor
|
||||||
call extend(cmd, list_args)
|
call extend(cmd, list_args)
|
||||||
endif
|
|
||||||
let env = {}
|
let env = {}
|
||||||
|
endif
|
||||||
|
let autoenv = {}
|
||||||
let i = 0
|
let i = 0
|
||||||
let arg_count = 0
|
let arg_count = 0
|
||||||
while i < len(cmd)
|
while i < len(cmd)
|
||||||
@@ -452,6 +464,9 @@ function! fugitive#PrepareDirEnvGitFlagsArgs(...) abort
|
|||||||
if has_key(cmd[i], 'git')
|
if has_key(cmd[i], 'git')
|
||||||
let git = cmd[i].git
|
let git = cmd[i].git
|
||||||
endif
|
endif
|
||||||
|
if has_key(cmd[i], 'env')
|
||||||
|
call extend(env, cmd[i].env)
|
||||||
|
endif
|
||||||
call remove(cmd, i)
|
call remove(cmd, i)
|
||||||
elseif cmd[i] =~# '^$\|[\/.]' && cmd[i] !~# '^-'
|
elseif cmd[i] =~# '^$\|[\/.]' && cmd[i] !~# '^-'
|
||||||
let dir = remove(cmd, i)
|
let dir = remove(cmd, i)
|
||||||
@@ -461,16 +476,12 @@ function! fugitive#PrepareDirEnvGitFlagsArgs(...) abort
|
|||||||
let dir = s:Dir(remove(cmd, i))
|
let dir = s:Dir(remove(cmd, i))
|
||||||
elseif cmd[i] ==# '-c' && len(cmd) > i + 1
|
elseif cmd[i] ==# '-c' && len(cmd) > i + 1
|
||||||
let key = matchstr(cmd[i+1], '^[^=]*')
|
let key = matchstr(cmd[i+1], '^[^=]*')
|
||||||
if has_key(s:prepare_env, tolower(key)) || key !~# '\.'
|
if has_key(s:prepare_env, tolower(key))
|
||||||
let var = get(s:prepare_env, tolower(key), key)
|
let var = s:prepare_env[tolower(key)]
|
||||||
let val = matchstr(cmd[i+1], '=\zs.*')
|
let val = matchstr(cmd[i+1], '=\zs.*')
|
||||||
let env[var] = val
|
let autoenv[var] = val
|
||||||
endif
|
endif
|
||||||
if cmd[i+1] =~# '\.'
|
|
||||||
let i += 2
|
let i += 2
|
||||||
else
|
|
||||||
call remove(cmd, i, i + 1)
|
|
||||||
endif
|
|
||||||
elseif cmd[i] =~# '^--.*pathspecs$'
|
elseif cmd[i] =~# '^--.*pathspecs$'
|
||||||
let explicit_pathspec_option = 1
|
let explicit_pathspec_option = 1
|
||||||
let i += 1
|
let i += 1
|
||||||
@@ -484,8 +495,11 @@ function! fugitive#PrepareDirEnvGitFlagsArgs(...) abort
|
|||||||
if !exists('dir')
|
if !exists('dir')
|
||||||
let dir = s:Dir()
|
let dir = s:Dir()
|
||||||
endif
|
endif
|
||||||
|
if !has_key(env, 'GIT_INDEX_FILE')
|
||||||
|
call s:PrepareEnv(autoenv, dir)
|
||||||
|
endif
|
||||||
call s:PreparePathArgs(cmd, dir, !exists('explicit_pathspec_option'))
|
call s:PreparePathArgs(cmd, dir, !exists('explicit_pathspec_option'))
|
||||||
return [dir, env, git, cmd[0 : -arg_count-1], arg_count ? cmd[-arg_count : -1] : []]
|
return [dir, env, extend(autoenv, env), git, cmd[0 : -arg_count-1], arg_count ? cmd[-arg_count : -1] : []]
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:BuildEnvPrefix(env) abort
|
function! s:BuildEnvPrefix(env) abort
|
||||||
@@ -522,8 +536,11 @@ function! s:JobOpts(cmd, env) abort
|
|||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:PrepareJob(...) abort
|
function! s:PrepareJob(...) abort
|
||||||
let [dir, env, git, flags, args] = call('fugitive#PrepareDirEnvGitFlagsArgs', a:000)
|
let [dir, user_env, exec_env, git, flags, args] = call('fugitive#PrepareDirEnvGitFlagsArgs', a:000)
|
||||||
let dict = {'git': git, 'git_dir': dir, 'flags': flags, 'args': args}
|
let dict = {'git': git, 'git_dir': dir, 'flags': flags, 'args': args}
|
||||||
|
if len(user_env)
|
||||||
|
let dict.env = user_env
|
||||||
|
endif
|
||||||
let cmd = flags + args
|
let cmd = flags + args
|
||||||
let tree = s:Tree(dir)
|
let tree = s:Tree(dir)
|
||||||
if empty(tree) || index(cmd, '--') == len(cmd) - 1
|
if empty(tree) || index(cmd, '--') == len(cmd) - 1
|
||||||
@@ -531,7 +548,7 @@ function! s:PrepareJob(...) abort
|
|||||||
else
|
else
|
||||||
call extend(cmd, git + ['-C', FugitiveGitPath(tree)], 'keep')
|
call extend(cmd, git + ['-C', FugitiveGitPath(tree)], 'keep')
|
||||||
endif
|
endif
|
||||||
return s:JobOpts(cmd, env) + [dict]
|
return s:JobOpts(cmd, exec_env) + [dict]
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:BuildShell(dir, env, git, args) abort
|
function! s:BuildShell(dir, env, git, args) abort
|
||||||
@@ -547,7 +564,7 @@ function! s:BuildShell(dir, env, git, args) abort
|
|||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! fugitive#ShellCommand(...) abort
|
function! fugitive#ShellCommand(...) abort
|
||||||
let [dir, env, git, flags, args] = call('fugitive#PrepareDirEnvGitFlagsArgs', a:000)
|
let [dir, _, env, git, flags, args] = call('fugitive#PrepareDirEnvGitFlagsArgs', a:000)
|
||||||
return s:BuildShell(dir, env, git, flags + args)
|
return s:BuildShell(dir, env, git, flags + args)
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
@@ -1368,9 +1385,15 @@ function! fugitive#Find(object, ...) abort
|
|||||||
elseif rev =~# '^:[0-3]:'
|
elseif rev =~# '^:[0-3]:'
|
||||||
let f = 'fugitive://' . dir . '//' . rev[1] . '/' . rev[3:-1]
|
let f = 'fugitive://' . dir . '//' . rev[1] . '/' . rev[3:-1]
|
||||||
elseif rev ==# ':'
|
elseif rev ==# ':'
|
||||||
let f = FugitiveFind('.git/index', dir)
|
let fdir = dir . '/'
|
||||||
if $GIT_INDEX_FILE =~# '/[^/]*index[^/]*\.lock$' && s:cpath(fnamemodify($GIT_INDEX_FILE,':p')[0:strlen(f)-6], s:cpath(f[0 : -6])) && filereadable($GIT_INDEX_FILE)
|
let f = fdir . 'index'
|
||||||
let f = fnamemodify($GIT_INDEX_FILE, ':p')
|
if len($GIT_INDEX_FILE)
|
||||||
|
let index_dir = substitute($GIT_INDEX_FILE, '[^/]\+$', '', '')
|
||||||
|
if s:cpath(index_dir, fdir)
|
||||||
|
let f = FugitiveVimPath($GIT_INDEX_FILE)
|
||||||
|
elseif s:cpath(resolve(FugitiveVimPath(index_dir)), fdir)
|
||||||
|
let f = resolve(FugitiveVimPath($GIT_INDEX_FILE))
|
||||||
|
endif
|
||||||
endif
|
endif
|
||||||
elseif rev =~# '^:(\%(top\|top,literal\|literal,top\|literal\))'
|
elseif rev =~# '^:(\%(top\|top,literal\|literal,top\|literal\))'
|
||||||
let f = matchstr(rev, ')\zs.*')
|
let f = matchstr(rev, ')\zs.*')
|
||||||
@@ -2144,8 +2167,8 @@ function! fugitive#BufReadStatus() abort
|
|||||||
|
|
||||||
let cmd = [fnamemodify(amatch, ':h')]
|
let cmd = [fnamemodify(amatch, ':h')]
|
||||||
setlocal noro ma nomodeline buftype=nowrite
|
setlocal noro ma nomodeline buftype=nowrite
|
||||||
if s:cpath(fnamemodify($GIT_INDEX_FILE !=# '' ? $GIT_INDEX_FILE : fugitive#Find('.git/index'), ':p')) !=# s:cpath(amatch)
|
if s:cpath(fnamemodify($GIT_INDEX_FILE !=# '' ? FugitiveVimPath($GIT_INDEX_FILE) : fugitive#Find('.git/index'), ':p')) !=# s:cpath(amatch)
|
||||||
let cmd += ['-c', 'GIT_INDEX_FILE=' . amatch]
|
let cmd += [{'env': {'GIT_INDEX_FILE': FugitiveGitPath(amatch)}}]
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if fugitive#GitVersion(2, 15)
|
if fugitive#GitVersion(2, 15)
|
||||||
@@ -3159,6 +3182,7 @@ function! fugitive#Command(line1, line2, range, bang, mods, arg) abort
|
|||||||
endif
|
endif
|
||||||
let i += 1
|
let i += 1
|
||||||
endwhile
|
endwhile
|
||||||
|
call s:PrepareEnv(env, dir)
|
||||||
let editcmd = a:line2 ? 'split' : 'edit'
|
let editcmd = a:line2 ? 'split' : 'edit'
|
||||||
if pager is# 1
|
if pager is# 1
|
||||||
if a:bang && a:line2 >= 0
|
if a:bang && a:line2 >= 0
|
||||||
|
|||||||
Reference in New Issue
Block a user