Mirror of @tangled.org/core. Running on a Raspberry Pi Zero 2 (Please be gentle).
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

knotserver/git/merge: merge options use git apply

authored by

Anirudh Oppiliappan and committed by
Akshay
943975c2 26f6bc6b

+75 -9
+57 -4
knotserver/git/merge.go
··· 24 24 Reason string 25 25 } 26 26 27 + // MergeOptions specifies the configuration for a merge operation 28 + type MergeOptions struct { 29 + CommitMessage string 30 + CommitBody string 31 + AuthorName string 32 + AuthorEmail string 33 + } 34 + 27 35 func (e ErrMerge) Error() string { 28 36 if e.HasConflict { 29 37 return fmt.Sprintf("merge failed due to conflicts: %s (%d conflicts)", e.Message, len(e.Conflicts)) ··· 82 74 return tmpDir, nil 83 75 } 84 76 85 - func (g *GitRepo) applyPatch(tmpDir, patchFile string, checkOnly bool) error { 77 + func (g *GitRepo) applyPatch(tmpDir, patchFile string, checkOnly bool, opts *MergeOptions) error { 86 78 var stderr bytes.Buffer 87 79 var cmd *exec.Cmd 88 80 ··· 90 82 cmd = exec.Command("git", "-C", tmpDir, "apply", "--check", "-v", patchFile) 91 83 } else { 92 84 exec.Command("git", "-C", tmpDir, "config", "advice.mergeConflict", "false").Run() 93 - cmd = exec.Command("git", "-C", tmpDir, "am", patchFile) 85 + 86 + if opts != nil { 87 + applyCmd := exec.Command("git", "-C", tmpDir, "apply", patchFile) 88 + applyCmd.Stderr = &stderr 89 + if err := applyCmd.Run(); err != nil { 90 + return fmt.Errorf("patch application failed: %s", stderr.String()) 91 + } 92 + 93 + stageCmd := exec.Command("git", "-C", tmpDir, "add", ".") 94 + if err := stageCmd.Run(); err != nil { 95 + return fmt.Errorf("failed to stage changes: %w", err) 96 + } 97 + 98 + commitArgs := []string{"-C", tmpDir, "commit"} 99 + 100 + // Set author if provided 101 + authorName := opts.AuthorName 102 + authorEmail := opts.AuthorEmail 103 + 104 + if authorEmail == "" { 105 + authorEmail = "noreply@tangled.sh" 106 + } 107 + 108 + if authorName == "" { 109 + authorName = "Tangled" 110 + } 111 + 112 + if authorName != "" { 113 + commitArgs = append(commitArgs, "--author", fmt.Sprintf("%s <%s>", authorName, authorEmail)) 114 + } 115 + 116 + commitArgs = append(commitArgs, "-m", opts.CommitMessage) 117 + 118 + if opts.CommitBody != "" { 119 + commitArgs = append(commitArgs, "-m", opts.CommitBody) 120 + } 121 + 122 + cmd = exec.Command("git", commitArgs...) 123 + } else { 124 + // If no commit message specified, use git-am which automatically creates a commit 125 + cmd = exec.Command("git", "-C", tmpDir, "am", patchFile) 126 + } 94 127 } 95 128 96 129 cmd.Stderr = &stderr ··· 171 122 } 172 123 defer os.RemoveAll(tmpDir) 173 124 174 - return g.applyPatch(tmpDir, patchFile, true) 125 + return g.applyPatch(tmpDir, patchFile, true, nil) 175 126 } 176 127 177 128 func (g *GitRepo) Merge(patchData []byte, targetBranch string) error { 129 + return g.MergeWithOptions(patchData, targetBranch, nil) 130 + } 131 + 132 + func (g *GitRepo) MergeWithOptions(patchData []byte, targetBranch string, opts *MergeOptions) error { 178 133 patchFile, err := g.createTempFileWithPatch(patchData) 179 134 if err != nil { 180 135 return &ErrMerge{ ··· 197 144 } 198 145 defer os.RemoveAll(tmpDir) 199 146 200 - if err := g.applyPatch(tmpDir, patchFile, false); err != nil { 147 + if err := g.applyPatch(tmpDir, patchFile, false, opts); err != nil { 201 148 return err 202 149 } 203 150
+9 -5
knotserver/routes.go
··· 559 559 func (h *Handle) Merge(w http.ResponseWriter, r *http.Request) { 560 560 path, _ := securejoin.SecureJoin(h.c.Repo.ScanPath, didPath(r)) 561 561 562 - var data struct { 563 - Patch string `json:"patch"` 564 - Branch string `json:"branch"` 565 - } 562 + data := types.MergeRequest{} 566 563 567 564 if err := json.NewDecoder(r.Body).Decode(&data); err != nil { 568 565 writeError(w, err.Error(), http.StatusBadRequest) 569 566 h.l.Error("git: failed to unmarshal json patch", "handler", "Merge", "error", err) 570 567 return 568 + } 569 + 570 + mo := &git.MergeOptions{ 571 + AuthorName: data.AuthorName, 572 + AuthorEmail: data.AuthorEmail, 573 + CommitBody: data.CommitBody, 574 + CommitMessage: data.CommitMessage, 571 575 } 572 576 573 577 patch := data.Patch ··· 581 577 notFound(w) 582 578 return 583 579 } 584 - if err := gr.Merge([]byte(patch), branch); err != nil { 580 + if err := gr.MergeWithOptions([]byte(patch), branch, mo); err != nil { 585 581 var mergeErr *git.ErrMerge 586 582 if errors.As(err, &mergeErr) { 587 583 conflicts := make([]types.ConflictInfo, len(mergeErr.Conflicts))
+9
types/merge.go
··· 11 11 Message string `json:"message"` 12 12 Error string `json:"error"` 13 13 } 14 + 15 + type MergeRequest struct { 16 + Patch string `json:"patch"` 17 + AuthorName string `json:"authorName,omitempty"` 18 + AuthorEmail string `json:"authorEmail,omitempty"` 19 + CommitBody string `json:"commitBody,omitempty"` 20 + CommitMessage string `json:"commitMessage,omitempty"` 21 + Branch string `json:"branch"` 22 + }