148

There are plenty of programs out there that can create a diff patch, but I'm having a heck of a time trying to apply one. I'm trying to distribute a patch, and I got a question from a user about how to apply it. So I tried to figure it out on my own and found out that I have no clue, and most of the tools I can find are command-line. (I can handle a command line, but a lot of people would be lost without a nice, friendly GUI. So those are no good for this purpose.)

I tried using TortoiseSVN. I have the patch I'd like to apply. I right-click on the patch, and there's an option under the TortoiseSVN submenu that says "Apply patch." All it does is pull up an empty window.

So I tried hitting Open. It has two options: merge and apply unified diff. (The patch is in unified diff format, luckily.) But the apply option just plain doesn't work: It asks for the patch and a folder. Somehow it forgot to ask for the file to apply the patch to! So TortoiseSVN just plain doesn't work. Is there a Windows GUI-based utility that will take a patch and a file and apply it properly?

EDIT: Looking at the replies so far, it seems that Tortoise will only do it right if it's a file that's already versioned. That's not the case here. I need to be able to apply a patch to a file that did not come out of an SVN repository. I just tried using Tortoise, because I happen to know that SVN uses diffs and has to know how to both create them and apply them.

isapir
  • 21,295
  • 13
  • 115
  • 116
Mason Wheeler
  • 82,511
  • 50
  • 270
  • 477
  • WinMerge answer sounded good but only explains how to make a patch, not how to apply one. TortoiseHG has a great way to apply patches, but only to files that are in an hg repo, as far as I know. If the external SVN TortoiseDiff can't do it, I wonder if any GUI tool can. – Warren P Oct 28 '11 at 20:01
  • 3
    Wow, you are right the short answer is still no - at least in WinMerge. Feature request on WinMerge here https://sourceforge.net/tracker/index.php?func=detail&aid=695741&group_id=13216&atid=363216 – KCD Feb 15 '12 at 20:18
  • It didn't "forget" to ask for the file to apply the patch to, the filename is contained inside the patchfile. – Ben Voigt Apr 27 '21 at 16:59

23 Answers23

33

Apply Patch

With TortoiseMerge:

  1. Find and open an existing SVN repo directory
  2. Create a new directory named "merges", if it does not exist already
  3. Copy the file onto which you want to apply the .patch file
  4. ADD and COMMIT to the svn repository before you continue to the next step
  5. Right click on merges and choose Apply patch...
  6. Double click the file from list
  7. The patched file with diff is displayed on the right pane
  8. Click on that pane and hit Save or export with File->Save As...

Alternative screeny if you Open from TortoiseMerge. In the screeny below, directory refers to the "merges" directory mentioned at step 2 above: Screeny

Screenshot of WinMerge GUI: Screeny

