fix(git): keep index URI buffer in sync on save and reload

This commit is contained in:
2026-05-06 04:05:54 +02:00
parent 74bfd552f2
commit abb5434893
3 changed files with 19 additions and 20 deletions
+4 -5
View File
@@ -24,14 +24,13 @@ end
---@param right integer ---@param right integer
---@param vertical boolean ---@param vertical boolean
function M.open(left, right, vertical) function M.open(left, right, vertical)
local left_name = vim.api.nvim_buf_get_name(left)
vim.cmd.normal({ "m'", bang = true }) vim.cmd.normal({ "m'", bang = true })
vim.api.nvim_set_current_buf(right) vim.api.nvim_set_current_buf(right)
vim.cmd.diffsplit({ vim.cmd.diffthis()
args = { left_name }, vim.api.nvim_open_win(left, true, {
mods = { split = "aboveleft", vertical = vertical, keepjumps = true }, split = vertical and "left" or "above",
magic = { file = false },
}) })
vim.cmd.diffthis()
end end
---@param left_win integer ---@param left_win integer
+1 -1
View File
@@ -71,7 +71,7 @@ function M.init()
pattern = "git://*", pattern = "git://*",
group = group, group = group,
callback = function(args) callback = function(args)
require("git.object").read_uri(args.buf) require("git.object").read_uri(args.buf, { force = true })
end, end,
}) })
+14 -14
View File
@@ -108,9 +108,6 @@ local function attach_index_writer(buf, r, path)
state.index_mode = mode state.index_mode = mode
end end
end end
-- Use the 3-arg form (mode sha path) instead of the comma
-- form (mode,sha,path), which doesn't survive paths
-- containing a comma.
if if
not util.exec({ not util.exec({
"git", "git",
@@ -123,6 +120,9 @@ local function attach_index_writer(buf, r, path)
then then
return return
end end
if state then
state.sha = r:rev_parse(":" .. path, true)
end
vim.bo[buf].modified = false vim.bo[buf].modified = false
end, end,
}) })
@@ -146,7 +146,7 @@ end
function M.buf_for(r, rev, content) function M.buf_for(r, rev, content)
local buf = vim.fn.bufadd(M.format_uri(rev)) local buf = vim.fn.bufadd(M.format_uri(rev))
repo.bind(buf, r) repo.bind(buf, r)
if content then if content and not vim.api.nvim_buf_is_loaded(buf) then
local state = r:state(buf) --[[@as -nil]] local state = r:state(buf) --[[@as -nil]]
state.pending_content = content state.pending_content = content
end end
@@ -155,7 +155,9 @@ function M.buf_for(r, rev, content)
end end
---@param buf integer ---@param buf integer
function M.read_uri(buf) ---@param opts { force?: boolean }?
function M.read_uri(buf, opts)
opts = opts or {}
local name = vim.api.nvim_buf_get_name(buf) local name = vim.api.nvim_buf_get_name(buf)
local rev = M.parse_uri(name) local rev = M.parse_uri(name)
if not rev then if not rev then
@@ -177,13 +179,15 @@ function M.read_uri(buf)
---@type string? ---@type string?
local stdout = state.pending_content local stdout = state.pending_content
state.pending_content = nil state.pending_content = nil
-- On a refresh tick (no caller-provided content), skip the re-read
-- when the rev still resolves to the same sha. Avoids re-firing
-- BufReadPost (and the LSP/treesitter re-attach storm) on every
-- fs-event for buffers whose content can't have changed.
if stdout == nil then if stdout == nil then
local rev_sha = r:rev_parse(rev_str, true) local rev_sha = r:rev_parse(rev_str, true)
if not rev_sha or rev_sha == state.sha then if not rev_sha then
return
end
if
not opts.force
and (rev_sha == state.sha or vim.bo[buf].modified)
then
return return
end end
stdout = util.exec( stdout = util.exec(
@@ -231,10 +235,6 @@ function M.read_uri(buf)
end end
vim.bo[buf].modified = false vim.bo[buf].modified = false
-- Match on the inner path directly. `vim.filetype.add` patterns
-- don't work because Vim normalises `git://` filenames (cwd-prefix
-- + `://` -> `:/`) before matching, breaking any pattern keyed on
-- the raw scheme.
if rev.path then if rev.path then
local ft = vim.filetype.match({ filename = rev.path, buf = buf }) local ft = vim.filetype.match({ filename = rev.path, buf = buf })
if ft then if ft then