+8
-8
knotserver/git/merge.go
+8
-8
knotserver/git/merge.go
···
12
"github.com/go-git/go-git/v5/plumbing"
13
)
14
15
-
type MergeError struct {
16
Message string
17
Conflicts []ConflictInfo
18
HasConflict bool
···
24
Reason string
25
}
26
27
-
func (e MergeError) Error() string {
28
if e.HasConflict {
29
return fmt.Sprintf("merge failed due to conflicts: %s (%d conflicts)", e.Message, len(e.Conflicts))
30
}
···
90
if err := cmd.Run(); err != nil {
91
if checkOnly {
92
conflicts := parseGitApplyErrors(stderr.String())
93
-
return &MergeError{
94
Message: "patch cannot be applied cleanly",
95
Conflicts: conflicts,
96
HasConflict: len(conflicts) > 0,
···
106
func (g *GitRepo) MergeCheck(patchData []byte, targetBranch string) error {
107
patchFile, err := g.createTempFileWithPatch(patchData)
108
if err != nil {
109
-
return &MergeError{
110
Message: err.Error(),
111
OtherError: err,
112
}
···
115
116
tmpDir, err := g.cloneRepository(targetBranch)
117
if err != nil {
118
-
return &MergeError{
119
Message: err.Error(),
120
OtherError: err,
121
}
···
128
func (g *GitRepo) Merge(patchData []byte, targetBranch string) error {
129
patchFile, err := g.createTempFileWithPatch(patchData)
130
if err != nil {
131
-
return &MergeError{
132
Message: err.Error(),
133
OtherError: err,
134
}
···
137
138
tmpDir, err := g.cloneRepository(targetBranch)
139
if err != nil {
140
-
return &MergeError{
141
Message: err.Error(),
142
OtherError: err,
143
}
···
150
151
pushCmd := exec.Command("git", "-C", tmpDir, "push")
152
if err := pushCmd.Run(); err != nil {
153
-
return &MergeError{
154
Message: "failed to push changes to bare repository",
155
OtherError: err,
156
}
···
12
"github.com/go-git/go-git/v5/plumbing"
13
)
14
15
+
type ErrMerge struct {
16
Message string
17
Conflicts []ConflictInfo
18
HasConflict bool
···
24
Reason string
25
}
26
27
+
func (e ErrMerge) Error() string {
28
if e.HasConflict {
29
return fmt.Sprintf("merge failed due to conflicts: %s (%d conflicts)", e.Message, len(e.Conflicts))
30
}
···
90
if err := cmd.Run(); err != nil {
91
if checkOnly {
92
conflicts := parseGitApplyErrors(stderr.String())
93
+
return &ErrMerge{
94
Message: "patch cannot be applied cleanly",
95
Conflicts: conflicts,
96
HasConflict: len(conflicts) > 0,
···
106
func (g *GitRepo) MergeCheck(patchData []byte, targetBranch string) error {
107
patchFile, err := g.createTempFileWithPatch(patchData)
108
if err != nil {
109
+
return &ErrMerge{
110
Message: err.Error(),
111
OtherError: err,
112
}
···
115
116
tmpDir, err := g.cloneRepository(targetBranch)
117
if err != nil {
118
+
return &ErrMerge{
119
Message: err.Error(),
120
OtherError: err,
121
}
···
128
func (g *GitRepo) Merge(patchData []byte, targetBranch string) error {
129
patchFile, err := g.createTempFileWithPatch(patchData)
130
if err != nil {
131
+
return &ErrMerge{
132
Message: err.Error(),
133
OtherError: err,
134
}
···
137
138
tmpDir, err := g.cloneRepository(targetBranch)
139
if err != nil {
140
+
return &ErrMerge{
141
Message: err.Error(),
142
OtherError: err,
143
}
···
150
151
pushCmd := exec.Command("git", "-C", tmpDir, "push")
152
if err := pushCmd.Run(); err != nil {
153
+
return &ErrMerge{
154
Message: "failed to push changes to bare repository",
155
OtherError: err,
156
}
+18
-18
knotserver/routes.go
+18
-18
knotserver/routes.go
···
577
notFound(w)
578
return
579
}
580
-
581
if err := gr.Merge([]byte(patch), branch); err != nil {
582
-
var mergeErr *git.MergeError
583
if errors.As(err, &mergeErr) {
584
-
conflictDetails := make([]map[string]interface{}, len(mergeErr.Conflicts))
585
for i, conflict := range mergeErr.Conflicts {
586
-
conflictDetails[i] = map[string]interface{}{
587
-
"filename": conflict.Filename,
588
-
"reason": conflict.Reason,
589
}
590
}
591
-
response := map[string]interface{}{
592
-
"message": mergeErr.Message,
593
-
"conflicts": conflictDetails,
594
}
595
writeConflict(w, response)
596
h.l.Error("git: merge conflict", "handler", "Merge", "error", mergeErr)
···
632
return
633
}
634
635
-
var mergeErr *git.MergeError
636
if errors.As(err, &mergeErr) {
637
-
conflictDetails := make([]map[string]interface{}, len(mergeErr.Conflicts))
638
for i, conflict := range mergeErr.Conflicts {
639
-
conflictDetails[i] = map[string]interface{}{
640
-
"filename": conflict.Filename,
641
-
"reason": conflict.Reason,
642
}
643
}
644
-
response := map[string]interface{}{
645
-
"message": mergeErr.Message,
646
-
"conflicts": conflictDetails,
647
}
648
writeConflict(w, response)
649
h.l.Error("git: merge conflict", "handler", "MergeCheck", "error", mergeErr.Error())
650
return
651
}
652
-
653
writeError(w, err.Error(), http.StatusInternalServerError)
654
h.l.Error("git: failed to check merge", "handler", "MergeCheck", "error", err.Error())
655
}
···
577
notFound(w)
578
return
579
}
580
if err := gr.Merge([]byte(patch), branch); err != nil {
581
+
var mergeErr *git.ErrMerge
582
if errors.As(err, &mergeErr) {
583
+
conflicts := make([]types.ConflictInfo, len(mergeErr.Conflicts))
584
for i, conflict := range mergeErr.Conflicts {
585
+
conflicts[i] = types.ConflictInfo{
586
+
Filename: conflict.Filename,
587
+
Reason: conflict.Reason,
588
}
589
}
590
+
response := types.MergeCheckResponse{
591
+
IsConflicted: true,
592
+
Conflicts: conflicts,
593
+
Message: mergeErr.Message,
594
}
595
writeConflict(w, response)
596
h.l.Error("git: merge conflict", "handler", "Merge", "error", mergeErr)
···
632
return
633
}
634
635
+
var mergeErr *git.ErrMerge
636
if errors.As(err, &mergeErr) {
637
+
conflicts := make([]types.ConflictInfo, len(mergeErr.Conflicts))
638
for i, conflict := range mergeErr.Conflicts {
639
+
conflicts[i] = types.ConflictInfo{
640
+
Filename: conflict.Filename,
641
+
Reason: conflict.Reason,
642
}
643
}
644
+
response := types.MergeCheckResponse{
645
+
IsConflicted: true,
646
+
Conflicts: conflicts,
647
+
Message: mergeErr.Message,
648
}
649
writeConflict(w, response)
650
h.l.Error("git: merge conflict", "handler", "MergeCheck", "error", mergeErr.Error())
651
return
652
}
653
writeError(w, err.Error(), http.StatusInternalServerError)
654
h.l.Error("git: failed to check merge", "handler", "MergeCheck", "error", err.Error())
655
}
+12
types/merge.go
+12
types/merge.go
···
1
package types
2
+
3
+
type ConflictInfo struct {
4
+
Filename string `json:"filename"`
5
+
Reason string `json:"reason"`
6
+
}
7
+
8
+
type MergeCheckResponse struct {
9
+
IsConflicted bool `json:"is_conflicted"`
10
+
Conflicts []ConflictInfo `json:"conflicts"`
11
+
Message string `json:"message"`
12
+
Error string `json:"error"`
13
+
}