Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 9 additions & 5 deletions lua/diffview/scene/views/diff/file_dir_diff_view.lua
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
local lazy = require("diffview.lazy")
local oop = require("diffview.oop")

local Diff2Hor = lazy.access("diffview.scene.layouts.diff_2_hor", "Diff2Hor") ---@type Diff2Hor|LazyModule
local Diff3Hor = lazy.access("diffview.scene.layouts.diff_3_hor", "Diff3Hor") ---@type Diff3Hor|LazyModule
local Diff4Mixed = lazy.access("diffview.scene.layouts.diff_4_mixed", "Diff4Mixed") ---@type Diff4Mixed|LazyModule
local File = lazy.access("diffview.vcs.file", "File") ---@type vcs.File|LazyModule
local FileEntry = lazy.access("diffview.scene.file_entry", "FileEntry") ---@type FileEntry|LazyModule
local NullDiffView = lazy.access("diffview.scene.views.diff.null_diff_view", "NullDiffView") ---@type NullDiffView|LazyModule
local NullRev = lazy.access("diffview.vcs.adapters.null.rev", "NullRev") ---@type NullRev|LazyModule
local RevType = lazy.access("diffview.vcs.rev", "RevType") ---@type RevType|LazyModule
local StandardView = lazy.access("diffview.scene.views.standard.standard_view", "StandardView") ---@type StandardView|LazyModule
local View = lazy.access("diffview.scene.view", "View") ---@type View|LazyModule
local utils = lazy.require("diffview.utils") ---@module "diffview.utils"

local fmt = string.format
Expand Down Expand Up @@ -214,12 +214,16 @@ function FileDirDiffView:_build_entry(rel, status, a_rev, b_rev, c_rev)
b_file = make_file(b_abs, b_rev, nil, nil)
end

local layout
local layout_class
if three_pane then
layout = Diff3Hor.__get()({ a = a_file, b = b_file, c = c_file })
layout_class = View.__get().get_default_merge_layout()
if layout_class == Diff4Mixed.__get() then
layout_class = View.__get().get_default_diff3()
end
else
layout = Diff2Hor.__get()({ a = a_file, b = b_file })
layout_class = View.__get().get_default_layout()
end
local layout = layout_class({ a = a_file, b = b_file, c = c_file })

