diff --git a/knotserver/git/merge.go b/knotserver/git/merge.go index 77e06ff7..013dca4a 100644 --- a/knotserver/git/merge.go +++ b/knotserver/git/merge.go @@ -187,7 +187,7 @@ func (g *GitRepo) applyPatch(patchData, patchFile string, opts MergeOptions) err } // else, apply using 'git apply' and commit it manually - applyCmd, err := wrapCmd(exec.Command("git", "-C", g.path, "apply", patchFile)) + applyCmd, err := wrapCmd(exec.Command("git", "-C", g.path, "apply", "--index", patchFile)) if err != nil { return fmt.Errorf("sandbox wrap for git apply: %w", err) } @@ -196,15 +196,6 @@ func (g *GitRepo) applyPatch(patchData, patchFile string, opts MergeOptions) err return fmt.Errorf("patch application failed: %s", stderr.String()) } - stderr.Reset() - stageCmd, err := wrapCmd(exec.Command("git", "-C", g.path, "add", ".")) - if err != nil { - return fmt.Errorf("sandbox wrap for git add: %w", err) - } - if err := stageCmd.Run(); err != nil { - return fmt.Errorf("failed to stage changes: %w", err) - } - commitArgs := []string{"-C", g.path, "commit", "--allow-empty"} // Set author if provided diff --git a/knotserver/git/merge_test.go b/knotserver/git/merge_test.go index d8a23889..35383e89 100644 --- a/knotserver/git/merge_test.go +++ b/knotserver/git/merge_test.go @@ -197,6 +197,54 @@ index 0000000..ce01362 assert.Equal(t, "hello\n", content) } +func TestApplyPatch_DoesNotCommitPatchFile(t *testing.T) { + h := helper(t) + defer h.cleanup() + + repo := h.initRepo() + + patch := `diff --git a/scallop.txt b/scallop.txt +new file mode 100644 +index 0000000..ce01362 +--- /dev/null ++++ b/scallop.txt +@@ -0,0 +1 @@ ++hello +` + + patchFile, err := createTempIn(repo.path, patch) + require.NoError(t, err) + defer os.Remove(patchFile) + + opts := MergeOptions{ + CommitMessage: "Add scallop.txt", + CommitterName: "nel", + CommitterEmail: "nel@nel.pet", + FormatPatch: false, + } + + err = repo.applyPatch(patch, patchFile, opts) + require.NoError(t, err) + + refreshed, err := PlainOpen(repo.path) + require.NoError(t, err) + + head, err := refreshed.r.Head() + require.NoError(t, err) + + commit, err := refreshed.r.CommitObject(head.Hash()) + require.NoError(t, err) + + tree, err := commit.Tree() + require.NoError(t, err) + + _, err = tree.File("scallop.txt") + assert.NoError(t, err, "patched file should be committed") + + _, err = tree.File(filepath.Base(patchFile)) + assert.ErrorIs(t, err, object.ErrFileNotFound, "temporary patch file must not be committed") +} + func TestApplyPatch_DeleteFile(t *testing.T) { h := helper(t) defer h.cleanup()