Create a git patch from the uncommitted changes in the current working directory
Asked Answered
T

8

1340

Say I have uncommitted changes in my working directory. How can I make a patch from those without having to create a commit?

Toole answered 1/3, 2011 at 19:14 Comment(4)
Accepted answer should probably be changed, given the second answer is nearly four times more popular.Iatrics
@TimOgilvy agreed. OP should do it. Second answer is far more popular and gives more informationCarolinecarolingian
I think it worth to mention you need patch from uncommitted changes in the title either.Sacrarium
Core git work flow: Copy all your files somewhere else before attempting to pull or switch branches, then do this, when it inevitably goes wrong. :) 1000's of upvotes suggests this happens alot :)Wainscot
A
600

git diff for unstaged changes.

git diff --cached for staged changes.

git diff HEAD for both staged and unstaged changes.

Abbotsun answered 1/3, 2011 at 19:16 Comment(13)
Is the output of git diff enough to create a patch that can be applied with git apply?Toole
yup, git diff is the inverse of git applyChokecherry
That fails with "No such file or directory" if you have new files in new directoriesAubergine
git format-patch also includes binary diffs and some meta info. Actually that would be the best bet for creating a patch, but afaik this does only work for checked in sources/ changes, right?Falbala
@sigjuice: Does git-diff handle binary differences? I think Eric has a good point, so this answer isn't quite complete.Chartreuse
Sometimes it might be useful to create a patch relative to the current directory. To achieve this, use git diff --relativeLiddy
git diff > a.patch to write it to a fileRefutation
Better than git diff --relative is just git diff . (where the dot implies the diff from the current directory).Riccio
Terse bordering on sarcastic, the answer below is more helpful.Leakage
@Liddy While very useful git diff --relative > x I could not use the output for git apply x. It just happened nothing. Strange.Keilakeily
This is not very helpful. git diff does not create a patch, it merely shows the changes. Below answer actually answers the question.Woodcut
I have a question: can the patch generated by this git diff command be used by the patch command? Are they compatible with each other?Ripen
...and git diff HEAD for both staged and unstaged. - i suggest you to append it to the answerIndefinable
R
2623

If you haven't yet commited the changes, then:

git diff > mypatch.patch

But sometimes it happens that part of the stuff you're doing are new files that are untracked and won't be in your git diff output. So, one way to do a patch is to stage everything for a new commit (git add each file, or just git add .) but don't do the commit, and then:

git diff --cached > mypatch.patch

Add the 'binary' option if you want to add binary files to the patch (e.g. mp3 files):

git diff --cached --binary > mypatch.patch

You can later apply the patch:

git apply mypatch.patch
Riccio answered 15/3, 2013 at 17:43 Comment(13)
I did exactly that and got "fatal: unrecognized input" upon executing git apply. Any idea what can cause this and how to fix it?Frederic
@Vitaly: is your patch readable if you open it with a text editor? it should be clean with no strange characters, for example if the color.diff setting is set your patch will have some 'color characters' that can make 'git apply' fail, in that case try git diff --no-color. Otherwise, it looks like an encoding problem.Riccio
Yes, it looks perfectly fine. I wasn't able to do this from the command line, but WebStorm's create/apply patch function did the trick. You are probably right about encoding issue, as I was creating a patch in Windows and applying it in Mac OS. Thanks for your reply.Frederic
@Vitaly: It's probably caused by UTF BOM - I had to remove the BOM bytes in editor.Circumgyration
To create the patch from the already staged changes you could also do git diff --staged > mypatch.patch, because --staged is a synonym for --cached. I think it easier to remember.Reiterant
Related to "new files that are untracked": "git diff" and "git diff --cached" only work if "git add <file>" has been called first. (I am new to git and wondered why I got an empty patch everytime)Fernandina
Yeah, when I say to "stage everything for a new commit", I mean git add whatever you want to stage. Git therminology :)Riccio
This got me out of a strange merge/rebase hell pretty easily, thanks :)Askari
In case you did commit it already you can diff between two commits. For example, if the fix is my last commit: git diff HEAD~1 HEAD > mypatch.patch Then to apply it anywhere else: git apply mypatch.patchCostard
Thank you. One the team members in my team didn't have git write only access. I wanted to check in code on his behalf patch has helped complete this activity.Angelangela
would be more helpful if you add into answer how to make patch from range of commits.Epimorphosis
An update on this answer: if you have new untracked files you can do git add -N <file-mask> it won't actually add the files but will start tracking them instead, making them available for git diff and the patch.Existence
fatal: unrecognized input is probably related to encoding issues (when using Powershell). Try to use cmd or git-bash instead of powershellMcmasters
A
600

git diff for unstaged changes.

git diff --cached for staged changes.

git diff HEAD for both staged and unstaged changes.

