Is there an equivalent of “git apply --reject” for

2019-07-01 10:58发布

问题:

I want to use git rebase to take a sequence of commits and apply them to a different root commit. For example,

git rebase --onto root start finish

to get the commits from start to finish based on root.

When git cannot apply a commit cleanly, it updates the file to show conflicts like this (example from git manual):

       Here are lines that are either unchanged from the common
       ancestor, or cleanly resolved because only one side changed.
       <<<<<<< yours:sample.txt
       Conflict resolution is hard;
       let's go shopping.
       =======
       Git makes conflict resolution easy.
       >>>>>>> theirs:sample.txt
       And here is another line that is cleanly resolved or unmodified.

The programmer edits the file to what it should be in the new branch, and then runs git --rebase continue to continue adding the commits from the source.

However, when there are a lot of changes in the file between root and start, there may be many lines like this and they may be hard to interpret. In such cases, one might prefer to have the "failed hunks" output to a file, so that one could read through the changes in the original commit (manually making the necessary changes in the file being altered, and then running git rebase --continue to continue adding commits).

The --reject option of git apply does this:

   --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.

This is also the behaviour of the patch program - so I can get what I want by first outputing the commit with git show, and then applying it with patch. This is not convenient when there are many commits involved, however.

Is there any way of doing this with git rebase (or another git command)?

回答1:

You can do something like this on a commit-by-commit basis.

When a merge conflict occurs, git gives a message like:

CONFLICT (content): Merge conflict in file.c
Failed to merge in the changes.
Patch failed at 0004 Changes to file
The copy of the patch that failed is found in:
   /home/g/src/project/.git/rebase-apply/patch

If file.c is mangled due to showing merge conflicts in the file, you can get the file back to the way it was before the commit with

git reset file.c
git checkout file.c

You can then run

patch -p1 </home/g/src/project/.git/rebase-apply/patch

The output of this could look something like

patching file file.c
Hunk #2 FAILED at 1133.
Hunk #3 FAILED at 1167.
Hunk #4 FAILED at 1201.
Hunk #5 FAILED at 1241.
Hunk #6 FAILED at 1251.
Hunk #7 succeeded at 1324 (offset 6 lines).
Hunk #8 FAILED at 1325.
Hunk #9 succeeded at 2142 (offset 11 lines).
Hunk #10 succeeded at 2163 (offset 11 lines).
Hunk #11 succeeded at 2181 (offset 11 lines).
Hunk #12 succeeded at 2279 (offset 11 lines).
Hunk #13 succeeded at 2299 (offset 11 lines).
Hunk #14 succeeded at 2412 (offset 11 lines).
Hunk #15 succeeded at 2508 (offset 11 lines).
Hunk #16 succeeded at 2531 (offset 11 lines).
Hunk #17 succeeded at 2540 (offset 11 lines).
Hunk #18 succeeded at 2581 (offset 11 lines).
Hunk #19 succeeded at 2599 (offset 11 lines).
Hunk #20 succeeded at 2611 (offset 11 lines).
Hunk #21 succeeded at 2629 (offset 11 lines).
Hunk #22 succeeded at 2637 (offset 11 lines).
Hunk #23 succeeded at 2668 (offset 11 lines).
Hunk #24 succeeded at 2677 (offset 11 lines).
Hunk #25 succeeded at 2805 (offset 11 lines).
Hunk #26 succeeded at 2871 (offset 11 lines).
Hunk #27 succeeded at 2911 (offset 11 lines).
Hunk #28 succeeded at 3028 (offset 11 lines).
Hunk #29 succeeded at 3085 (offset 11 lines).
Hunk #30 succeeded at 3117 (offset 11 lines).
Hunk #31 succeeded at 3557 (offset 11 lines).
Hunk #32 succeeded at 3572 (offset 11 lines).
Hunk #33 succeeded at 4773 (offset 11 lines).
Hunk #34 succeeded at 4807 (offset 11 lines).
Hunk #35 succeeded at 4859 (offset 11 lines).
6 out of 35 hunks FAILED -- saving rejects to file file.c.rej

Then make the changes in file.c.rej manually, then run

git add -u
git rebase --continue

to continue.



标签: git patch rebase