git version 2.19.0
I have two commits for file 'myfile' I am cherry picking from one branch to another branch. During the last patch apply, I get "error: mydir/myfile: does not match index".
1) I generate the two patch files commit1.patch (oldest) and commit2.patch (newest):
cd /target-branch
git --git-dir=/source-branch/myrepo/.git format-patch -k -1 <commit N's ID>
2) I apply patch #1:
git apply -3 commit1.patch
error: patch failed: mydir/myfile:17
error: repository lacks the necessary blob to fall back on 3-way merge.
error: mydir/myfile: patch does not apply
...which fails as expected because two of the hunks in patch modify code blocks added in a commit older than commit #1. I'm not applying that older commit because it's a fix I do not want in target branch.
3) I reapply patch 1 using --reject instead of -3 to skip applying the two non-applicable hunks:
git apply --reject 1.patch
... which logs no errors and logs the two patch hunks it skipped as expected, and applies the rest of the patch.
4) I apply patch #2:
git apply -3 commit2.patch
error: mydir/myfile: does not match index
Why error "does not match index"? 'git status' shows staging is empty, 'git fsck' reports no errors, 'git diff --cached' reports nothing.
I found a workaround: Fresh clone the target branch, edit-out the two hunks which cannot be applied from commit1.patch, then do:
git apply -3 commit1.patch
git apply -3 commit2.patch
… which works with no errors
How can I resolve the "does not match index" error commit2.patch outputs, other than first manually removing the two hunks from commit1.patch?
The answer to your issue is in the git apply
documentation, but in several parts, to which I added boldface (the options were already boldfaced):
-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.
From here you must back up a bit:
--index
When--check
is in effect, or when applying the patch (which is the default when none of the options that disables it is in effect), make sure the patch is applicable to what the current index file records. If the file to be patched in the working tree is not up to date, it is flagged as an error. This flag also causes the index file to be updated.
So by using -3
you turned on --index
, and --index
explicitly calls for an error if the work-tree copy of the file does not match the index copy of the file.
Earlier, in step 3, you manually ran git apply --reject
, without -3
or --index
. That doesn't fail when creating the .rej
file, but does leave the index and work-tree copies different.
If there is to be no point in using -3
, simply leave it out in both cases, so that you apply without updating the index copy of the file and without constraining the work-tree copy of the file to match the index copy of the file either.