197

I 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_here blank 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 diff looked 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

Edit, 5 years further down the road I have largely abandoned git apply and don’t even used git stash much. git rebase FTW.

Michael Lorton
  • 43,060
  • 26
  • 103
  • 144
  • 9
    Is there any reason you specifically want to use `patch` rather than `git apply` ? – CB Bailey Jan 06 '11 at 00:41
  • 3
    And even then, do you really need patches rather than something like `git stash` or other git tools? – CB Bailey Jan 06 '11 at 00:43
  • 3
    Post-edit, I think that `git stash` is the easiest solution for what you are trying to do, but there are lots of approaches that work. – CB Bailey Jan 06 '11 at 01:26
  • I haven't tried `stash` but I tried `apply`, and if `stash` is *easier* than that, well, that must be one easy git command. – Michael Lorton Jan 06 '11 at 01:35
  • 1
    @Malvolio: Indeed it is, you don't even have to think of a temporary file name to store your patch in. – CB Bailey Jan 06 '11 at 12:15
  • 5
    @Charlse, sometimes you need to send a patch to someone without the entire git repository. For example if using `git-svn`. – Elazar Leibovich Mar 29 '11 at 08:27
  • 1
    @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. – Conrado Jul 17 '15 at 14:42
  • @CBBailey, because he might want to create a script that patches downloaded sources, maybe in embedded systems, without git installed. – Vassilis May 31 '20 at 15:12

5 Answers5

256

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
ndim
  • 35,870
  • 12
  • 47
  • 57
  • 2
    If you're wondering why, [the man docs](http://www.gnu.org/software/diffutils/manual/diffutils.html#patch-Directories) sums it up nicely - [source](http://unix.stackexchange.com/a/26502/17836). – tutuDajuju Feb 25 '16 at 15:28
  • 3
    This won't work with renames; `git diff` outputs a line which `patch` ignores. `git apply` is the way to go. – hraban Jan 14 '19 at 11:33
156

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
CB Bailey
  • 755,051
  • 104
  • 632
  • 656
  • 8
    `git diff --no-prefix master > diff.patch` and then `git checkout master` `patch -p0 < diff.patch` – Natim Nov 18 '14 at 10:41
  • 3
    @Natim For ultimate safety I would recommend using `patch --dry-run < diff.patch` before issuing the last command. – ᴠɪɴᴄᴇɴᴛ Jan 20 '16 at 21:55
  • 1
    @ᴠɪɴᴄᴇɴᴛ what would be the benefit of doing that? Since we are using git we are unlikely to loose anything isn't it? – Natim Jan 26 '16 at 13:21
  • 2
    @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 use `patch` outside of git (maybe using a patch file generated by `diff`) in a more general use case. – ᴠɪɴᴄᴇɴᴛ Jan 26 '16 at 17:11
  • In 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? – jamshid Mar 09 '17 at 05:46
16

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
Henrik Gustafsson
  • 51,180
  • 9
  • 47
  • 60
12
  1. I save the diff of the current directory (including uncommitted files) against the current HEAD.
  2. Then you can transport the save.patch file to wherever (including binary files).
  3. 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
Matej
  • 9,548
  • 8
  • 49
  • 66
  • Hahaha. 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 bare `git diff > save.patch` and `git checkout .` instead of a reset, but yeah... – Michael Lorton Sep 05 '14 at 14:55
  • Oh didn't notice its 4 yrs old :P. Btw, the reset is just to demonstrate it works.. I also don't see anyone using `git apply` or making the diff relevant to your state and the pointer to the last commit available. Doing just `git diff` hasn't done anything at all – Matej Sep 05 '14 at 14:58
  • Yeah, now I wonder how I found out about `git apply`. The thing with `git diff` is (I think) from using `git reset` -- the relationships among the repo, the index, and the working area are the issue. – Michael Lorton Sep 05 '14 at 19:39
8

A useful trick to avoid creating temporary patch files:

git diff | patch -p1 -d [dst-dir]
Owen Blacker
  • 4,117
  • 2
  • 33
  • 70
slowstart
  • 303
  • 4
  • 8
  • 1
    Exactly what I wanted. Also works perfectly with stashes! `git stash show -p stash@{3} | patch -p1 -d [dst-dir]` – dtmland Apr 07 '17 at 15:51