From b5bc56c31851f313da65a7a04fa9e1b9aa51bc4f Mon Sep 17 00:00:00 2001 From: Rob Cornish Date: Sun, 28 Sep 2014 18:26:34 +1000 Subject: [PATCH] Made git commands work despite values of `GIT_DIR` and `GIT_WORK_TREE` The previous method for interacting with a bundle via git involved cd'ing into the bundle directory then running the relevant git commands. The problem with this approach is that if the environmental variables `GIT_DIR` and `GIT_WORK_TREE` are set at this point then git will preference their values over those implied by the current directory. (This can cause trouble for vcsh users, for example.) This patch uses the git arguments `-C`, `--git-dir`, and `--work-tree` to specify the location of the bundle explicitly. This overcomes the original problem since git gives these values precedence over `GIT_DIR` and `GIT_WORK_TREE`. --- autoload/vundle/installer.vim | 51 +++++++++++++++-------------------- autoload/vundle/scripts.vim | 7 ++--- 2 files changed, 23 insertions(+), 35 deletions(-) diff --git a/autoload/vundle/installer.vim b/autoload/vundle/installer.vim index 614b64b..5f9e2c1 100644 --- a/autoload/vundle/installer.vim +++ b/autoload/vundle/installer.vim @@ -321,6 +321,19 @@ func! s:helptags(rtp) abort return 1 endf +" --------------------------------------------------------------------------- +" Expand a git command relative to a specified bundle, so that it can be +" executed as a system command. +" +" bundle -- the bundle object to run the git command relative to +" cmd -- the git command (e.g. 'ls-files') +" return -- the fully expanded system command (string) +" --------------------------------------------------------------------------- +func! vundle#installer#expand_git_cmd(bundle, cmd) abort + let out = 'git -C '.vundle#installer#shellesc(a:bundle.path()).' --git-dir=.git/ --work-tree=. '.a:cmd + return out +endf + " --------------------------------------------------------------------------- " Get the URL for the remote called 'origin' on the repository that @@ -330,8 +343,7 @@ endf " return -- the URL for the origin remote (string) " --------------------------------------------------------------------------- func! s:get_current_origin_url(bundle) abort - let cmd = 'cd '.vundle#installer#shellesc(a:bundle.path()).' && git config --get remote.origin.url' - let cmd = vundle#installer#shellesc_cd(cmd) + let cmd = vundle#installer#expand_git_cmd(a:bundle, 'config --get remote.origin.url') let out = s:strip(s:system(cmd)) return out endf @@ -344,8 +356,7 @@ endf " return -- A 15 character log sha for the current HEAD " --------------------------------------------------------------------------- func! s:get_current_sha(bundle) - let cmd = 'cd '.vundle#installer#shellesc(a:bundle.path()).' && git rev-parse HEAD' - let cmd = vundle#installer#shellesc_cd(cmd) + let cmd = vundle#installer#expand_git_cmd(a:bundle, 'rev-parse HEAD') let out = s:system(cmd)[0:15] return out endf @@ -375,14 +386,12 @@ func! s:make_sync_command(bang, bundle) abort call s:log('> Plugin ' . a:bundle.name . ' new URI: ' . a:bundle.uri) " Directory names match but the origin remotes are not the same let cmd_parts = [ - \ 'cd '.vundle#installer#shellesc(a:bundle.path()) , - \ 'git remote set-url origin ' . vundle#installer#shellesc(a:bundle.uri), - \ 'git fetch', - \ 'git reset --hard origin/HEAD', - \ 'git submodule update --init --recursive', + \ vundle#installer#expand_git_cmd(a:bundle, 'remote set-url origin ' . vundle#installer#shellesc(a:bundle.uri)), + \ vundle#installer#expand_git_cmd(a:bundle, 'fetch'), + \ vundle#installer#expand_git_cmd(a:bundle, 'reset --hard origin/HEAD'), + \ vundle#installer#expand_git_cmd(a:bundle, 'submodule update --init --recursive') \ ] let cmd = join(cmd_parts, ' && ') - let cmd = vundle#installer#shellesc_cd(cmd) let initial_sha = '' return [cmd, initial_sha] endif @@ -393,12 +402,10 @@ func! s:make_sync_command(bang, bundle) abort endif let cmd_parts = [ - \ 'cd '.vundle#installer#shellesc(a:bundle.path()), - \ 'git pull', - \ 'git submodule update --init --recursive', + \ vundle#installer#expand_git_cmd(a:bundle, 'pull'), + \ vundle#installer#expand_git_cmd(a:bundle, 'submodule update --init --recursive'), \ ] let cmd = join(cmd_parts, ' && ') - let cmd = vundle#installer#shellesc_cd(cmd) let initial_sha = s:get_current_sha(a:bundle) else @@ -473,22 +480,6 @@ func! vundle#installer#shellesc(cmd) abort endf -" --------------------------------------------------------------------------- -" Fix a cd shell command to be used on Windows. -" -" cmd -- the command to be fixed (string) -" return -- the fixed command (string) -" --------------------------------------------------------------------------- -func! vundle#installer#shellesc_cd(cmd) abort - if ((has('win32') || has('win64')) && empty(matchstr(&shell, 'sh'))) - let cmd = substitute(a:cmd, '^cd ','cd /d ','') " add /d switch to change drives - return cmd - else - return a:cmd - endif -endf - - " --------------------------------------------------------------------------- " Make a system call. This can be used to change the way system calls " are made during developing, without searching the whole code base for diff --git a/autoload/vundle/scripts.vim b/autoload/vundle/scripts.vim index d7409a1..8eea823 100644 --- a/autoload/vundle/scripts.vim +++ b/autoload/vundle/scripts.vim @@ -68,11 +68,8 @@ func! s:create_changelog() abort let updated_sha = bundle_data[1] let bundle = bundle_data[2] - let cmd = 'cd '.vundle#installer#shellesc(bundle.path()). - \ ' && git log --pretty=format:"%s %an, %ar" --graph '. - \ initial_sha.'..'.updated_sha - - let cmd = vundle#installer#shellesc_cd(cmd) + let cmd = vundle#installer#expand_git_cmd(bundle, + \ 'log --pretty=format:"%s %an, %ar" --graph '.initial_sha.'..'.updated_sha) let updates = system(cmd)