Sheriff Md
  • 656
  • 1
  • 7
  • 11
  • @WarrenP : yes it does explain how to apply the patch using TortoiseMerge – Walter Stabosz Jul 26 '12 at 17:48
  • 4
    My comment made sense before edits, and no longer makes sense after edits. Are you confused yet? The edit timestamp above (mar 24, '11) appears to be incorrect, since the OP has edited his answer again since October 2011. I think the timestamp on my comment is wrong too. – Warren P Jul 26 '12 at 18:22
  • 10
    @SheriffMd Don't you receive the error "D:\Folder is not a working copy" ? – onmyway133 Feb 26 '13 at 11:26
  • 1
    @SheriffMd I also get the message "folder ... is not a working copy" - so, how is it possible to use tortoise merge to apply a patch to non-versioned file? – Peter T. Nov 05 '13 at 08:59
  • 1
    @onmyway133, I've rephrased the steps. Refer Step 2 and Step 4. You will not receive the "not a working copy" error message. – Sheriff Md Sep 01 '14 at 11:34
21

The patch.exe utility from the Git installation works on Windows 10.

Install Git for Windows then use the "C:\Program Files\Git\usr\bin\patch.exe" command to apply a patch.

If any error message like a Hunk #1 FAILED at 1 (different line endings). had been got on the output during applying a patch, try to add the -l (that is a shortcut for the --ignore-whitespace) or the --binary switches to the command line.

Evgeniy Generalov
  • 1,296
  • 14
  • 26
  • This question is mostly about a GUI tool for casual users who are not familiar with the typical command-line tools. Your answer would be more useful if you at least provided some full sample commands as example. – Álvaro González Dec 02 '16 at 10:20
  • Works with composer in Windows 10. – ecdani Dec 14 '18 at 12:42
21

I made pure Python tool just for that. It has predictable cross-platform behavior. Although it doesn't create new files (at the time of writing this) and lacks a GUI, it can be used as a library to create graphic tool.

UPDATE: It should be more convenient to use it if you have Python installed.

pip install patch
python -m patch
anatoly techtonik
  • 19,847
  • 9
  • 124
  • 140
18

TortoiseMerge is a separate utility that comes bundled with TortoiseSVN.

It can also be can be downloaded separately in the TortoiseDiff.zip archive. This will allow you to apply unified diffs to non-versioned files.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Paul Shannon
  • 323
  • 2
  • 6
16

I know you said you would prefer a GUI, but the commandline tools will do the work nicely. See GnuWin for a port of unix tools to Windows. You'd need the patch command, obviously ;-)

You might run into a problem with the line termination, though. The GnuWin port will assume that the patchfile has DOS style line termination (CR/LF). Try to open the patchfile in a reasonably smart editor and it will convert it for you.

Sardaukar
  • 29,034
  • 5
  • 26
  • 32
  • Well put. Wouldn't have been able to figure out the line termination problem without this comment. – Bryan Jul 29 '11 at 13:35
  • Another way to deal with the line endings is to add the "--binary" option to the command line. – brad-tot Mar 14 '13 at 15:18
  • 4
    This was what got me on the right track. However, running Windows 7 or newer you need to update the manifest of patch.exe to avoid having the UAC pop-up each time. See this page for a how-to: http://math.nist.gov/oommf/software-patchsets/patch_on_Windows7.html – Anttu Feb 05 '14 at 06:41
  • 1
    Even with the UAC fixes, the GnuWin version of patch messes up file security settings. The build shipped with git doesn't suffer from either issue. – Artfunkel Mar 07 '16 at 10:38
7

You can use this Win32 native port of the patch utility.

It comes along with a bigger selection of other utilities and in contrast to Cygwin and similar it does not need any DLLs or similar. Just pick your tiny executable of choice and store it wherever you want.

Simple usage:

patch.exe -i <patchfile>

Get more help:

patch.exe --help
RivieraKid
  • 5,923
  • 4
  • 38
  • 47
logisch
  • 79
  • 1
  • 1
  • 4
    I'm having trouble with this on Windows 7: it opens a new CMD window and prompts for administrative privileges when I attempt to run `patch.exe`. – Roy Tinker Aug 26 '13 at 17:32
  • 3
    The patch executable can also be found in the Git for Windows bundle. – Snicksie Jan 27 '14 at 08:29
  • 6
    If you are running into issues running patch.exe, you can rename it to anything that does not include `patch`. Windows considers all exes with the word `patch` to be suspect. – wbond Feb 02 '14 at 22:07
7

In TortoiseSVN, patch applying does work. You need to apply the patch to the same directory as it was created from. It is always important to keep this in mind. So here's how you do it in TortoiseSVN:

Right click on the folder you want to apply the patch to. It will present a dialog asking for the location of the patch file. Select the file and this should open up a little file list window that lists the changed files, and clicking each item should open a diff window that shows what the patch is about to do to that file.

Good luck.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Dan
  • 3,665
  • 1
  • 31
  • 39
3

I use MSYS2 from http://www.msys2.org/

It provides many utilities like patch, which, git, tree, and many more.

After installing MSYS2 simply run the package manager to install patch:

pacman -S patch
isapir
  • 21,295
  • 13
  • 115
  • 116
  • This is just a convoluted way to install a command-line tool. I suspect you only read the question title and not the question itself. :) – Álvaro González Jun 27 '17 at 09:35
