Skip to content

Commit d36effe

Browse files
committed
fix: adjust jj adapter integration for safety
Reorder adapter probing so GitAdapter is tried before JjAdapter, avoiding unnecessary `jj root` calls in plain git repos. Revert generic file.lua changes (bufload/checktime, is_loaded→is_valid) and replace them with a jj-specific on_local_buffer_reused() hook, so existing Git/Hg behaviour is unchanged.
1 parent c457419 commit d36effe

5 files changed

Lines changed: 55 additions & 15 deletions

File tree

lua/diffview/tests/functional/jj_adapter_spec.lua

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,32 @@ describe("diffview.vcs.adapters.jj", function()
160160
end)
161161
end)
162162

163+
describe("on_local_buffer_reused()", function()
164+
it("calls checktime on an unmodified buffer", function()
165+
local adapter = new_adapter()
166+
local bufnr = vim.api.nvim_create_buf(true, false)
167+
168+
-- checktime requires a file on disk; write a temp file so the buffer
169+
-- has a real name and checktime doesn't error.
170+
local tmpfile = vim.fn.tempname()
171+
vim.fn.writefile({ "hello" }, tmpfile)
172+
vim.api.nvim_buf_set_name(bufnr, tmpfile)
173+
vim.fn.bufload(bufnr)
174+
175+
-- Should not error.
176+
assert.has_no.errors(function()
177+
adapter:on_local_buffer_reused(bufnr)
178+
end)
179+
180+
-- Buffer should still be loaded and valid.
181+
assert.is_true(vim.api.nvim_buf_is_valid(bufnr))
182+
assert.is_true(vim.api.nvim_buf_is_loaded(bufnr))
183+
184+
pcall(vim.api.nvim_buf_delete, bufnr, { force = true })
185+
vim.fn.delete(tmpfile)
186+
end)
187+
end)
188+
163189
describe("rev_to_args()", function()
164190
it("returns --from/--to for commit ranges", function()
165191
local adapter = new_adapter()

lua/diffview/vcs/adapter.lua

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,14 @@ function VCSAdapter:force_entry_refresh_on_noop(left, right)
272272
return false
273273
end
274274

275+
---Called when `_create_local_buffer` reuses an existing buffer. Adapters
276+
---whose VCS rewrites working-copy files (e.g. jj) should override this to
277+
---ensure the buffer content reflects the current state on disk.
278+
---@param bufnr integer
279+
function VCSAdapter:on_local_buffer_reused(bufnr)
280+
-- Default: no-op. Git and Hg do not rewrite working-copy files.
281+
end
282+
275283
---Restore a file to the requested state
276284
---@param path string # file to restore
277285
---@param kind '"staged"'|'"working"'

lua/diffview/vcs/adapters/jj/init.lua

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -434,6 +434,21 @@ function JjAdapter:force_entry_refresh_on_noop(left, right)
434434
return self:has_local(left, right)
435435
end
436436

437+
---Jj may rewrite working-copy files when revisions change, so reload the
438+
---buffer from disk when it is reused.
439+
---@param bufnr integer
440+
function JjAdapter:on_local_buffer_reused(bufnr)
441+
local api = vim.api
442+
443+
if not api.nvim_buf_is_loaded(bufnr) then
444+
vim.fn.bufload(bufnr)
445+
end
446+
447+
if not vim.bo[bufnr].modified then
448+
pcall(vim.cmd, ("checktime %d"):format(bufnr))
449+
end
450+
end
451+
437452
---@param left Rev
438453
---@param right Rev
439454
---@return string[]

lua/diffview/vcs/file.lua

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -182,15 +182,8 @@ function File:_create_local_buffer()
182182
else
183183
-- NOTE: LSP servers might load buffers in the background and unlist
184184
-- them. Explicitly set the buffer as listed when loading it here.
185-
if not api.nvim_buf_is_loaded(self.bufnr) then
186-
vim.fn.bufload(self.bufnr)
187-
end
188-
189-
if not vim.bo[self.bufnr].modified then
190-
pcall(vim.cmd, ("checktime %d"):format(self.bufnr))
191-
end
192-
193185
vim.bo[self.bufnr].buflisted = true
186+
self.adapter:on_local_buffer_reused(self.bufnr)
194187
end
195188

196189
self:post_buf_created()
@@ -508,7 +501,7 @@ function File:detach_buffer()
508501
end
509502

510503
function File:dispose_buffer()
511-
if self.bufnr and api.nvim_buf_is_valid(self.bufnr) then
504+
if self.bufnr and api.nvim_buf_is_loaded(self.bufnr) then
512505
self:detach_buffer()
513506

514507
if not lib.is_buf_in_use(self.bufnr, { self }) then
@@ -520,14 +513,12 @@ function File:dispose_buffer()
520513
end
521514

522515
function File.safe_delete_buf(bufnr)
523-
if not bufnr or bufnr == File.NULL_FILE.bufnr or not api.nvim_buf_is_valid(bufnr) then
516+
if not bufnr or bufnr == File.NULL_FILE.bufnr or not api.nvim_buf_is_loaded(bufnr) then
524517
return
525518
end
526519

527-
if api.nvim_buf_is_loaded(bufnr) then
528-
for _, winid in ipairs(utils.win_find_buf(bufnr, 0)) do
529-
File.load_null_buffer(winid)
530-
end
520+
for _, winid in ipairs(utils.win_find_buf(bufnr, 0)) do
521+
File.load_null_buffer(winid)
531522
end
532523

533524
pcall(api.nvim_buf_delete, bufnr, { force = true })

lua/diffview/vcs/init.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ local M = {}
1717
---@return string? err
1818
---@return VCSAdapter? adapter
1919
function M.get_adapter(opt)
20-
local adapter_kinds = { JjAdapter, GitAdapter, HgAdapter, P4Adapter }
20+
local adapter_kinds = { GitAdapter, JjAdapter, HgAdapter, P4Adapter }
2121

2222
if not opt.cmd_ctx then
2323
opt.cmd_ctx = {}

0 commit comments

Comments
 (0)