Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Git: suggestion for applying patches when the source is known to have changed substantially

Tags:

git

patch

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.

like image 540
Mike Robinson Avatar asked Jun 26 '16 14:06

Mike Robinson


1 Answers

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.

like image 54
user3840170 Avatar answered Sep 19 '22 13:09

user3840170