I am trying to move several commits from one project to the second, similar one, using git.
So I created a patch, containing 5 commits:
git format-patch 4af51 --stdout > changes.patch
Then move the patch to second project's folder and wants to apply the patch:
git am changes.patch
...but it gives me error:
Applying: Fixed products ordering in order summary.
error: patch failed: index.php:17
error: index.php: patch does not apply
Patch failed at 0001 Fixed products ordering in order summary.
The copy of the patch that failed is found in:
c:/.../project2/.git/rebase-apply/patch
When you have resolved this problem, run "git am --continue".
If you prefer to skip this patch, run "git am --skip" instead.
To restore the original branch and stop patching, run "git am --abort".
So I opened the index.php, but nothing changed there. I assume some >>>>>>>
marks etc., like when resolving merge conflict, but no conflict was marked in the file. git status
gave me also empty list of changed files (only changes.patch
was there). So I run git am --continue
, but another error appears:
Applying: Fixed products ordering in order summary.
No changes - did you forget to use 'git add'?
If there is nothing left to stage, chances are that something else
already introduced the same changes; you might want to skip this patch.
When you have resolved this problem, run "git am --continue".
If you prefer to skip this patch, run "git am --skip" instead.
To restore the original branch and stop patching, run "git am --abort".
I am using Windows 7 and newest git version "1.9.4.msysgit.1"
P.S. After few hours of googling, I found few solutions, but nothing works for me:
git am -3 changes.patch
gives strange "sha1 information" error:
Applying: Fixed products ordering in order summary.
fatal: sha1 information is lacking or useless (index.php).
Repository lacks necessary blobs to fall back on 3-way merge.
Cannot fall back to three-way merge.
Patch failed at 0001 Fixed products ordering in order summary.
The copy of the patch that failed is found in:
c:/.../project2/.git/rebase-apply/patch
When you have resolved this problem, run "git am --continue".
If you prefer to skip this patch, run "git am --skip" instead.
To restore the original branch and stop patching, run "git am --abort".
git am changes.patch --ignore-whitespace --no-scissors --ignore-space-change
gives first error as above: "error: patch failed: index.php:17", but no conflict marks in index.php
was added.
In order to apply a Git patch file, use the “git am” command and specify the Git patch file to be used. Referring to our previous example, make sure to check out to the branch where you want your patch file to be applied.
What is git am ? git am is a super useful command which can be used for many things as it's reading and parsing the mailbox containing the commits you specify and allows you to use only parts of the extracted data such as the code diff, the autor, the message…
A patch is usually skipped when the changes it contains were already applied in the past. There are many possible reasons for this: a merge, a cherry-pick, changes operated manually or using another patch etc.
A patch is little more (see below) than a series of instructions: "add this here", "remove that there", "change this third thing to a fourth". That's why Git tells you:
The copy of the patch that failed is found in: c:/.../project2/.git/rebase-apply/patch
You can open that patch in your favorite viewer or editor, open the files-to-be-changed in your favorite editor, and "hand apply" the patch, using what you know (and Git does not) to figure out how "add this here" is to be done when the files-to-be-changed now look little or nothing like what they did when they were changed earlier, with those changes delivered to you as a patch.
A three-way merge introduces that "little more" information than the plain "series of instructions": it tells you what the original version of the file was as well. If your repository has the original version, your Git software, working in your repository, can compare what you did to a file, to what the patch says to do to the file.
As you saw above, if you request the three-way merge, Git can't find the "original version" in the other repository, so it can't even attempt the three-way merge. As a result you get no conflict markers, and you must do the patch-application by hand.
(There are cases where the "a little more" part is missing. The extra information is supplied by the Index:
line in the patch, e.g.:
diff --git a/go.mod b/go.mod
index 1fefa60..38a3a41 100644
The second line may read, e.g.:
index 1fefa6021dcd205c1243e236d686595920d9621b..38a3a41434fda3a68ce3356092a89afca81eb614 100644
in more-complete cases. Note the two hash IDs, separated by two dots. The one on the left is the one your Git software will use, to attempt to find a file in your own repository that has the given hash ID. Applying the supplied patch to that file, which must exist, must work and must produce a file whose hash ID will be that on the right, and doing all of this gives Git all the additional information required.)
--reject
When you have to apply the patch by hand, it's still possible that Git can apply most of the patch for you automatically and leave only a few pieces to the entity with the ability to reason about the code (or whatever it is that needs patching). Adding --reject
tells Git to do that, and leave the "inapplicable" parts of the patch in rejection files. If you use this option, you must still hand-apply each failing patch, and figure out what to do with the rejected portions.
Once you have made the required changes, you can git add
the modified files and use git am --continue
to tell Git to commit the changes and move on to the next patch.
Since we don't have your code, I can't tell if this is the case, but sometimes, you wind up with one of the patches saying things that amount to, e.g., "fix the spelling of a word on line 42" when the spelling there was already fixed.
In this particular case, you, having looked at the patch and the current code, should say to yourself: "aha, this patch should just be skipped entirely!" That's when you use the other advice Git already printed:
If you prefer to skip this patch, run "git am --skip" instead.
If you run git am --skip
, Git will skip over that patch, so that if there were five patches in the mailbox, it will end up adding just four commits, instead of five (or three instead of five if you skip twice, and so on).
I had the same problem. I had used
git format-patch <commit_hash>
to create the patch. My main problem was patch was failing due to some conflicts, but I could not see any merge conflict in the file content. I had used git am --3way <patch_file_path>
to apply the patch.
The correct command to apply the patch should be:
git am --3way --ignore-space-change <patch_file_path>
If you execute the above command for patching, it will create a merge conflict if patch apply fails. Then you can fix the conflict in your files, like the same way merge conflicts are resolved for git merge
git format-patch
also has the -B
flag.
The description in the man page leaves much to be desired, but in simple language it's the threshold format-patch will abide to before doing a total re-write of the file (by a single deletion of everything old, followed by a single insertion of everything new).
This proved very useful for me when manual editing was too cumbersome, and the source was more authoritative than my destination.
An example:
git format-patch -B10% --stdout my_tag_name > big_patch.patch
git am -3 -i < big_patch.patch
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