Treat changed remotes as new plugins

If one had this plugin:

Plugin 'foo/bar'

And now switches to another one with the same name:

Plugin 'baz/bar'

Recognise this scenario and replace the old plugin with the new one,
rather than silently assuming they are the same.

Fixes #367 #48 #183 #400
This commit is contained in:
Jacobo de Vera 2014-04-03 08:25:29 +02:00
parent e7660d50f3
commit 53cb1215f6

View File

@ -3,7 +3,7 @@
" to g:bundle_dir. If a:bang is 1 it will also update all plugins (git pull). " to g:bundle_dir. If a:bang is 1 it will also update all plugins (git pull).
" "
" bang -- 1 or 0 " bang -- 1 or 0
" ... -- any number of bundle specifications (seperate arguments) " ... -- any number of bundle specifications (separate arguments)
" --------------------------------------------------------------------------- " ---------------------------------------------------------------------------
func! vundle#installer#new(bang, ...) abort func! vundle#installer#new(bang, ...) abort
let bundles = (a:1 == '') ? let bundles = (a:1 == '') ?
@ -323,27 +323,67 @@ endf
" --------------------------------------------------------------------------- " ---------------------------------------------------------------------------
" Install or update a given bundle object with git. " Get the URL for the remote called 'origin' on the repository that
" corresponds to a given bundle.
"
" bundle -- a bundle object to check the repository for
" 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 = g:shellesc_cd(cmd)
let out = s:strip(s:system(cmd))
return out
endf
" ---------------------------------------------------------------------------
" Create the appropriate sync command to run according to the current state of
" the local repository (clone, pull, reset, etc).
"
" In the case of a pull (update), also return the current sha, so that we can
" later check that there has been an upgrade.
" "
" bang -- 0 if only new plugins should be installed, 1 if existing plugins " bang -- 0 if only new plugins should be installed, 1 if existing plugins
" should be updated " should be updated
" bundle -- a bundle object (dict) " bundle -- a bundle object to create the sync command for
" return -- 'todate' if nothing was updated or the repository was up to date, " return -- A list containing the command to run and the sha for the current
" 'new' when the plugin was newly installed, 'updated' if some " HEAD
" changes where pulled via git, 'error' if an error occurred in the
" shell command
" --------------------------------------------------------------------------- " ---------------------------------------------------------------------------
func! s:sync(bang, bundle) abort func! s:make_sync_command(bang, bundle) abort
" Do not sync if this bundle is pinned
if a:bundle.is_pinned()
return 'pinned'
endif
let git_dir = expand(a:bundle.path().'/.git/', 1) let git_dir = expand(a:bundle.path().'/.git/', 1)
if isdirectory(git_dir) || filereadable(expand(a:bundle.path().'/.git', 1)) if isdirectory(git_dir) || filereadable(expand(a:bundle.path().'/.git', 1))
if !(a:bang) | return 'todate' | endif
let cmd = 'cd '.vundle#installer#shellesc(a:bundle.path()).' && git pull && git submodule update --init --recursive'
let current_origin_url = s:get_current_origin_url(a:bundle)
if current_origin_url != a:bundle.uri
call s:log('Plugin URI change detected for Plugin ' . a:bundle.name)
call s:log('> Plugin ' . a:bundle.name . ' old URI: ' . current_origin_url)
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',
\ ]
let cmd = join(cmd_parts, ' && ')
let cmd = g:shellesc_cd(cmd)
let initial_sha = ''
return [cmd, initial_sha]
endif
if !(a:bang)
" The repo exists, and no !, so leave as it is.
return ['', '']
endif
let cmd_parts = [
\ 'cd '.vundle#installer#shellesc(a:bundle.path()),
\ 'git pull',
\ 'git submodule update --init --recursive',
\ ]
let cmd = join(cmd_parts, ' && ')
let cmd = g:shellesc_cd(cmd) let cmd = g:shellesc_cd(cmd)
let get_current_sha = 'cd '.vundle#installer#shellesc(a:bundle.path()).' && git rev-parse HEAD' let get_current_sha = 'cd '.vundle#installer#shellesc(a:bundle.path()).' && git rev-parse HEAD'
@ -353,6 +393,33 @@ func! s:sync(bang, bundle) abort
let cmd = 'git clone --recursive '.vundle#installer#shellesc(a:bundle.uri).' '.vundle#installer#shellesc(a:bundle.path()) let cmd = 'git clone --recursive '.vundle#installer#shellesc(a:bundle.uri).' '.vundle#installer#shellesc(a:bundle.path())
let initial_sha = '' let initial_sha = ''
endif endif
return [cmd, initial_sha]
endf
" ---------------------------------------------------------------------------
" Install or update a given bundle object with git.
"
" bang -- 0 if only new plugins should be installed, 1 if existing plugins
" should be updated
" bundle -- a bundle object (dictionary)
" return -- a string indicating the status of the bundle installation:
" - todate : Nothing was updated or the repository was up to date
" - new : The plugin was newly installed
" - updated : Some changes where pulled via git
" - error : An error occurred in the shell command
" - pinned : The bundle is marked as pinned
" ---------------------------------------------------------------------------
func! s:sync(bang, bundle) abort
" Do not sync if this bundle is pinned
if a:bundle.is_pinned()
return 'pinned'
endif
let [ cmd, initial_sha ] = s:make_sync_command(a:bang, a:bundle)
if empty(cmd)
return 'todate'
endif
let out = s:system(cmd) let out = s:system(cmd)
call s:log('') call s:log('')
@ -427,7 +494,7 @@ endf
" Add a log message to Vundle's internal logging variable. " Add a log message to Vundle's internal logging variable.
" "
" str -- the log message (string) " str -- the log message (string)
" prefix -- optional prefix for multiline entries (string) " prefix -- optional prefix for multi-line entries (string)
" return -- a:str " return -- a:str
" --------------------------------------------------------------------------- " ---------------------------------------------------------------------------
func! s:log(str, ...) abort func! s:log(str, ...) abort
@ -441,4 +508,15 @@ func! s:log(str, ...) abort
return a:str return a:str
endf endf
" ---------------------------------------------------------------------------
" Remove leading and trailing whitespace from a string
"
" str -- The string to rid of trailing and leading spaces
" return -- A string stripped of side spaces
" ---------------------------------------------------------------------------
func! s:strip(str)
return substitute(a:str, '\%^\_s*\(.\{-}\)\_s*\%$', '\1', '')
endf
" vim: set expandtab sts=2 ts=2 sw=2 tw=78 norl: " vim: set expandtab sts=2 ts=2 sw=2 tw=78 norl: