Skip to content

Commit

Permalink
fix(manager): manager.update() never resolve when buf_check() fails
Browse files Browse the repository at this point in the history
Problem: If `buf_check(...)` fails (mostly when cache is outdated), it
would abort updating gitsigns, but this actually leads to the coroutine
never resolving and stuck forever. It is because the asynchronous
callback `cb()` is never called.

As a result, gitsigns might be stuck forever and fail to update silently
(see #924), and manual reattach or refresh also doesn't work, because of
the unresolved coroutine that is recognized to be "still running", i.e.,
any subsequent calls to "throttled" `manager.update()` will not be
executed.

Solution: Make `buf_check()` always yield a value (true/false) to ensure
that `manager.update()` will resolve and finish its execution after all.
  • Loading branch information
wookayin authored and lewis6991 committed Dec 10, 2023
1 parent 017c924 commit 6e05045
Showing 1 changed file with 20 additions and 10 deletions.
30 changes: 20 additions & 10 deletions lua/gitsigns/manager.lua
Original file line number Diff line number Diff line change
Expand Up @@ -430,24 +430,24 @@ end

--- @param bufnr? integer
--- @param check_compare_text? boolean
--- @param cb function
--- @param cb fun(boolean)
M.buf_check = async.wrap(function(bufnr, check_compare_text, cb)
vim.schedule(function()
if bufnr then
if not api.nvim_buf_is_valid(bufnr) then
dprint('Buffer not valid, aborting')
return
return cb(false)
end
if not cache[bufnr] then
dprint('Has detached, aborting')
return
return cb(false)
end
if check_compare_text and not cache[bufnr].compare_text then
dprint('compare_text was invalid, aborting')
return
return cb(false)
end
end
cb()
cb(true)
end)
end, 3)

Expand All @@ -460,7 +460,9 @@ local update_cnt = 0
--- @param bufnr integer
M.update = throttle_by_id(function(bufnr)
local __FUNC__ = 'update'
M.buf_check(bufnr)
if not M.buf_check(bufnr) then
return
end
local bcache = cache[bufnr]
local old_hunks, old_hunks_staged = bcache.hunks, bcache.hunks_staged
bcache.hunks, bcache.hunks_staged = nil, nil
Expand All @@ -473,22 +475,30 @@ M.update = throttle_by_id(function(bufnr)

if not bcache.compare_text or config._refresh_staged_on_update or file_mode then
bcache.compare_text = git_obj:get_show_text(compare_rev)
M.buf_check(bufnr, true)
if not M.buf_check(bufnr, true) then
return
end
end

local buftext = util.buf_lines(bufnr)

bcache.hunks = run_diff(bcache.compare_text, buftext)
M.buf_check(bufnr)
if not M.buf_check(bufnr) then
return
end

if config._signs_staged_enable and not file_mode then
if not bcache.compare_text_head or config._refresh_staged_on_update then
local staged_compare_rev = bcache.commit and string.format('%s^', bcache.commit) or 'HEAD'
bcache.compare_text_head = git_obj:get_show_text(staged_compare_rev)
M.buf_check(bufnr, true)
if not M.buf_check(bufnr, true) then
return
end
end
local hunks_head = run_diff(bcache.compare_text_head, buftext)
M.buf_check(bufnr)
if not M.buf_check(bufnr) then
return
end
bcache.hunks_staged = gs_hunks.filter_common(hunks_head, bcache.hunks)
end

Expand Down

0 comments on commit 6e05045

Please sign in to comment.