mirror of
https://github.com/jesseduffield/lazygit.git
synced 2026-09-27 17:56:37 -04:00
Hand an external diff command to git through the environment
An external diff command rides on the git command as a diff.external config, which means it is fixed when the command is built. That is before the layout pass, so the width the renderer is to lay out for isn't known yet, and the command can't be told about it. Pass it as GIT_EXTERNAL_DIFF from the render instead, where the width is known and where a stdin filter is already handed to git the same way. git ranks the variable exactly as it ranks the config, behind a per-path diff driver from .gitattributes, so a repository that defines one still gets it (verified on git 2.22.5 and 2.55). An empty command means the user wants their own git config to apply, so leave the variable unset for that; git takes it being set at all as an instruction. The renderer command leaves the git arguments, so it also leaves the key that says which diff a render is of. Cycling between two external diff renderers now keeps the view's place, the way cycling between two stdin filters already does. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
f06b881f55
commit
f496f17452
@@ -312,7 +312,7 @@ func TestCommitShowCmdObj(t *testing.T) {
|
||||
similarityThreshold: 50,
|
||||
ignoreWhitespace: false,
|
||||
diffRendererConfig: &config.DiffRendererConfig{Type: "extDiff", Command: "difft --color=always"},
|
||||
expected: []string{"-C", "/path/to/worktree", "-c", "diff.external=difft --color=always", "-c", "diff.noprefix=false", "show", "--ext-diff", "--unified=3", "--find-renames=50%", "--submodule", "--color=always", "--stat", "--decorate", "-p", "1234567890", "--"},
|
||||
expected: []string{"-C", "/path/to/worktree", "-c", "diff.noprefix=false", "show", "--ext-diff", "--unified=3", "--find-renames=50%", "--submodule", "--color=always", "--stat", "--decorate", "-p", "1234567890", "--"},
|
||||
},
|
||||
{
|
||||
testName: "Show diff using git's external diff config",
|
||||
|
||||
@@ -125,11 +125,9 @@ func (self *GitCommandBuilder) GitDirIf(condition bool, path string) *GitCommand
|
||||
|
||||
func (self *GitCommandBuilder) AddCommonDiffArgs(diffRendererConfigManager *config.DiffRendererConfigManager, userConfig *config.UserConfig, forUI bool) *GitCommandBuilder {
|
||||
contextSize := userConfig.Git.DiffContextSize
|
||||
extDiffCmd := diffRendererConfigManager.GetExternalDiffCommand(contextSize)
|
||||
useExtDiff := forUI && diffRendererConfigManager.GetDiffRendererType() == config.DiffRendererType_ExtDiff
|
||||
|
||||
return self.
|
||||
ConfigIf(forUI && extDiffCmd != "", "diff.external="+extDiffCmd).
|
||||
ArgIfElse(useExtDiff, "--ext-diff", "--no-ext-diff").
|
||||
Arg(fmt.Sprintf("--unified=%d", contextSize)).
|
||||
ArgIf(forUI && userConfig.Git.IgnoreWhitespaceInDiffView, "--ignore-all-space").
|
||||
|
||||
@@ -139,7 +139,7 @@ func TestStashStashEntryCmdObj(t *testing.T) {
|
||||
similarityThreshold: 50,
|
||||
ignoreWhitespace: false,
|
||||
diffRendererConfig: &config.DiffRendererConfig{Type: "extDiff", Command: "difft --color=always"},
|
||||
expected: []string{"git", "-C", "/path/to/worktree", "-c", "diff.external=difft --color=always", "stash", "show", "--ext-diff", "--unified=3", "--find-renames=50%", "-p", "--stat", "-u", "--color=always", "refs/stash@{5}"},
|
||||
expected: []string{"git", "-C", "/path/to/worktree", "stash", "show", "--ext-diff", "--unified=3", "--find-renames=50%", "-p", "--stat", "-u", "--color=always", "refs/stash@{5}"},
|
||||
},
|
||||
{
|
||||
testName: "Show diff using git's external diff config",
|
||||
|
||||
+15
-3
@@ -84,10 +84,12 @@ func (gui *Gui) newPtyTask(view *gocui.View, cmd *exec.Cmd, prefix string) error
|
||||
|
||||
// Run the pty after layout so that it gets the correct size
|
||||
gui.afterLayout(func() error {
|
||||
// Need to get the width and the pager command again because the layout might have
|
||||
// changed the size of the view
|
||||
// Need to get the width and the renderer command again because the layout
|
||||
// might have changed the size of the view
|
||||
width = view.InnerWidth()
|
||||
pager := gui.stateAccessor.GetDiffRendererConfigManager().GetStdinFilterCommand(width)
|
||||
diffRendererConfigManager := gui.stateAccessor.GetDiffRendererConfigManager()
|
||||
pager := diffRendererConfigManager.GetStdinFilterCommand(width)
|
||||
externalDiff := diffRendererConfigManager.GetExternalDiffCommand(gui.c.UserConfig().Git.DiffContextSize)
|
||||
|
||||
cmdStr := strings.Join(cmd.Args, " ")
|
||||
|
||||
@@ -100,6 +102,16 @@ func (gui *Gui) newPtyTask(view *gocui.View, cmd *exec.Cmd, prefix string) error
|
||||
|
||||
cmd.Env = append(cmd.Env, "GIT_PAGER="+pager)
|
||||
|
||||
// An external diff command is named to git here, in the environment,
|
||||
// because the width it renders at is only known after the layout, and
|
||||
// the command's arguments were settled before it. An empty command
|
||||
// means the user wants git's own diff.external config to apply, so
|
||||
// leave the variable unset in that case; git takes it being set at all
|
||||
// as an instruction, however little it says.
|
||||
if externalDiff != "" {
|
||||
cmd.Env = append(cmd.Env, "GIT_EXTERNAL_DIFF="+externalDiff)
|
||||
}
|
||||
|
||||
manager := gui.getManager(view)
|
||||
|
||||
// Size the pty from the view's dimensions here, on the UI thread; the
|
||||
|
||||
Reference in New Issue
Block a user