Reversing a git diff --binary patch with ReverseFileDiff and printing it produces a patch that git apply refuses with "creates incorrect result", while git apply -R of the original patch undoes the same change without complaint.
main.go, in a module requiring go-diff v0.9.0:
package main
import (
"io"
"os"
"github.com/sourcegraph/go-diff/diff"
)
func main() {
in, _ := io.ReadAll(os.Stdin)
fd, err := diff.ParseFileDiff(in)
if err != nil {
panic(err)
}
rev, err := diff.ReverseFileDiff(fd)
if err != nil {
panic(err)
}
out, err := diff.PrintFileDiff(rev)
if err != nil {
panic(err)
}
os.Stdout.Write(out)
}
Run from that module's directory (the diff below is git diff --binary of bin.dat going from the two bytes 00 01 to the four bytes 00 01 02 03; the file starts at the four-byte state):
go build -o revdiff .
rm -rf t && mkdir t && cd t && git init -q
printf '\x00\x01\x02\x03' > bin.dat
cat > fwd.diff <<'EOF'
diff --git a/bin.dat b/bin.dat
index bdc955b7b2e610ad5a72302b139a2e6cb325519a..eaf36c1daccfdf325514461cd1a2ffbc139b5464 100644
GIT binary patch
literal 4
LcmZQzWMT#Y01f~L
literal 2
JcmZQz1ONa700IC2
EOF
git apply -R --check fwd.diff && echo "git apply -R: ok"
../revdiff < fwd.diff > rev.diff
cat rev.diff
git apply --check rev.diff
Output:
git apply -R: ok
diff --git b/bin.dat a/bin.dat
index eaf36c1daccfdf325514461cd1a2ffbc139b5464..bdc955b7b2e610ad5a72302b139a2e6cb325519a 100644
GIT binary patch
literal 4
LcmZQzWMT#Y01f~L
literal 2
JcmZQz1ONa700IC2
error: binary patch to 'bin.dat' creates incorrect result (expecting bdc955b7b2e610ad5a72302b139a2e6cb325519a, got eaf36c1daccfdf325514461cd1a2ffbc139b5464)
error: bin.dat: patch does not apply
The reversed patch has the index hashes and the diff --git arguments swapped, but the two literal sections are still in the original order; git diff -R --binary of the same change writes literal 2 before literal 4. Running git apply rev.diff without --check fails the same way and leaves bin.dat unchanged.
Tested on go-diff v0.9.0 and on current master (cf64c62, the same commit), with git 2.50.1.
BTW, this was found by an automated program that writes property-based tests for various open source projects using hegel (but it has been reviewed by hand before reporting). We've also potentially found (but not yet hand validated) 2 other bugs in go-diff. You can see the tests at https://github.com/hegeldev/hegel-zoo/tree/main/targets/go/go-diff. Let us know if you would like us to file the other bugs found and/or contribute the tests. NB the tests are currently LLM generated and probably not yet suitable for inclusion as is, but we're happy to help get them into a better state if you want them.
Reversing a
git diff --binarypatch withReverseFileDiffand printing it produces a patch thatgit applyrefuses with "creates incorrect result", whilegit apply -Rof the original patch undoes the same change without complaint.main.go, in a module requiring go-diff v0.9.0:Run from that module's directory (the diff below is
git diff --binaryofbin.datgoing from the two bytes00 01to the four bytes00 01 02 03; the file starts at the four-byte state):Output:
The reversed patch has the
indexhashes and thediff --gitarguments swapped, but the twoliteralsections are still in the original order;git diff -R --binaryof the same change writesliteral 2beforeliteral 4. Runninggit apply rev.diffwithout--checkfails the same way and leavesbin.datunchanged.Tested on go-diff v0.9.0 and on current master (cf64c62, the same commit), with git 2.50.1.
BTW, this was found by an automated program that writes property-based tests for various open source projects using hegel (but it has been reviewed by hand before reporting). We've also potentially found (but not yet hand validated) 2 other bugs in go-diff. You can see the tests at https://github.com/hegeldev/hegel-zoo/tree/main/targets/go/go-diff. Let us know if you would like us to file the other bugs found and/or contribute the tests. NB the tests are currently LLM generated and probably not yet suitable for inclusion as is, but we're happy to help get them into a better state if you want them.