About five months ago now, we started on a project to overhaul and upgrade a legacy PHP-4/5 application, moving it to PHP-7 (and many other things). This application consists of more than 2,700 files, and extensive changes have been made to almost all of them.
Meanwhile, the legacy application continues to support the customer, and so-far about 250 changes have been made. I have (and can make ...) git
patches to represent those changes. My immediate problem is that most of them do not git apply
.
It is, of course, easy to see why: "line numbers," as expressed in the patch, are pretty-much useless. Although in most cases the source-code being looked-for is there, it might have been moved some distance.
My present thinking (based on the examination of about 30 of the patch files) is that in usefully-many cases the literal source-code that is to be patched is still present, verbatim, in the source file, just not at the expected place.
Although I am realist enough to know that many of these patches will have to be analyzed and made by hand, I would like to minimize this, both for the sake of time and for accuracy. I would like for the folks who will be doing this ... including me(!) ... to be able to leverage automated tools as much as possible, knowing that they will then have to check their work per-patch. I have no illusions that I'm likely to be able to do all these files at once, automagically, "Shazam."
Therefore, who out there has dealt with a similar situation? What do you suggest that I do? One suggestion has been to use the patch
command, with a fuzz
option, that, it is cautioned, may work or may cause an incorrect patch to be applied.
(We plan to do one patch at a time in any case: "patch, git commit
, rinse and repeat." So that we can git diff
to check each change for sanity.)
"War stories" requested. Thanks.
git apply
provides several options that can be used to apply patches heuristically or semi-manually, most of which are described on the git-apply(1)
manual page:
-C
can reduce the number of context lines that have to match in the hunk for patching to succeed.
-C<n>
- Ensure at least
<n>
lines of surrounding context match before and after each change. When fewer lines of surrounding context exist they all must match. By default no context is ever ignored.
--recount
will ignore line numbers.
--recount
- Do not trust the line counts in the hunk headers, but infer them by inspecting the patch (e.g. after editing the patch without adjusting the hunk headers appropriately).
--reject
will leave hunks that fail to apply in .rej
files, like patch
does. You can then inspect those files and apply the changes manually.
--reject
- For atomicity,
git apply
by default fails the whole patch and does not touch the working tree when some of the hunks do not apply. This option makes it apply the parts of the patch that are applicable, and leave the rejected hunks in corresponding *.rej files.
--3way
will attempt a three-way merge, assuming the patches were generated by git in the first place.
-3
--3way
- When the patch does not apply cleanly, fall back on 3-way merge if the patch records the identity of blobs it is supposed to apply to, and we have those blobs available locally, possibly leaving the conflict markers in the files in the working tree for the user to resolve. This option implies the
--index
option, and is incompatible with the--reject
and the--cached
options.
Personally, I have used git apply -C1 --recount
with some success to convert quilt patches into git commits.
Alternatively, you may simply use the patch
utility to apply the patch, without using the git apply
command at all. By default patch
will apply hunks fuzzily and leave hunks that entirely fail to apply in .rej
files; if the --merge
option is given, failing hunks will generate conflict markers instead.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With