2

It appears that TortoiseSVN (TortoiseMerge) requires the line Index: foobar.py in the diff/patch file. This is what I needed to do to make a non-TortoiseSVN patch file work with TortoiseSVN's right-click Apply Patch command.

Before:

--- foobar.py.org   Sat May 08 16:00:56 2010
+++ foobar.py   Sat May 08 15:47:48 2010

After:

Index: foobar.py
===================================================================
--- foobar.py
+++ foobar.py   (working copy)

Or if you know the specific revision your contributor was working from:

Index: foobar.py
===================================================================
--- foobar.py   (revision 1157)
+++ foobar.py   (working copy)
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
matt wilkie
  • 17,268
  • 24
  • 80
  • 115
2

I am already using BeyondCompare (commercial) for diffs and merges, and this tool also has the capability to create, view and apply patches.

FourtyTwo
  • 1,616
  • 2
  • 15
  • 43
2

EDIT: Looking at the replies so far, it seems that Tortoise will only do it right if it's a file that's already versioned. That's not the case here. I need to be able to apply a patch to a file that did not come out of an SVN repository. I just tried using Tortoise because I happen to know that SVN uses diffs and has to know how to both create them and apply them.

You can install Cygwin, then use the command-line patch tool to apply the patch. See also this Unix man page, which applies to patch.

Brian Clapper
  • 25,705
  • 7
  • 65
  • 65
  • 4
    Yeah, I could. I've got Cygwin, in fact. I could probably make your solution work, too. I'm not gonna put my users through that, though. You have any idea how many Windows users these days don't even know what a command line is? :P – Mason Wheeler Feb 05 '09 at 21:29
1

If you are using Mercurial, this is done via "import". So at the command line, the hg import command, or (you may find the --no-commit option useful), or "Repository" => "Import..." in Hg Workbench.

Note that these will commit the changes by default; you can avoid this using hg import --no-commit option if using the command-line, or if you used Hg Workbench, you might find it useful to issue hg rollback after the merge.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
1

Eclipse should be able to do it, go to TeamSynchronize perspective and then into Project->Apply patch

Jose Ospina
  • 2,097
  • 3
  • 26
  • 40
1

For Java projects, I have used NetBeans to apply patch files. If the Java code you are patching is not already a NetBeans project, create a project for it. To create a new project:

  • Select menu File -> New Project
  • In the resulting dialog, make it a Java Application project. Give it a name in the dialog, and click Finish.
  • Right-click the name of your project, and select Properties from the context menu
  • In the resulting dialog, select Sources, and add a Source Folder. Browse to your Java source.

Now that you have a project, apply the patch:

  • Highlight your project to select it
  • From the main menu, select menu Tools -> Apply Diff Patch
  • In the resulting dialog, browse to your patch file, select it, and press the Patch button.

That's it. Your patch should be applied, and you should see a diff window showing the changes.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
1

The patch tells it what file to apply to. The header should be something like (view it in Notepad or your fav text editor):

--- Folder/old_file
+++ Folder/new_file

In the case of a Subversion patch, you'd have revision numbers as well (since the file names are the same).

GNU patch will let you override those names, but I don't know of any GUI tools to do the same. I'd check with the various diff programs - though, it does not appear WinMerge supports applying patches.

Jeromy Anglim
  • 33,939
  • 30
  • 115
  • 173
