1
0
mirror of https://github.com/jesseduffield/lazygit.git synced 2025-05-15 22:26:40 +02:00

Add patch option WillBeAppliedReverse

It's not used yet, but covered with tests already.
This commit is contained in:
Stefan Haller 2023-02-26 13:48:10 +01:00
parent f76cc27956
commit c79e360584
3 changed files with 86 additions and 15 deletions

View File

@ -45,7 +45,7 @@ func headerInfo(header string) (int, int, string) {
return oldStart, newStart, heading return oldStart, newStart, heading
} }
func (hunk *PatchHunk) updatedLines(lineIndices []int, reverse bool) []string { func (hunk *PatchHunk) updatedLines(lineIndices []int, reverse bool, willBeAppliedReverse bool) []string {
skippedNewlineMessageIndex := -1 skippedNewlineMessageIndex := -1
newLines := []string{} newLines := []string{}
@ -58,7 +58,7 @@ func (hunk *PatchHunk) updatedLines(lineIndices []int, reverse bool) []string {
isLineSelected := lo.Contains(lineIndices, lineIdx) isLineSelected := lo.Contains(lineIndices, lineIdx)
firstChar, content := line[:1], line[1:] firstChar, content := line[:1], line[1:]
transformedFirstChar := transformedFirstChar(firstChar, reverse, isLineSelected) transformedFirstChar := transformedFirstChar(firstChar, reverse, willBeAppliedReverse, isLineSelected)
if isLineSelected || (transformedFirstChar == "\\" && skippedNewlineMessageIndex != lineIdx) || transformedFirstChar == " " { if isLineSelected || (transformedFirstChar == "\\" && skippedNewlineMessageIndex != lineIdx) || transformedFirstChar == " " {
newLines = append(newLines, transformedFirstChar+content) newLines = append(newLines, transformedFirstChar+content)
@ -74,7 +74,7 @@ func (hunk *PatchHunk) updatedLines(lineIndices []int, reverse bool) []string {
return newLines return newLines
} }
func transformedFirstChar(firstChar string, reverse bool, isLineSelected bool) string { func transformedFirstChar(firstChar string, reverse bool, willBeAppliedReverse bool, isLineSelected bool) string {
if reverse { if reverse {
if !isLineSelected && firstChar == "+" { if !isLineSelected && firstChar == "+" {
return " " return " "
@ -87,7 +87,11 @@ func transformedFirstChar(firstChar string, reverse bool, isLineSelected bool) s
} }
} }
if !isLineSelected && firstChar == "-" { linesToKeepInPatchContext := "-"
if willBeAppliedReverse {
linesToKeepInPatchContext = "+"
}
if !isLineSelected && firstChar == linesToKeepInPatchContext {
return " " return " "
} }
@ -98,8 +102,8 @@ func (hunk *PatchHunk) formatHeader(oldStart int, oldLength int, newStart int, n
return fmt.Sprintf("@@ -%d,%d +%d,%d @@%s\n", oldStart, oldLength, newStart, newLength, heading) return fmt.Sprintf("@@ -%d,%d +%d,%d @@%s\n", oldStart, oldLength, newStart, newLength, heading)
} }
func (hunk *PatchHunk) formatWithChanges(lineIndices []int, reverse bool, startOffset int) (int, string) { func (hunk *PatchHunk) formatWithChanges(lineIndices []int, reverse bool, willBeAppliedReverse bool, startOffset int) (int, string) {
bodyLines := hunk.updatedLines(lineIndices, reverse) bodyLines := hunk.updatedLines(lineIndices, reverse, willBeAppliedReverse)
startOffset, header, ok := hunk.updatedHeader(bodyLines, startOffset, reverse) startOffset, header, ok := hunk.updatedHeader(bodyLines, startOffset, reverse)
if !ok { if !ok {
return startOffset, "" return startOffset, ""

View File

@ -18,6 +18,15 @@ type PatchOptions struct {
// generating the patch. // generating the patch.
Reverse bool Reverse bool
// If true, we're building a patch that we are going to apply using
// "git apply --reverse". In other words, we are not flipping the '+' and
// '-' ourselves while creating the patch, but git is going to do that when
// applying. This has consequences for which lines we need to keep or
// discard when filtering lines from partial hunks.
//
// Currently incompatible with Reverse.
WillBeAppliedReverse bool
// Whether to keep or discard the original diff header including the // Whether to keep or discard the original diff header including the
// "index deadbeef..fa1afe1 100644" line. // "index deadbeef..fa1afe1 100644" line.
KeepOriginalHeader bool KeepOriginalHeader bool
@ -105,7 +114,8 @@ outer:
formattedHunks := "" formattedHunks := ""
var formattedHunk string var formattedHunk string
for _, hunk := range hunksInRange { for _, hunk := range hunksInRange {
startOffset, formattedHunk = hunk.formatWithChanges(lineIndices, opts.Reverse, startOffset) startOffset, formattedHunk = hunk.formatWithChanges(
lineIndices, opts.Reverse, opts.WillBeAppliedReverse, startOffset)
formattedHunks += formattedHunk formattedHunks += formattedHunk
} }

View File

@ -69,6 +69,20 @@ index e48a11c..b2ab81b 100644
... ...
` `
const twoChangesInOneHunk = `diff --git a/filename b/filename
index 9320895..6d79956 100644
--- a/filename
+++ b/filename
@@ -1,5 +1,5 @@
apple
-grape
+kiwi
orange
-pear
+banana
lemon
`
const newFile = `diff --git a/newfile b/newfile const newFile = `diff --git a/newfile b/newfile
new file mode 100644 new file mode 100644
index 0000000..4e680cc index 0000000..4e680cc
@ -101,13 +115,14 @@ const exampleHunk = `@@ -1,5 +1,5 @@
// TestModifyPatchForRange is a function. // TestModifyPatchForRange is a function.
func TestModifyPatchForRange(t *testing.T) { func TestModifyPatchForRange(t *testing.T) {
type scenario struct { type scenario struct {
testName string testName string
filename string filename string
diffText string diffText string
firstLineIndex int firstLineIndex int
lastLineIndex int lastLineIndex int
reverse bool reverse bool
expected string willBeAppliedReverse bool
expected string
} }
scenarios := []scenario{ scenarios := []scenario{
@ -506,6 +521,44 @@ func TestModifyPatchForRange(t *testing.T) {
@@ -1,1 +0,0 @@ @@ -1,1 +0,0 @@
-new line -new line
\ No newline at end of file \ No newline at end of file
`,
},
{
testName: "adding part of a hunk",
filename: "filename",
firstLineIndex: 6,
lastLineIndex: 7,
reverse: false,
willBeAppliedReverse: false,
diffText: twoChangesInOneHunk,
expected: `--- a/filename
+++ b/filename
@@ -1,5 +1,5 @@
apple
-grape
+kiwi
orange
pear
lemon
`,
},
{
testName: "adding part of a hunk, will-be-applied-reverse",
filename: "filename",
firstLineIndex: 6,
lastLineIndex: 7,
reverse: false,
willBeAppliedReverse: true,
diffText: twoChangesInOneHunk,
expected: `--- a/filename
+++ b/filename
@@ -1,5 +1,5 @@
apple
-grape
+kiwi
orange
banana
lemon
`, `,
}, },
} }
@ -514,7 +567,11 @@ func TestModifyPatchForRange(t *testing.T) {
s := s s := s
t.Run(s.testName, func(t *testing.T) { t.Run(s.testName, func(t *testing.T) {
result := ModifiedPatchForRange(nil, s.filename, s.diffText, s.firstLineIndex, s.lastLineIndex, result := ModifiedPatchForRange(nil, s.filename, s.diffText, s.firstLineIndex, s.lastLineIndex,
PatchOptions{Reverse: s.reverse, KeepOriginalHeader: false}) PatchOptions{
Reverse: s.reverse,
WillBeAppliedReverse: s.willBeAppliedReverse,
KeepOriginalHeader: false,
})
if !assert.Equal(t, s.expected, result) { if !assert.Equal(t, s.expected, result) {
fmt.Println(result) fmt.Println(result)
} }