From f0ae3fc65624901c2a75733605b60525242ea822 Mon Sep 17 00:00:00 2001 From: Oscar Wallberg Date: Fri, 29 May 2026 12:04:03 +0200 Subject: [PATCH] fix(status): open unmerged files from status view --- lua/git/status_view.lua | 5 +++ test/git/status_view_test.lua | 64 +++++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+) diff --git a/lua/git/status_view.lua b/lua/git/status_view.lua index 64d5838..5b14623 100644 --- a/lua/git/status_view.lua +++ b/lua/git/status_view.lua @@ -289,6 +289,11 @@ local function newer_pane(s, row) if row.section == "untracked" then return worktree_pane(s.repo, entry.path) end + if row.section == "unmerged" then + if vim.uv.fs_stat(vim.fs.joinpath(s.repo.worktree, entry.path)) then + return worktree_pane(s.repo, entry.path) + end + end return nil end diff --git a/test/git/status_view_test.lua b/test/git/status_view_test.lua index df5cd2e..77e5cd1 100644 --- a/test/git/status_view_test.lua +++ b/test/git/status_view_test.lua @@ -98,6 +98,46 @@ local function setup_sidebar_with_unstaged_file( return sidebar_win, entry_line end +---@param file_path string +---@return string repo +---@return integer sidebar_win +---@return integer entry_line +local function setup_sidebar_with_unmerged_file(file_path) + local repo = h.make_repo({ [file_path] = "base\n" }) + h.git(repo, "checkout", "-q", "-b", "side") + t.write(repo, file_path, "theirs\n") + h.git(repo, "commit", "-q", "-am", "side") + h.git(repo, "checkout", "-q", "main") + t.write(repo, file_path, "ours\n") + h.git(repo, "commit", "-q", "-am", "main") + local merge = vim.system({ "git", "merge", "side" }, { + cwd = repo, + text = true, + }):wait() + t.truthy(merge.code ~= 0, "merge should leave a conflict") + + vim.cmd("cd " .. repo) + require("git.status_view").open({ placement = "sidebar" }) + local sidebar_buf, sidebar_win = find_sidebar() + assert(sidebar_buf, "sidebar buffer should exist") + assert(sidebar_win, "sidebar window should exist") + + local r = assert( + require("git.core.repo").find(vim.fn.getcwd()), + "repo should resolve for the test worktree" + ) + r:refresh() + t.wait_for(function() + return r.status and #r.status:rows("unmerged") > 0 + end, "git status to report unmerged changes") + + local entry_line = assert( + find_line(sidebar_buf, vim.pesc(file_path) .. "$"), + file_path .. " should appear in sidebar" + ) + return repo, sidebar_win, entry_line +end + t.test("stage with diff open: sidebar cursor stays put", function() install_cursor_restore_autocmd() local sidebar_win, line = setup_sidebar_with_unstaged_file( @@ -128,6 +168,30 @@ t.test("stage with diff open: sidebar cursor stays put", function() ) end) +t.test( + " on an unmerged entry opens the conflicted worktree file", + function() + local repo, sidebar_win, line = + setup_sidebar_with_unmerged_file("foo.txt") + + vim.api.nvim_set_current_win(sidebar_win) + vim.api.nvim_win_set_cursor(sidebar_win, { line, 0 }) + t.press("") + t.wait_for(function() + return vim.api.nvim_buf_get_name(0) + == vim.fs.joinpath(repo, "foo.txt") + end, "conflicted worktree file to open") + + t.eq(vim.api.nvim_buf_get_lines(0, 0, -1, false), { + "<<<<<<< HEAD", + "ours", + "=======", + "theirs", + ">>>>>>> side", + }, "opened buffer should show conflict markers from the worktree") + end +) + t.test( "stage with diff open: diff foldmethod is preserved on refresh", function()