-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathapply_render.go
More file actions
88 lines (75 loc) · 2.3 KB
/
apply_render.go
File metadata and controls
88 lines (75 loc) · 2.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
package git_diff_parser
import "bytes"
func renderApplyResult(pristine []byte, outcome applyOutcome, options applyOptions) applyResult {
result := applyResult{
Content: joinFileLines(outcome.content),
Reject: renderRejectContent(outcome.rejectHead, outcome.conflicts),
}
if len(outcome.conflicts) == 0 {
return result
}
switch options.Mode {
case applyModeMerge:
result.Content = renderMergeContent(outcome.content, outcome.conflicts, options.ConflictLabels)
result.MergeConflicts = len(outcome.conflicts)
default:
result.Content = append([]byte{}, pristine...)
result.DirectMisses = len(outcome.conflicts)
}
return result
}
func renderMergeContent(base []fileLine, conflicts []applyConflict, labels conflictLabels) []byte {
if len(conflicts) == 0 {
return joinFileLines(base)
}
rendered := append([]fileLine(nil), base...)
for i := len(conflicts) - 1; i >= 0; i-- {
conflict := conflicts[i]
if conflict.offset < 0 || conflict.offset > len(rendered) {
continue
}
end := conflict.offset + len(conflict.ours)
if end > len(rendered) {
end = len(rendered)
}
replacement := renderConflictLines(labels, conflict.ours, conflict.theirs)
rendered = append(rendered[:conflict.offset], append(replacement, rendered[end:]...)...)
}
return joinFileLines(rendered)
}
func renderRejectContent(header string, conflicts []applyConflict) []byte {
if len(conflicts) == 0 {
return nil
}
var buf bytes.Buffer
if header != "" {
buf.WriteString(header)
buf.WriteByte('\n')
}
for i := range conflicts {
if conflicts[i].hunk.header != "" {
buf.WriteString(conflicts[i].hunk.header)
buf.WriteByte('\n')
}
for _, line := range conflicts[i].hunk.lines {
buf.WriteByte(line.kind)
buf.WriteString(line.text)
if line.hasNewline {
buf.WriteByte('\n')
}
}
}
return buf.Bytes()
}
func renderConflictLines(labels conflictLabels, ours, theirs []fileLine) []fileLine {
lines := []fileLine{
{text: "<<<<<<< " + labels.Current, hasNewline: true},
}
lines = appendSourceLines(lines, ours...)
lines = ensureTrailingNewline(lines)
lines = append(lines, fileLine{text: "=======", hasNewline: true})
lines = appendSourceLines(lines, theirs...)
lines = ensureTrailingNewline(lines)
lines = append(lines, fileLine{text: ">>>>>>> " + labels.Incoming, hasNewline: true})
return lines
}