erikkallen
erikkallen

Reputation: 34391

Apply patches created with git log -p

I have a file of patches (all of which apply to a single file) generated with

git log -p file-of-interest.txt >patches.txt

Now I want to apply these patches in another repo, but when I try

git am patches.txt

I get the error message "Patch format detection failed."

(git apply does not work either). Which is the correct way to apply these patches?

Edit: What I want to do is to extract all changes to a single file between two commits into a set of patches, and then apply those changes in another repo. git log -p from..to -- the-file will generate the diff. If it is not possible to apply the patch from git log, is it possible to make format-patch (or another command) generate the patches for only a single file?

Upvotes: 10

Views: 8276

Answers (4)

Reed Sandberg
Reed Sandberg

Reputation: 731

You can use git diff hash1...hash2 >a.patch to create a patch file only of the commits that hash2 has that hash1 doesn't have (note the 3 dots ...). This would be equivalent to git log -p hash1..hash2 (note the 2 dots ..) but the output would be in a format that you could actually patch files with.

The more common git diff hash1 hash2 >a.patch will create a patch file of all differences between hash1 and hash2 including commits that hash1 has but hash2 doesn't.

Upvotes: 0

yucer
yucer

Reputation: 5039

If you format the hash resulting from git log prepending the number of the path with the "-" symbol then all the patchs can be generated at once in different files. Example:

git format-patch $(git log --reverse 073dd505f..fff28ff65 --pretty="%H" -- the/needed/path | awk '{print -NR, " ", $0}')

That will cover all the filter that you can apply from git log. They are not allways consecutive commits. For example taking the patchs corresponding to a given user:

git format-patch $(git log --reverse --author="John Doe" --pretty="%H" -- the/needed/path | awk '{print -NR, " ", $0}')

The --reverse option is needed to give you the patch in chronological order, because git log give the most recents first.

Upvotes: 1

twalberg
twalberg

Reputation: 62369

You need to break the patches down into individual patches. You could do that manually from your git log -p output, then use git apply to apply them in sequence. git log -p output wasn't really intended for git to process...

But a better option would be to use git format-patch to create the sequence of patch files for you (no manual splitting needed), then use git am to apply them all in one go...

git format-patch -o <output_directory> <from_revision>..<to_revision> -- file-of-interest.txt

Also note that git am expects email-formatted patches (like those produced by git format-patch, which is why you get "Patch format detection failed"). Patches generated with diff or git diff should be applied with git apply, not git am. But the git format-patch / git am workflow is more flexible and generally more robust.

Upvotes: 13

Mathew
Mathew

Reputation: 8279

git log won't generate a patch file in that way. Use git log to find out the commit numbers you want to compare and use git diff instead:

git diff 073dd505f fff28ff65 > changes.patch

Upvotes: 0

Related Questions