Abbotsun answered 1/3, 2011 at 19:16 Comment(13)
Is the output of git diff enough to create a patch that can be applied with git apply?Toole
yup, git diff is the inverse of git applyChokecherry
That fails with "No such file or directory" if you have new files in new directoriesAubergine
git format-patch also includes binary diffs and some meta info. Actually that would be the best bet for creating a patch, but afaik this does only work for checked in sources/ changes, right?Falbala
@sigjuice: Does git-diff handle binary differences? I think Eric has a good point, so this answer isn't quite complete.Chartreuse
Sometimes it might be useful to create a patch relative to the current directory. To achieve this, use git diff --relativeLiddy
git diff > a.patch to write it to a fileRefutation
Better than git diff --relative is just git diff . (where the dot implies the diff from the current directory).Riccio
Terse bordering on sarcastic, the answer below is more helpful.Leakage
@Liddy While very useful git diff --relative > x I could not use the output for git apply x. It just happened nothing. Strange.Keilakeily
This is not very helpful. git diff does not create a patch, it merely shows the changes. Below answer actually answers the question.Woodcut
I have a question: can the patch generated by this git diff command be used by the patch command? Are they compatible with each other?Ripen
...and git diff HEAD for both staged and unstaged. - i suggest you to append it to the answerIndefinable
C
108

git diff and git apply will work for text files, but won't work for binary files.

You can easily create a full binary patch, but you will have to create a temporary commit. Once you've made your temporary commit(s), you can create the patch with:

git format-patch <options...>

After you've made the patch, run this command:

git reset --mixed <SHA of commit *before* your working-changes commit(s)>

This will roll back your temporary commit(s). The final result leaves your working copy (intentionally) dirty with the same changes you originally had.

On the receiving side, you can use the same trick to apply the changes to the working copy, without having the commit history. Simply apply the patch(es), and git reset --mixed <SHA of commit *before* the patches>.

Note that you might have to be well-synced for this whole option to work. I've seen some errors when applying patches when the person making them hadn't pulled down as many changes as I had. There are probably ways to get it to work, but I haven't looked far into it.


Here's how to create the same patches in Tortoise Git (not that I recommend using that tool):

  1. Commit your working changes
  2. Right click the branch root directory and click Tortoise Git -> Create Patch Serial
    1. Choose whichever range makes sense (Since: FETCH_HEAD will work if you're well-synced)
    2. Create the patch(es)
  3. Right click the branch root directory and click Tortise Git -> Show Log
  4. Right click the commit before your temporary commit(s), and click reset "<branch>" to this...
  5. Select the Mixed option

And how to apply them:

  1. Right click the branch root directory and click Tortoise Git -> Apply Patch Serial
  2. Select the correct patch(es) and apply them
  3. Right click the branch root directory and click Tortise Git -> Show Log
  4. Right click the commit before the patch's commit(s), and click reset "<branch>" to this...
  5. Select the Mixed option
Chartreuse answered 25/3, 2012 at 22:18 Comment(1)
Technically this does require creating a commit which OP asked to avoid, but it's a temporary one and the answer is useful regardless.Gramps
H
54

To create a patch with both modified & new files (staged) you can run:

git diff HEAD > file_name.patch
Hurwit answered 13/10, 2015 at 9:17 Comment(4)
Thanks, in my case, this answer works, but git diff --cached > mypatch.patch is not working.Isar
I have a question: can file_name.patch be used by the patch command? Are they compatible with each other?Ripen
git diff + git diff --cached/staged == git diff HEAD (show all the changes since the last commit)Slinky
@RakshithRavi afaik, yes they are. you may use your patch created by git diff HEAD > file-name.patch e.g. as follows: patch --forward --strip=1 < file-name.patchIndefinable
E
32

I like:

git format-patch HEAD~<N>

where <N> is number of last commits to save as patches.

The details how to use the command are in the DOC

UPD Explanation of fix when GIT_PREFIX is called from top level Git directory

UPD
Here you can find how to apply them then.

UPD For those who did not get the idea of format-patch
Add alias:

git config --global alias.make-patch '!bash -c "cd ${GIT_PREFIX:-.};git add .;git commit -m ''uncommited''; git format-patch HEAD~1; git reset HEAD~1"'

Then at any directory of your project repository run:

git make-patch

This command will create 0001-uncommited.patch at your current directory. Patch will contain all the changes and untracked files that are visible to next command:

git status .
Epimorphosis answered 13/9, 2018 at 13:19 Comment(4)
There is a simpler way than creating a commit and uncommiting. git diff --cached --binaryNephralgia
@IgorGanapolsky: Do you notice alias? git config --global alias.make-patch ....Epimorphosis
Based on the fact that it results in paths like ../folder, it's not doing it only in the current working directory.Elroyels
Nice idea, but looks suspect if you have some files/directories that you haven't committed deliberately.Halbert
D
10

If you want to do binary, give a --binary option when you run git diff.

Degrease answered 8/10, 2012 at 5:19 Comment(0)
S
7

We could also specify the files, to include just the files with relative changes, particularly when they span multiple directories e.x.

git diff ~/path1/file1.ext ~/path2/file2.ext...fileN.ext > ~/whatever_path/whatever_name.patch

I found this to be not specified in the answers or comments, which are all relevant and correct, so chose to add it. Explicit is better than implicit!

Staphylo answered 27/1, 2020 at 12:49 Comment(0)
A
1

uncomminetted

git diff --cached > name.patch

committed (much more useful)

git diff HEAD~commit_count > name.patch
Anthropo answered 23/5, 2022 at 5:56 Comment(1)
git diff --cached outputs nothing at all , I have a bunch of changes uncommitedWainscot

© 2022 - 2024 — McMap. All rights reserved.