Repository: jesseduffield/lazygit (language: go)

Issue:
Custom patches do not work if diff.noprefix is true
**Describe the bug**
Git fails to apply patches if it is configured to not prefix diffs. Seen in custom patch feature.
```.gitconfig
[diff]
	noprefix = true
```

Probably should use `git apply -p0`.

**To Reproduce**
Steps to reproduce the behavior:

1. Configure git diff to noprefix = true
2. Create a custom patch in lazygit
3. Move patch out into index
4. See error

**Expected behavior**
The patch should be moved.

**Version info:**
Installed using `go install github.com/jesseduffield/lazygit@latest`.
```
$ lazygit --version
commit=, build date=, build source=unknown, version=unversioned, os=linux, arch=amd64, git version=2.40.1
```



Discussion / hints:
Thanks for the report. This should be easy to fix by explicitly passing `--default-prefix` to the git diff command. (However, `--default-prefix` was only added in 2.40.0, so for better compatibility we can use `--src-prefix=a/ --dst-prefix=b/` which were added in 1.5.4.)

Out of curiosity, why are you setting `diff.noprefix` to true?
I'm using it so that it is easier to select file path from `git diff` output with a double click and pasting it in IDE to go to the file :man_shrugging: 

Fix patch:
diff --git a/pkg/commands/git_commands/commit.go b/pkg/commands/git_commands/commit.go
index dfb0b408510..12806dafc32 100644
--- a/pkg/commands/git_commands/commit.go
+++ b/pkg/commands/git_commands/commit.go
@@ -239,6 +239,7 @@ func (self *CommitCommands) ShowCmdObj(sha string, filterPath string) oscommands
 
 	extDiffCmd := self.UserConfig.Git.Paging.ExternalDiffCommand
 	cmdArgs := NewGitCmd("show").
+		Config("diff.noprefix=false").
 		ConfigIf(extDiffCmd != "", "diff.external="+extDiffCmd).
 		ArgIfElse(extDiffCmd != "", "--ext-diff", "--no-ext-diff").
 		Arg("--submodule").
