go-gitdiff
A Go library for parsing and applying patches generated by git diff
, git show
, and git format-patch
. It can also parse and apply unified diffs
generated by the standard diff
tool.
It supports both standard line-oriented text patches and Git binary patches.
patch, err := os.Open("changes.patch")
if err != nil {
log.Fatalf(err)
}
files, preamble, err := gitdiff.Parse(patch)
if err != nil {
log.Fatalf(err)
}
// files is a slice of *gitdiff.File describing the files changed in the patch
// preamble is a string of the content of the patch before the first file
Status
In development, expect API changes. Patch parsing works, but has not been
tested extensively against real-world patches. Patch application has not been
implemented yet.
Why another git/unified diff parser?
Several packages with similar
functionality exist, so why did I write another?
-
No other packages I found support binary diffs, as generated with the
--binary
flag. This is the main reason for writing a new packages, as the
format is pretty different from line-oriented diffs and is unique to Git.
-
Most other packages only parse patches, so you need another package to apply
them (and if they do support applies, it is only for text files.)
-
This package aims to accept anything that git apply
accepts, and closely
follows the logic in apply.c
.
-
It seemed like a fun thing to write and a good way to learn more about Git.
Differences From Git
-
Certain types of invalid input that are accepted by git apply
generate
errors. These include:
- Numbers immediately followed by non-numeric characters
- Trailing characters on a line after valid or expected content
-
Errors for invalid input are generally more verbose and specific than those
from git apply
.
-
The translation from C to Go may have introduced inconsistencies in the way
Unicode file names are handled; these are bugs, so please report any issues
of this type.
-
When reading headers, there is no validation that OIDs present on an index
line are shorter than or equal to the maximum hash length, as this requires
knowing if the repository used SHA1 or SHA256 hashes.
-
When reading "traditional" patches (those not produced by git
), prefixes
are not stripped from file names; git apply
attempts to remove prefixes
that match the current repository directory/prefix.