Skip to content

Commit

Permalink
Pull upstream force-pushed Git tags
Browse files Browse the repository at this point in the history
Resolves wbthomason#1100. Pull upstream tags even if they
were force-pushed. Git version 2.20 changed the behavior
of fetching tags so that non-fast-forward updates would fail.
Some plugin authors, like `nvim-tree/nvim-tree.lua` use a
tag named `nightly` that is force-pushed with latest updates
to provide bleeding-edge changes.

By adding an explicit refspec to the `git fetch` command
line with a leading plus-sign ('+') Git will always update
the tag to the new commit, regardless of whether it was
force-pushed upstream.

See https://www.git-scm.com/docs/git-fetch#Documentation/git-fetch.txt-ltrefspecgt
for details (paragraph beginning "Until Git version 2.20...").
  • Loading branch information
overhacked committed Dec 15, 2022
1 parent 64ae65f commit 48f1216
Showing 1 changed file with 13 additions and 3 deletions.
16 changes: 13 additions & 3 deletions lua/packer/plugin_types/git.lua
Original file line number Diff line number Diff line change
Expand Up @@ -380,8 +380,18 @@ git.setup = function(plugin)
options = { env = git.job_env },
}

-- If a tag is specified, name its refspec on the update
-- or fetch command line with a leading plus-sign ('+') to ensure that
-- upstream commits are pull/fetch-ed even if upstream force-pushed.
-- Not needed for branches, because in that case pulling force-pushed
-- commits is the default.
local explicit_refspec = ''
if plugin.tag then
explicit_refspec = fmt(' origin +refs/tags/%s', plugin.tag)
end

if needs_checkout then
r:and_then(await, jobs.run(config.exec_cmd .. config.subcommands.fetch, update_opts))
r:and_then(await, jobs.run(fetch_cmd .. explicit_refspec, update_opts))
r:and_then(await, handle_checkouts(plugin, install_to, disp, opts))
local function merge_output(res)
if res.output ~= nil then
Expand All @@ -406,13 +416,13 @@ git.setup = function(plugin)

if opts.preview_updates then
disp:task_update(plugin_name, 'fetching updates...')
r:and_then(await, jobs.run(fetch_cmd, update_opts))
r:and_then(await, jobs.run(fetch_cmd .. explicit_refspec, update_opts))
elseif opts.pull_head then
disp:task_update(plugin_name, 'pulling updates from head...')
r:and_then(await, jobs.run(update_head_cmd, update_opts))
else
disp:task_update(plugin_name, 'pulling updates...')
r:and_then(await, jobs.run(update_cmd, update_opts)):and_then(await, jobs.run(submodule_cmd, update_opts))
r:and_then(await, jobs.run(update_cmd .. explicit_refspec, update_opts)):and_then(await, jobs.run(submodule_cmd, update_opts))
end
r:map_err(function(err)
plugin.output = { err = vim.list_extend(update_info.err, update_info.output), data = {} }
Expand Down

0 comments on commit 48f1216

Please sign in to comment.