diff --git a/pkg/commands/git_commands/commit_file_loader.go b/pkg/commands/git_commands/commit_file_loader.go
index 7abdc74c5e3..68faf31cad4 100644
--- a/pkg/commands/git_commands/commit_file_loader.go
+++ b/pkg/commands/git_commands/commit_file_loader.go
@@ -24,6 +24,7 @@ func NewCommitFileLoader(common *common.Common, cmd oscommands.ICmdObjBuilder) *
 // GetFilesInDiff get the specified commit files
 func (self *CommitFileLoader) GetFilesInDiff(from string, to string, reverse bool) ([]*models.CommitFile, error) {
 	cmdArgs := NewGitCmd("diff").
+		Config("diff.noprefix=false").
 		Arg("--submodule").
 		Arg("--no-ext-diff").
 		Arg("--name-status").
diff --git a/pkg/commands/git_commands/diff.go b/pkg/commands/git_commands/diff.go
index 73b30bc4848..9f81bb91d53 100644
--- a/pkg/commands/git_commands/diff.go
+++ b/pkg/commands/git_commands/diff.go
@@ -15,6 +15,7 @@ func NewDiffCommands(gitCommon *GitCommon) *DiffCommands {
 func (self *DiffCommands) DiffCmdObj(diffArgs []string) oscommands.ICmdObj {
 	return self.cmd.New(
 		NewGitCmd("diff").
+			Config("diff.noprefix=false").
 			Arg("--submodule", "--no-ext-diff", "--color").
 			Arg(diffArgs...).
 			Dir(self.repoPaths.worktreePath).
@@ -24,6 +25,7 @@ func (self *DiffCommands) DiffCmdObj(diffArgs []string) oscommands.ICmdObj {
 
 func (self *DiffCommands) internalDiffCmdObj(diffArgs ...string) *GitCommandBuilder {
 	return NewGitCmd("diff").
+		Config("diff.noprefix=false").
 		Arg("--no-ext-diff", "--no-color").
 		Arg(diffArgs...).
 		Dir(self.repoPaths.worktreePath)
@@ -87,6 +89,7 @@ func (self *DiffCommands) OpenDiffToolCmdObj(opts DiffToolCmdOptions) oscommands
 func (self *DiffCommands) DiffIndexCmdObj(diffArgs ...string) oscommands.ICmdObj {
 	return self.cmd.New(
 		NewGitCmd("diff-index").
+			Config("diff.noprefix=false").
 			Arg("--submodule", "--no-ext-diff", "--no-color", "--patch").
 			Arg(diffArgs...).ToArgv(),
 	)
diff --git a/pkg/commands/git_commands/patch.go b/pkg/commands/git_commands/patch.go
index 749e5dc22b7..c632e35ae93 100644
--- a/pkg/commands/git_commands/patch.go
+++ b/pkg/commands/git_commands/patch.go
@@ -321,7 +321,11 @@ func (self *PatchCommands) PullPatchIntoNewCommit(
 // only some lines of a range of adjacent added lines. To solve this, we
 // get the diff of HEAD and the original commit and then apply that.
 func (self *PatchCommands) diffHeadAgainstCommit(commit *models.Commit) (string, error) {
-	cmdArgs := NewGitCmd("diff").Arg("HEAD.." + commit.Sha).ToArgv()
+	cmdArgs := NewGitCmd("diff").
+		Config("diff.noprefix=false").
+		Arg("--no-ext-diff").
+		Arg("HEAD.." + commit.Sha).
+		ToArgv()
 
 	return self.cmd.New(cmdArgs).RunWithOutput()
 }
diff --git a/pkg/commands/git_commands/working_tree.go b/pkg/commands/git_commands/working_tree.go
index 054a272d4b9..2bb82578d52 100644
--- a/pkg/commands/git_commands/working_tree.go
+++ b/pkg/commands/git_commands/working_tree.go
@@ -291,6 +291,7 @@ func (self *WorkingTreeCommands) ShowFileDiffCmdObj(from string, to string, reve
 	useExtDiff := extDiffCmd != "" && !plain
 
 	cmdArgs := NewGitCmd("diff").
+		Config("diff.noprefix=false").
 		ConfigIf(useExtDiff, "diff.external="+extDiffCmd).
 		ArgIfElse(useExtDiff, "--ext-diff", "--no-ext-diff").
 		Arg("--submodule").


Test patch:
diff --git a/pkg/commands/git_commands/commit_test.go b/pkg/commands/git_commands/commit_test.go
index a2b674eebff..34b064d677f 100644
--- a/pkg/commands/git_commands/commit_test.go
+++ b/pkg/commands/git_commands/commit_test.go
@@ -197,7 +197,7 @@ func TestCommitShowCmdObj(t *testing.T) {
 			contextSize:      3,
 			ignoreWhitespace: false,
 			extDiffCmd:       "",
-			expected:         []string{"-C", "/path/to/worktree", "show", "--no-ext-diff", "--submodule", "--color=always", "--unified=3", "--stat", "--decorate", "-p", "1234567890"},
+			expected:         []string{"-C", "/path/to/worktree", "-c", "diff.noprefix=false", "show", "--no-ext-diff", "--submodule", "--color=always", "--unified=3", "--stat", "--decorate", "-p", "1234567890"},
 		},
 		{
 			testName:         "Default case with filter path",
@@ -205,7 +205,7 @@ func TestCommitShowCmdObj(t *testing.T) {
 			contextSize:      3,
 			ignoreWhitespace: false,
 			extDiffCmd:       "",
-			expected:         []string{"-C", "/path/to/worktree", "show", "--no-ext-diff", "--submodule", "--color=always", "--unified=3", "--stat", "--decorate", "-p", "1234567890", "--", "file.txt"},
+			expected:         []string{"-C", "/path/to/worktree", "-c", "diff.noprefix=false", "show", "--no-ext-diff", "--submodule", "--color=always", "--unified=3", "--stat", "--decorate", "-p", "1234567890", "--", "file.txt"},
 		},
 		{
 			testName:         "Show diff with custom context size",
@@ -213,7 +213,7 @@ func TestCommitShowCmdObj(t *testing.T) {
 			contextSize:      77,
 			ignoreWhitespace: false,
 			extDiffCmd:       "",
-			expected:         []string{"-C", "/path/to/worktree", "show", "--no-ext-diff", "--submodule", "--color=always", "--unified=77", "--stat", "--decorate", "-p", "1234567890"},
+			expected:         []string{"-C", "/path/to/worktree", "-c", "diff.noprefix=false", "show", "--no-ext-diff", "--submodule", "--color=always", "--unified=77", "--stat", "--decorate", "-p", "1234567890"},
 		},
 		{
 			testName:         "Show diff, ignoring whitespace",
@@ -221,7 +221,7 @@ func TestCommitShowCmdObj(t *testing.T) {
 			contextSize:      77,
 			ignoreWhitespace: true,
 			extDiffCmd:       "",
-			expected:         []string{"-C", "/path/to/worktree", "show", "--no-ext-diff", "--submodule", "--color=always", "--unified=77", "--stat", "--decorate", "-p", "1234567890", "--ignore-all-space"},
+			expected:         []string{"-C", "/path/to/worktree", "-c", "diff.noprefix=false", "show", "--no-ext-diff", "--submodule", "--color=always", "--unified=77", "--stat", "--decorate", "-p", "1234567890", "--ignore-all-space"},
 		},
 		{
 			testName:         "Show diff with external diff command",
@@ -229,7 +229,7 @@ func TestCommitShowCmdObj(t *testing.T) {
 			contextSize:      3,
 			ignoreWhitespace: false,
 			extDiffCmd:       "difft --color=always",
-			expected:         []string{"-C", "/path/to/worktree", "-c", "diff.external=difft --color=always", "show", "--ext-diff", "--submodule", "--color=always", "--unified=3", "--stat", "--decorate", "-p", "1234567890"},
+			expected:         []string{"-C", "/path/to/worktree", "-c", "diff.external=difft --color=always", "-c", "diff.noprefix=false", "show", "--ext-diff", "--submodule", "--color=always", "--unified=3", "--stat", "--decorate", "-p", "1234567890"},
 		},
 	}
 
diff --git a/pkg/commands/git_commands/working_tree_test.go b/pkg/commands/git_commands/working_tree_test.go
index 51fa88b7ff2..08255e247e4 100644
--- a/pkg/commands/git_commands/working_tree_test.go
+++ b/pkg/commands/git_commands/working_tree_test.go
@@ -348,7 +348,7 @@ func TestWorkingTreeShowFileDiff(t *testing.T) {
 			ignoreWhitespace: false,
 			contextSize:      3,
 			runner: oscommands.NewFakeRunner(t).
-				ExpectGitArgs([]string{"-C", "/path/to/worktree", "diff", "--no-ext-diff", "--submodule", "--unified=3", "--no-renames", "--color=always", "1234567890", "0987654321", "--", "test.txt"}, expectedResult, nil),
+				ExpectGitArgs([]string{"-C", "/path/to/worktree", "-c", "diff.noprefix=false", "diff", "--no-ext-diff", "--submodule", "--unified=3", "--no-renames", "--color=always", "1234567890", "0987654321", "--", "test.txt"}, expectedResult, nil),
 		},
 		{
 			testName:         "Show diff with custom context size",
@@ -359,7 +359,7 @@ func TestWorkingTreeShowFileDiff(t *testing.T) {
 			ignoreWhitespace: false,
 			contextSize:      123,
 			runner: oscommands.NewFakeRunner(t).
-				ExpectGitArgs([]string{"-C", "/path/to/worktree", "diff", "--no-ext-diff", "--submodule", "--unified=123", "--no-renames", "--color=always", "1234567890", "0987654321", "--", "test.txt"}, expectedResult, nil),
+				ExpectGitArgs([]string{"-C", "/path/to/worktree", "-c", "diff.noprefix=false", "diff", "--no-ext-diff", "--submodule", "--unified=123", "--no-renames", "--color=always", "1234567890", "0987654321", "--", "test.txt"}, expectedResult, nil),
 		},
 		{
 			testName:         "Default case (ignore whitespace)",
@@ -370,7 +370,7 @@ func TestWorkingTreeShowFileDiff(t *testing.T) {
 			ignoreWhitespace: true,
 			contextSize:      3,
 			runner: oscommands.NewFakeRunner(t).
-				ExpectGitArgs([]string{"-C", "/path/to/worktree", "diff", "--no-ext-diff", "--submodule", "--unified=3", "--no-renames", "--color=always", "1234567890", "0987654321", "--ignore-all-space", "--", "test.txt"}, expectedResult, nil),
+				ExpectGitArgs([]string{"-C", "/path/to/worktree", "-c", "diff.noprefix=false", "diff", "--no-ext-diff", "--submodule", "--unified=3", "--no-renames", "--color=always", "1234567890", "0987654321", "--ignore-all-space", "--", "test.txt"}, expectedResult, nil),
 		},
 	}
 
diff --git a/pkg/integration/tests/patch_building/move_to_index_works_even_if_noprefix_is_set.go b/pkg/integration/tests/patch_building/move_to_index_works_even_if_noprefix_is_set.go
new file mode 100644
index 00000000000..391223c6099
--- /dev/null
+++ b/pkg/integration/tests/patch_building/move_to_index_works_even_if_noprefix_is_set.go
@@ -0,0 +1,50 @@
+package patch_building
+
+import (
+	"github.com/jesseduffield/lazygit/pkg/config"
+	. "github.com/jesseduffield/lazygit/pkg/integration/components"
+)
+
+var MoveToIndexWorksEvenIfNoprefixIsSet = NewIntegrationTest(NewIntegrationTestArgs{
+	Description:  "Moving a patch to the index works even if diff.noprefix or diff.external are set",
+	ExtraCmdArgs: []string{},
+	Skip:         false,
+	SetupConfig:  func(config *config.AppConfig) {},
+	SetupRepo: func(shell *Shell) {
+		shell.CreateFileAndAdd("file1", "file1 content\n")
+		shell.Commit("first commit")
+
+		// Test that this works even if custom diff options are set
+		shell.SetConfig("diff.noprefix", "true")
+		shell.SetConfig("diff.external", "echo")
+	},
+	Run: func(t *TestDriver, keys config.KeybindingConfig) {
+		t.Views().Commits().
+			Focus().
+			Lines(
+				Contains("first commit").IsSelected(),
+			).
+			PressEnter()
+
+		t.Views().CommitFiles().
+			IsFocused().
+			Lines(
+				Contains("file1").IsSelected(),
+			).
+			PressPrimaryAction()
+
+		t.Views().PatchBuildingSecondary().Content(Contains("+file1 content"))
+
+		t.Common().SelectPatchOption(Contains("Move patch out into index"))
+
+		t.Views().CommitFiles().IsFocused().
+			Lines(
+				Equals("(none)"),
+			)
+
+		t.Views().Files().
+			Lines(
+				Contains("A").Contains("file1"),
+			)
+	},
+})
diff --git a/pkg/integration/tests/test_list.go b/pkg/integration/tests/test_list.go
index 3abc41853b9..b770b953d2c 100644
--- a/pkg/integration/tests/test_list.go
+++ b/pkg/integration/tests/test_list.go
@@ -204,6 +204,7 @@ var tests = []*components.IntegrationTest{
 	patch_building.MoveToIndexPartOfAdjacentAddedLines,
 	patch_building.MoveToIndexPartial,
 	patch_building.MoveToIndexWithConflict,
+	patch_building.MoveToIndexWorksEvenIfNoprefixIsSet,
 	patch_building.MoveToLaterCommit,
 	patch_building.MoveToLaterCommitPartialHunk,
 	patch_building.MoveToNewCommit,