Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,17 @@ All notable changes to the Vim Plugin Manager will be documented in this file.
startup check re-fetches (TTL skipped). It was previously accepted
but ignored.

### Fixed
- Update no longer reports "Fetch failed" when an upstream tag moved: the
update fetch is `git fetch --tags --force origin`, so a tag-clobber
rejection (local tag object differing from the remote one) refreshes
the tag mirror instead of failing the whole fetch - branch refs were
already updating successfully in that case. Local tags in a plugin
submodule are mirrors of upstream, never local creations, so the
forced refresh matches the pull trust level. Diagnosed on a real
setup: 12 stale v1.x/v2.1.x tag mirrors were poisoning every update
of the affected module.

### Removed
- Dead code: never-read async job state fields (`id`, `started`,
`queued`), the unused `g:plugin_manager_periodic_timer` write, four
Expand Down
4 changes: 2 additions & 2 deletions autoload/plugin_manager/cmd/update.vim
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ function! s:update_specific_plugin_async(ctx) abort

" Step 1: Fetch first, stash only if a pull turns out to be needed
call plugin_manager#ui#update_operation(l:op_id, 'Fetching updates')
call plugin_manager#async#git('git -C ' . shellescape(a:ctx.module_path) . ' fetch --tags origin', {
call plugin_manager#async#git('git -C ' . shellescape(a:ctx.module_path) . ' fetch --tags --force origin', {
\ 'callback': function('s:on_fetch_complete', [a:ctx])
\ })
endfunction
Expand Down Expand Up @@ -385,7 +385,7 @@ function! s:update_all_plugins_async(ctx) abort
for l:module in a:ctx.valid_modules
let l:module_path = get(l:module, 'abs_path', l:module.path)
call plugin_manager#async#git(
\ 'git -C ' . shellescape(l:module_path) . ' fetch --tags origin', {
\ 'git -C ' . shellescape(l:module_path) . ' fetch --tags --force origin', {
\ 'callback': function('s:on_module_fetched', [a:ctx, l:module])
\ })
endfor
Expand Down
25 changes: 25 additions & 0 deletions tests/update.vader
Original file line number Diff line number Diff line change
Expand Up @@ -326,3 +326,28 @@ Execute (custom-branch module is skipped with the exact skip message):
call system('git -C ' . shellescape(g:_pm_upd_plug) . ' checkout -q main')
call system('git -C ' . shellescape(g:_pm_upd_plug) . ' branch -D dev')
unlet g:_pm_upd_sb

Execute (a moved upstream tag does not fail the fetch):
" Upstream tags can move (re-annotated). The module's local tag copy is
" a mirror, never a local creation: git fetch --tags --force must refresh
" it instead of failing the whole fetch (branch refs update regardless;
" a plain tag rejection must not mark the module as failed).
call system('git -C ' . shellescape(g:_pm_upd_tmp_src) . ' tag -a v9.9.9 -m rel')
call system('git -C ' . shellescape(g:_pm_upd_tmp_src) . ' push -q origin v9.9.9')
" Local tag with a DIFFERENT tag-object SHA than the remote one.
call system('git -C ' . shellescape(g:_pm_upd_plug) . ' tag -a v9.9.9 -m local')
call plugin_manager#cmd#dispatch('update')
let g:_pm_upd_sb = join(getbufline(bufnr('PluginManager'), 1, '$'), "\n")
Assert g:_pm_upd_sb !~# 'Fetch failed',
\ 'a tag clobber rejection must not fail the fetch, got: ' . g:_pm_upd_sb
" The local tag mirror is refreshed to the remote tag object.
let g:_pm_upd_local_tag = substitute(
\ system('git -C ' . shellescape(g:_pm_upd_plug) . ' show-ref --tags v9.9.9'),
\ '\n', '', 'g')
let g:_pm_upd_remote_tag = substitute(
\ system('git -C ' . shellescape(g:_pm_upd_tmp_src) . ' show-ref --tags v9.9.9'),
\ '\n', '', 'g')
Assert g:_pm_upd_local_tag ==# g:_pm_upd_remote_tag,
\ 'tag must be refreshed to the remote object, got: '
\ . g:_pm_upd_local_tag . ' vs ' . g:_pm_upd_remote_tag
unlet g:_pm_upd_sb g:_pm_upd_local_tag g:_pm_upd_remote_tag
Loading