Apply a Unified Diff to a File

Paste the file and the patch; get the patched text back. Unapply a diff in reverse, tolerate drifted context with fuzz, and see exactly which hunks conflicted.

Try:
Patched file

About this tool

A unified diff describes a change; this tool performs it. Paste the file as it is now and the patch from git diff, git show, git format-patch, diff -u, or svn diff, and get the patched text back — no repository, no working tree, no upload. It is the other half of a diff viewer: instead of showing what a patch would do, it does it and tells you where every hunk landed.

Worked example — this file:

fn main() {
    let x = 1;
    println!("{x}");
}

with this patch:

--- a/src/main.rs
+++ b/src/main.rs
@@ -1,4 +1,5 @@
 fn main() {
     let x = 1;
+    let y = 2;
     println!("{x}");
 }

produces:

fn main() {
    let x = 1;
    let y = 2;
    println!("{x}");
}

Tick Reverse and paste the patched file instead to get the original back — the same patch, run backwards, the way git apply -R reverts a change.

When the file has moved on

A patch rarely matches its file byte for byte forever. Three controls handle the usual drift:

Conflicts

Set Output to Dry-run report for a git apply --check-style pass that changes nothing:

1 of 2 hunks applied · list.txt

 [1] @@ -1,2 +1,3 @@  applied at line 1
 [2] @@ -6,2 +7,2 @@  FAILED — expected `NOPE` at line 6, found `foxtrot`

1 hunk failed. Set output=rejects for those hunks as a patch, or on_conflict=skip to apply the rest.

On conflict defaults to fail, so you never get a half-applied file by accident — the error names the hunk, the line it expected and the line it actually found. Switch it to skip to apply every hunk that does match, then set Output to Rejected hunks to get the leftovers as a standalone patch you can fix by hand. JSON result returns the same information as data: a status, landing line, offset and fuzz per hunk, plus the patched text.

Multi-file patches

This tool patches one pasted file. If the diff touches several paths, put one of them in File in a multi-file patch — a full path, a bare filename, or any substring. With no filter, a multi-file patch lists the paths it found instead of guessing which one your text is. To split a large patch first, use a diff hunk selector; to produce a diff from two texts, use a text diff tool.

Limits and edge cases

FAQ

Does this change any file on my computer or in my repository?

No. It reads the two texts you paste and returns a third one. Copy the result back into your editor yourself — which is also why a bad patch here costs you nothing.

What is the difference between fuzz and offset?

Offset means the hunk matched perfectly, just at a different line number than its header claimed — that is always allowed and always reported. Fuzz means the context did not match perfectly, so the tool ignored up to that many context lines at each end of the hunk to place it. A hunk applied with fuzz deserves a second look; a hunk applied with only an offset does not.

Why did my patch fail when `git apply` accepts it?

The most common causes are a source file that has drifted (raise fuzz or turn on ignore whitespace), indentation changed between tabs and spaces (ignore whitespace), or a multi-file patch where the pasted text is a different file than the hunks target (set the file filter). The failure message names the line the hunk expected and the line found in its place, which usually identifies which of the three it is.

Can I recover the original file from a patched one?

Yes — paste the patched file, paste the same diff, and tick Reverse. The + and - sides swap roles, so the change is undone. This is the same operation as git apply -R or patch -R, and it is how you revert a commit's diff without the commit.

What does the rejected-hunks output give me?

The hunks that did not apply, re-emitted as a valid unified diff with file headers and recounted @@ ranges — the equivalent of the .rej file patch --reject writes. Fix the context by hand, then run it through this tool again.

Does it handle patches with no `---`/`+++` headers?

Yes. Bare @@ hunks pasted out of a code review or a chat message are accepted; the file is simply labelled as having no file header in the report. diff --git, index, and mail-style preambles are also understood and ignored where they carry no hunks.

Developer & Automation Access

Run it from the terminal

Same engine as this page, headless — via the gizza CLI:

gizza tool apply-patch 'fn main() {
    let x = 1;
    println!("{x}");
}' 'patch=--- a/src/main.rs
+++ b/src/main.rs
@@ -1,4 +1,5 @@
 fn main() {
     let x = 1;
+    let y = 2;
     println!("{x}");
 }'

New to the CLI? Get gizza →

Open it by URL

Pre-fill and auto-run this tool with query parameters — the names match the API/CLI:

https://gizza.ai/tools/apply-patch/?source=fn%20main%28%29%20%7B%0A%20%20%20%20let%20x%20%3D%201%3B%0A%20%20%20%20println%21%28%22%7Bx%7D%22%29%3B%0A%7D&patch=---%20a%2Fsrc%2Fmain.rs%0A%2B%2B%2B%20b%2Fsrc%2Fmain.rs%0A%40%40%20-1%2C4%20%2B1%2C5%20%40%40%0A%20fn%20main%28%29%20%7B%0A%20%20%20%20%20let%20x%20%3D%201%3B%0A%2B%20%20%20%20let%20y%20%3D%202%3B%0A%20%20%20%20%20println%21%28%22%7Bx%7D%22%29%3B%0A%20%7D&output=patched&reverse=true&fuzz=2&ignore_whitespace=true&on_conflict=fail&file=src%2Fmain.rs

Machine-readable descriptor: tool.json — title + parameters JSON Schema for agents.