views:

4178

answers:

8

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. Does anyone know of 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.

+2  A: 

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

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, and please respond if you have a question on this.

That doesn't help. The destination files didn't come out of an SVN archive. (See the edit to the original post.)
Mason Wheeler
A: 

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
+1  A: 

Here's an video showing how to do it :)

l3dx
Doesn't work. It has to be in the repository first for that video to work. (See the edit to the original post.)
Mason Wheeler
+2  A: 

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.

Mark Brackett
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
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
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 Zaslavsky
I see. OK, that makes more sense. Thanks for clearing that up, David!
Mason Wheeler
A: 

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
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
You have a point there...
Brian Clapper
A: 

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
+1  A: 

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-tsvn patch file work with tsvn'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)
matt wilkie
A: 

TortoiseMerge is a seperate 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.

Paul Shannon