How to use patches?
Asked by isenwald:

Hi all, I have a problem. I am using SourceTree with git and gerrit and was wondering is it possible to apply a patch to a revision that hasn't been merged yet.

My scenario is I have a class MyClass that has some comments from the gerrit reviewer. I have made the changes but instead of pushing a new change I would like to apply a patch and push that.

I create a patch from a file and apply it to the staging area. The patch is loaded fine, the strip index is determined to be 1, however I get errors such as:

error: while searching for:  
etc. and it rejects the hunks. Any help would be greatly appreciated.


Answers:
author: stevestreeting
body: That usually means that there's been enough other changes since the patch was taken that the 'fuzz' used to locate the corresponding changes didn't manage to match. Did you generate the patch in SourceTree or elsewhere? SourceTree defaults to generating a unified diff with context of 3 lines, which is usually a good blend of being able to locate the change even if it's moved a few lines, without introducing so much context that changes around it might reject the patch.

You could look at the patch, make a note of the line numbers at the top of each hunk, and find this in your current file state. The context lines around each change should match within a few lines of the line numbers listed. If they don't, then the patch will be rejected as not matching. You can try to tweak the patch to match the new content, or apply the changes manually.

The 'error while searching for' suggests it might be just that the lines in the context areas of the patch have just moved by more lines than it looks for. Each hunk starts something like this:

```
diff --git a/path/to/some/file.txtb/path/to/some/file.txt--- a/path/to/some/file.txt+++ b/path/to/some/file.txt@@ -4325,6 +4325,7 @@
```

The part inside the '@@' markers is the lne numbers, and the '-' section refers to the state before patching, and the '+' section the state after. In both cases, the first number is the line number, and the second number is the number of lines in this hunk. So this header is saying that this hunk should apply to the old file at line 4325, and the old state had 6 lines. After modification the start is still at line 4325 (it would only be different if a previous hunk added / removed lines), but it's 7 lines long.

So if for example line 4325 didn't match the file anymore, but because of other changes this section of code was now at line 4462, you could alter both of the instances of 4325 to 4462 to correct it. It gets more complicated from the second hunk onwards because the before/after start lines might be different, but hopefully the difference will be the same.

Another option: although it's not possible in 'git apply', if you drop to the command line and use the GNU patch tool, you can use the 'fuzz' option to make it tolerate larger differences in state (see 'man patch'). This will only apply to the working copy state. However, increasing the fuzz can also cause incorrect patching so it should be used with caution.

Another other option: you could abandon this and use cherry-pick instead in a separate commit. This is smarter about intermediate changes (because it has the history graph to help resolve issues).

HTH

comments: author: isenwald
body: Thanks for the detailed answer, yes the patch was created in SourceTree.

My hunks have values such as: @@ -70,25 +70,25 @@

I.e. the left and right values are always equal. The change I made to the file doesn't include adding any new lines, it was just some punctuation changes in the comments for some of the methods I have.


author: stevestreeting
body: OK, so if you look at line 70 in that file, does the context in the patch (the 3 lines before and after the actual changes in the patch) match that? I suspect not - the issue is likely that the state of the file right now is different enough from the state at which the patch was taken from that the section it's trying to find is somewhere else. If you can find the lines in your file which DO match, say it's actually at line 85 now, then you can alter both '70' entries to '85' to make the patch apply.


author: isenwald
body: That solved it! Thanks!