275

I work on WordPress based project and I want to patch my project at each new release version of WP. For this, I want generate a patch between two commits or tags.

For example, in my repo /www/WP I do this:

$ git patch-format com1..com2 --stdout > '~/patchs/mypatch.patch'

# or

$ git patch-format tag1..tag2 --stdout > '~/patchs/mypatch.patch'

/www/WP git natif WordPress

/www/myproject My git project WordPress based

The git apply command line doesn't work, I think because we are in different repositories.

Can I generate a patch file without a commit, just a differential and apply it to another git repository?

crmpicco
  • 16,605
  • 26
  • 134
  • 210
zatamine
  • 3,458
  • 3
  • 25
  • 33

6 Answers6

405

You can just use git diff to produce a unified diff suitable for git apply:

git diff tag1..tag2 > mypatch.patch

You can then apply the resulting patch with:

git apply mypatch.patch
Enrico Campidoglio
  • 56,676
  • 12
  • 126
  • 154
  • 1
    Thank you Enrico, I used `$git diff -u tag1..tag2 > mypatch.patch` and `$git apply --stat > mypatch.patch` the answer is `0 files changed` any other suggestion please ? :) – zatamine Jan 28 '15 at 13:48
  • You need to specify the path to the patch file as an argument of `git apply`. I updated my answer with an example. – Enrico Campidoglio Jan 28 '15 at 23:05
  • 5
    I used `git diff -p tag1 tag2 > my.patch` which worked well. – barclay Jan 19 '18 at 20:30
  • How do I make patches in unified diff format? https://sourceware.org/glibc/wiki/Contribution%20checklist#Proper_Formatted_Unified_diff_of_the_Changes says `Only unified diff (-uNr) format is acceptable.` but when I try `git diff -uNr tag1..tag2 > mypatch.patch` I get the message `usage: git diff [] [ []] [--] [...]` – Aaron Franke Apr 23 '18 at 05:22
  • if you use VSCode and preffer GUI then this plugin will also work https://marketplace.visualstudio.com/items?itemName=paragdiwan.gitpatch – harsh zalavadiya Aug 24 '18 at 15:09
  • In my case I had a new repo and wanted to create a patch with all the changes from beginning , tagged the first commit 0.0.1 and last one as 0.0.2 and then created a patch with ```git diff 0.0.1 0.0.2 > changes.patch``` – Mahtab Alam Sep 24 '18 at 05:18
  • 6
    Be careful `git diff ...` + `git apply ...` do not handle deleted / moved files properly ... when `git format-patch ...` + `git am ...` do. – Thomas Vincent Jan 08 '20 at 13:32
  • I think this doesn‘t work with binary files. – erikbstack Sep 07 '22 at 13:09
  • Also can be useful: `git apply --ignore-space-change --ignore-whitespace mypatch.patch` – Yeheshuah Dec 09 '22 at 05:26
73

To produce patch for several commits, you should use format-patch git command, e.g.

git format-patch -k --stdout R1..R2

This will export your commits into patch file in mailbox format.

To generate patch for the last commit, run:

git format-patch -k --stdout HEAD~1

Then in another repository apply the patch by am git command, e.g.

git am -3 -k file.patch

See: man git-format-patch and git-am.

evandrix
  • 6,041
  • 4
  • 27
  • 38
kenorb
  • 155,785
  • 88
  • 678
  • 743
  • 1
    What about a patch that can be applied with `patch -p1`? https://sourceware.org/glibc/wiki/Contribution%20checklist#Proper_Formatted_Unified_diff_of_the_Changes – Aaron Franke Apr 23 '18 at 05:23
  • I was moving patch from linux to winodws, so had to use --ignore-whitespace as mentioned here https://stackoverflow.com/questions/13190679/error-while-applying-a-patch-in-git – Mahesh Jun 06 '18 at 10:46
  • 2
    @AaronFranke, you can try '-p' option: git format-patch -p HEAD^1 – Piroxiljin Jan 16 '19 at 06:29
  • Of note, this has the advantage of keeping the commit messages, author, & commit dates of the original commits. – M. Justin Feb 27 '20 at 16:07
  • `--stdout` would dump the output into the terminal, which you'd need to pipe using `> file.patch`. Alternatively, if you don't include `--stdout` it generates files in the format `nnnn-commt-message.patch` (where `nnnn` is a rolling number starting from `0001`). – ADTC Oct 14 '21 at 07:10
  • 1
    Also, kindly explain the options `-3` and `-k` in your answer. Personally I don't think `-k` is necessary here but I'm not too sure about `-3`. – ADTC Oct 14 '21 at 12:38
  • I share @ADTC's reaction. Fwiw, **format-patch**: _`-k, --keep-subject` Do not strip/add [PATCH] from the first line of the commit log message_ and **am**: _`-k, --keep` Pass -k flag to git mailinfo (see [git-mailinfo(1)](https://linux.die.net/man/1/git-mailinfo))_ [seems same as previous -k] and _`-3, --3way` When the patch does not apply cleanly, fall back on 3-way merge_. Imo, a 3-way merge for conflicts is always a good idea, as you can handle conflicts like you would in your normal workflow instead of the command failing, eg. `-k` seems take it or leave it, subjective preference. – ruffin Apr 26 '22 at 17:49
51

You can apply two commands

  1. git diff --patch > mypatch.patch // to generate the patch`
  2. git apply mypatch.patch // to apply the patch`
3

As a complementary, to produce patch for only one specific commit, use:

git format-patch -1 <sha>

When the patch file is generated, make sure your other repo knows where it is when you use git am ${patch-name}

Before adding the patch, use git apply --check ${patch-name} to make sure that there is no confict.

Eugene
  • 10,627
  • 5
  • 49
  • 67
2

You even can do patches only for sub directory you are currently in. Just add .

git format-patch -k b365cce8..80a2c18a .

Then you can apply them:

git am *.patch

See this answer for details

Eugen Konkov
  • 22,193
  • 17
  • 108
  • 158
0

Make use of this command.

git diff master..localbranch > file.patch