return FileEntry({
adapter = self.adapter,
Expand Down
15 changes: 8 additions & 7 deletions lua/diffview/scene/views/diff/file_merge_view.lua
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
local lazy = require("diffview.lazy")
local oop = require("diffview.oop")

local Diff3Hor = lazy.access("diffview.scene.layouts.diff_3_hor", "Diff3Hor") ---@type Diff3Hor|LazyModule
local Diff4Mixed = lazy.access("diffview.scene.layouts.diff_4_mixed", "Diff4Mixed") ---@type Diff4Mixed|LazyModule
local File = lazy.access("diffview.vcs.file", "File") ---@type vcs.File|LazyModule
local FileEntry = lazy.access("diffview.scene.file_entry", "FileEntry") ---@type FileEntry|LazyModule
local NullDiffView = lazy.access("diffview.scene.views.diff.null_diff_view", "NullDiffView") ---@type NullDiffView|LazyModule
local NullRev = lazy.access("diffview.vcs.adapters.null.rev", "NullRev") ---@type NullRev|LazyModule
local RevType = lazy.access("diffview.vcs.rev", "RevType") ---@type RevType|LazyModule
local View = lazy.access("diffview.scene.view", "View") ---@type View|LazyModule
local utils = lazy.require("diffview.utils") ---@module "diffview.utils"

local fmt = string.format
Expand Down Expand Up @@ -80,14 +80,15 @@ function FileMergeView:init(opt)
local a_file = make_file(self.left_path, left_rev, "OURS (Current changes)", self.left_path)
local b_file = make_file(self.output_path, output_rev, "MERGED (Output)", nil)
local c_file = make_file(self.right_path, right_rev, "THEIRS (Incoming changes)", self.right_path)
local d_file = self.base_path
and make_file(self.base_path, base_rev, "BASE (Common ancestor)", self.base_path)
or nil

local layout
if self.base_path then
local d_file = make_file(self.base_path, base_rev, "BASE (Common ancestor)", self.base_path)
layout = Diff4Mixed.__get()({ a = a_file, b = b_file, c = c_file, d = d_file })
else
layout = Diff3Hor.__get()({ a = a_file, b = b_file, c = c_file })
local layout_class = View.__get().get_default_merge_layout()
if not d_file and layout_class == Diff4Mixed.__get() then
layout_class = View.__get().get_default_diff3()
end
local layout = layout_class({ a = a_file, b = b_file, c = c_file, d = d_file })

local entry = FileEntry({
adapter = self.adapter,
Expand Down
39 changes: 38 additions & 1 deletion lua/diffview/tests/functional/file_merge_view_spec.lua
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
local actions = require("diffview.actions")
local config = require("diffview.config")
local helpers = require("diffview.tests.helpers")
local lib = require("diffview.lib")
local Diff3Hor = require("diffview.scene.layouts.diff_3_hor").Diff3Hor
Expand Down Expand Up @@ -65,7 +66,8 @@ describe("diffview.scene.views.diff.file_merge_view", function()
assert.True(view.files.conflicting[1].layout:instanceof(Diff3Hor))
end)

it("uses Diff4Mixed when base is provided", function()
it("uses Diff4Mixed when base is provided and config selects Diff4Mixed", function()
config.setup({ view = { merge_tool = { layout = "diff4_mixed" } } })
local adapter = NullAdapter.create({ toplevel = "/tmp" })
local view = FileMergeView({
adapter = adapter,
Expand All @@ -76,6 +78,39 @@ describe("diffview.scene.views.diff.file_merge_view", function()
})

assert.True(view.files.conflicting[1].layout:instanceof(Diff4Mixed))
config.setup({})
end)

it("downgrades a configured Diff4Mixed to Diff3 default when no base is provided", function()
config.setup({ view = { merge_tool = { layout = "diff4_mixed" } } })
local Diff3 = require("diffview.scene.layouts.diff_3").Diff3
local adapter = NullAdapter.create({ toplevel = "/tmp" })
local view = FileMergeView({
adapter = adapter,
output_path = output_path,
left_path = left_path,
right_path = right_path,
})

assert.False(view.files.conflicting[1].layout:instanceof(Diff4Mixed))
assert.True(view.files.conflicting[1].layout:instanceof(Diff3))
config.setup({})
end)

it("honours a Diff3 config even when base is provided (base is dropped)", function()
config.setup({ view = { merge_tool = { layout = "diff3_mixed" } } })
local Diff3Mixed = require("diffview.scene.layouts.diff_3_mixed").Diff3Mixed
local adapter = NullAdapter.create({ toplevel = "/tmp" })
local view = FileMergeView({
adapter = adapter,
output_path = output_path,
base_path = base_path,
left_path = left_path,
right_path = right_path,
})

assert.True(view.files.conflicting[1].layout:instanceof(Diff3Mixed))
config.setup({})
end)

it("populates conflicting (not working) with a single entry", function()
Expand Down Expand Up @@ -126,6 +161,7 @@ describe("diffview.scene.views.diff.file_merge_view", function()
end)

it("binds each window's file to the matching on-disk path", function()
config.setup({ view = { merge_tool = { layout = "diff4_mixed" } } })
local adapter = NullAdapter.create({ toplevel = "/tmp" })
local view = FileMergeView({
adapter = adapter,
Expand All @@ -140,6 +176,7 @@ describe("diffview.scene.views.diff.file_merge_view", function()
eq(output_path, layout.b.file.path) -- OUTPUT (editable)
eq(right_path, layout.c.file.path) -- THEIRS
eq(base_path, layout.d.file.path) -- BASE
config.setup({})
end)

it("populates `merge_ctx` so `merge_only` keymaps show in the help panel", function()
Expand Down
Loading