Mark Brackett
  • 84,552
  • 17
  • 108
  • 152
  • No, there's nothing like that at the top of my patch. Are you saying that the filename and path has to be included in the diff itself? Who thought that up? What are you supposed to do if you want to distribute a diff to someone who might have things installed in other folders?!? – Mason Wheeler Feb 05 '09 at 18:52
  • The top of the patch starts out like this: --- / +++ / @@ -6,12 +6,12 @@ No filenames or anything. How is a built-in path supposed to work? What if I created the patch on XP and someone's trying to use it on Vista (or vice-versa) and the path to the Documents folder is different? – Mason Wheeler Feb 05 '09 at 18:56
  • 2
    The filenames are relative to the root directory of the repository, so XP/Vista folder structure differences don't matter. And the reason for having filenames in the patch is that most patches affect multiple files. – David Z Feb 05 '09 at 20:51
  • I see. OK, that makes more sense. Thanks for clearing that up, David! – Mason Wheeler Feb 05 '09 at 21:31
  • @MasonWheeler: A patchfile requires the filename lines. If your file doesn't have that, it's not a patchfile (it may have been created by diff -- not all combinations of command-line options to diff will create patchfiles) – Ben Voigt Apr 27 '21 at 17:03
1

Using git Diff or linux patch to apply a patch on windows using git diff

Patches created anywhere on linux, MacOS or else, using the GNU patch command or git diff can be all applied on windows using git apply.

Create the patch

For instance to create the patch from 2 directories in which 1 or more files have been changed:

diff -Naru original_dir modified_dir > 0001-path-file.patch

  • "-N" treat absent files as empty, necessary to only consider modified content
  • "-a" treat all files as text, not compulsory, needs removed if dealing - with binary patches.
  • "-r" recursive for directories traversal
  • "-u" adds 3 lines of context by default around all diffs

OR using git diff

git diff original_dir modified_dir > 0001-path-file.patch

Then copy the .patch file on the windows environment as well as the original_dir directory that contains the original unchanged files.

Apply with git diff:

1 Copy the patch file in the parent directory

2 cd into the original directory

3 Apply the patch using git apply

copy 0001-path-file.patch ..\original_dir\
cd original_dir
git apply < 0001-path-file.patch
rsacchettini
  • 121
  • 5
0

If you are getting "Not a working copy" error message then try selecting a directory from TortoiseMerge dialog box which is a working directory of SVN.

Vinod Dalvi
  • 389
  • 1
  • 4
  • 33
0

A BusyBox port for Windows has both a diff and patch command, but they only support unified format.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Meow
  • 4,341
  • 1
  • 18
  • 17
0

Just use:

patch -p0 < path-file.patch

remember execute this command only from the folder location where you created the patch.

Ashish Lohia
  • 269
  • 1
  • 12
0

When applying patches using TortoiseSVN, I typically save the path in the root of the checked out repository. You should then be able to right click on the patch, go to the TortoiseSVN menu, and click ApplyPatch. ApplyPatch should automatically figure out which level in the directory hierarchy the patch was created.

I have, however, had issues in the past with applying patches that contain new files, or which involve renames to files. Whatever algorithm Tortoise uses for this doesn't seem to handle those scenarios very well. Unicode can give you similar issues.

tsellon
  • 2,396
  • 5
  • 24
  • 33
0

If you have git install on Windows and you want to apply a patch for a git repository, you can simply do from a Windows Power Shell:

git apply ..\0001-your-patch.patch
OlivierM
  • 2,820
  • 24
  • 41
0

in response to the query earlier about patch and Python 3, I got the error TypeError: can only concatenate str (not "bytes") to str

The solution for me was to change the source, in the _normalize_filenames function:

-        debug("    target = " + p.target)
-        debug("    source = " + p.source)
+        debug("    target = ", p.target)
+        debug("    source = ", p.source)

then patch worked fine for me (Python 3, Windows 10)

0

Do you have two monitors? I was having the same issue with TortoiseMerge and I realized that when I disabled one of the monitors the little window with the file list showed up. Hope this helps you.

mercator
  • 28,290
  • 8
  • 63
  • 72
Bruno
  • 1