Can I get a patch-compatible output from git-diff?
Solution 1
If you want to use patch you need to remove the a/ b/ prefixes that git uses by default. You can do this with the --no-prefix option (you can also do this with patch's -p option):
git diff --no-prefix [<other git-diff arguments>]
Usually though, it is easier to use straight git diff and then use the output to feed to git apply.
Most of the time I try to avoid using textual patches. Usually one or more of temporary commits combined with rebase, git stash and bundles are easier to manage.
For your use case I think that stash is most appropriate.
# save uncommitted changes
git stash
# do a merge or some other operation
git merge some-branch
# re-apply changes, removing stash if successful
# (you may be asked to resolve conflicts).
git stash pop
Solution 2
Just use -p1: you will need to use -p0 in the --no-prefix case anyway, so you can just leave out the --no-prefix and use -p1:
$ git diff > save.patch
$ patch -p1 < save.patch
$ git diff --no-prefix > save.patch
$ patch -p0 < save.patch
Solution 3
The git diffs have an extra path segment prepended to the file paths. You can strip the this entry in the path by specifying -p1 with patch, like so:
patch -p1 < save.patch
Solution 4
- I save the diff of the current directory (including uncommitted files) against the current HEAD.
- Then you can transport the
save.patchfile to wherever (including binary files). - On your target machine, apply the patch using
git apply <file>
Note: it diff's the currently staged files too.
$ git diff --binary --staged HEAD > save.patch
$ git reset --hard
$ <transport it>
$ git apply save.patch
Solution 5
A useful trick to avoid creating temporary patch files:
git diff | patch -p1 -d [dst-dir]
Related videos on Youtube
Michael Lorton
Updated on May 14, 2022Comments
-
Michael Lorton 18 minutesI am doing something very simple wrong. I'm trying to prepare an ordinary patch file, so I can reapply some changes:
$ git diff > before $ git diff something_here > save.patch $ git checkout . $ patch < save.patch $ git diff > after $ diff before after $With
something_hereblank it almost works, but the file names aren't right. I think I'm just I'm missing some option.In real life, I am going to do a merge after the checkout, so the patch might fail there, but you see what I'm getting at.
Edit My fault here for asking the wrong question. The actual question is, I want to save my changes away, do a merge, then re-apply the changes, if possible? I asked it the wrong way because I am used to using patch to solve these sorts of problems and
git difflooked like that's what it wanted me to do.Charles Bailey's comment had the right answer. For me, git-apply is the right thing to do (git-stash looks more heavy-weight than I need and rebasing and bundles is definitely beyond my current skill level.) I'm going to accept the answer Charles gave (because you can't accept a comment). Thanks for all the suggestions.
Edit, 6 years later As anyone familiar with the subject knows, I over-estimated the difficulty of
git stash. Pretty much every day or so, I will use the following sequence:$ git stash $ git merge $ git stash pop-
CB Bailey over 11 yearsIs there any reason you specifically want to usepatchrather thangit apply? -
CB Bailey over 11 yearsAnd even then, do you really need patches rather than something likegit stashor other git tools? -
CB Bailey over 11 yearsPost-edit, I think thatgit stashis the easiest solution for what you are trying to do, but there are lots of approaches that work. -
Michael Lorton over 11 yearsI haven't triedstashbut I triedapply, and ifstashis easier than that, well, that must be one easy git command. -
CB Bailey over 11 years@Malvolio: Indeed it is, you don't even have to think of a temporary file name to store your patch in. -
Elazar Leibovich about 11 years@Charlse, sometimes you need to send a patch to someone without the entire git repository. For example if usinggit-svn. -
Conrado almost 7 years@CharlesBailey necromancing this to mention that perhaps I would only like to apply some changes, so editing the patch manually is a quick way to do that. -
Vassilis almost 2 years@CBBailey, because he might want to create a script that patches downloaded sources, maybe in embedded systems, without git installed.
-
-
Michael Lorton over 7 yearsHahaha. That's funny. I asked this question almost four years ago and the way I have been doing this has evolved but if you had asked me yesterday how to do it, I would have given your answer and said I got it from answers to this question. (Actually I would probably use a baregit diff > save.patchandgit checkout .instead of a reset, but yeah... -
Matej over 7 yearsOh didn't notice its 4 yrs old :P. Btw, the reset is just to demonstrate it works.. I also don't see anyone usinggit applyor making the diff relevant to your state and the pointer to the last commit available. Doing justgit diffhasn't done anything at all -
Michael Lorton over 7 yearsYeah, now I wonder how I found out aboutgit apply. The thing withgit diffis (I think) from usinggit reset-- the relationships among the repo, the index, and the working area are the issue. -
Natim over 7 yearsgit diff --no-prefix master > diff.patchand thengit checkout masterpatch -p0 < diff.patch -
ᴠɪɴᴄᴇɴᴛ over 6 years@Natim For ultimate safety I would recommend usingpatch --dry-run < diff.patchbefore issuing the last command. -
Natim over 6 years@ᴠɪɴᴄᴇɴᴛ what would be the benefit of doing that? Since we are using git we are unlikely to loose anything isn't it? -
ᴠɪɴᴄᴇɴᴛ over 6 years@Natim As I said, just for ultimate safety, no need to undo anything in case of error. I was also thinking about people who read this and want to usepatchoutside of git (maybe using a patch file generated bydiff) in a more general use case. -
tutuDajuju about 6 yearsIf you're wondering why, the man docs sums it up nicely - source. -
jamshid about 5 yearsIn order to include new files in your patch you need to also include "git diff --no-prefix --cached" in the patch. Maybe there's a better way? -
dtmland about 5 yearsExactly what I wanted. Also works perfectly with stashes!git stash show -p [email protected]{3} | patch -p1 -d [dst-dir] -
hraban over 3 yearsThis won't work with renames;git diffoutputs a line whichpatchignores.git applyis the way to go.