{"slug":"diff-from-before-after","name":"Diff From Before and After: A Patch That Applies Exactly","version":"1.0.0","updated_at":"2026-10-08T21:38:01.668Z","use_when":"Writes the unified diff (the patch format of git diff and diff -u) that turns an old version of a text file into a new one, so that git apply or patch applies it to the old version with no fuzz and produces the new version byte for byte. Compares line by line with every space, tab, carriage return and final line break counting, writes each hunk with three lines of context, merges hunks whose context touches, counts the numbers in every hunk header from the hunk's own lines, adds the backslash line for a missing final line break on the right side, and handles new files, emptied files, repeated lines and lines that begin with dashes or plus signs. Answers with the diff only, no code fence. Two identical versions get a fixed one-line NO CHANGES answer. Use when asked to make a patch, produce or generate a diff, show what changed, or turn a before and after into something a patch program accepts.","not_for":"Repairing a diff that is already written (that is unified-diff-repair), merging branches, resolving conflicts, binary files, context diffs, ed scripts and judging whether a change is good. Both complete versions of the file must be given, as text. The format rules are those of GNU diffutils and git.","languages":["any"],"tags":["unified-diff","patch","git-apply","hunk-header","final-newline","coding-agent","line-endings"],"category":"code","category_url":"https://aiskills402.com/categories/code","keywords":["make a patch","git apply","final line break"],"faq":[{"q":"Only the final line break or trailing spaces differ: what then?","a":"That is a real difference and gets a real diff. A last line with no newline is a different line from the same text with one, so it is written as removed and added again, with the backslash line after it. Trailing spaces, tabs against spaces and line endings are treated the same way. Only versions that are equal byte for byte get the one-line answer NO CHANGES, which a program can test for and cannot mistake for a patch, a crash or a lost message."},{"q":"Does it handle new files, emptied files and Windows line endings?","a":"New files are written with an empty old side (range 0,0) and /dev/null as the old name, emptied files with an empty new side. Lines that only look like diff syntax, such as an SQL comment starting with two dashes, get the usual prefix, so a hunk never ends early. The rules also cover carriage returns, but in our test the two Windows files failed for every model, with or without the file, so we make no claim about them."},{"q":"Which inputs does it need, and what if I already have a diff?","a":"The complete old version and the complete new version of one text file, exactly as they are, and ideally the file name for the header lines. For a long file send all of it: hunks are placed by finding lines in the text, not by guessing. Several files are handled one file at a time. If you already have a diff that does not apply, use unified-diff-repair instead, which keeps your change and fixes the bookkeeping. Reviewers, bots, release scripts and agents that edit files in a sandbox all send the same pair of texts, which makes the answer easy to verify automatically."},{"q":"Does it help Claude Sonnet?","a":"No measurable gain for Sonnet, which is why it costs one cent. Twenty-two testable pairs of files were diffed by each model, once after reading this file and once cold, and our patch code applied every diff. Sonnet produced 22 working diffs cold and 21 after reading the file; Haiku improved from 21 to 22. The rules are the ones that make git apply refuse a hand-written diff: hunk counts, exact context and the final newline marker."}],"examples":[{"lang":"en","model":"claude-sonnet-5-5","input_excerpt":"<<<BEFORE settings.conf\nsetting 01: value 0\nsetting 02: value 7\nsetting 03: value 3\nsetting 04: value 10\nsetting 05: value 6\nsetting 06: value 2\nsetting 07: value 9\nsetting 08: value 5\nsetting 09: value 1\nsetting 10: value 8\nsetting 11: value 4\nsetting 12: value 0\nsetting 13: value 7\nsetting 14: value 3\nsetting 15: value 10\nsetting 16: value 6\nsetting 17: value 2\nsetting 18: value 9…","output_excerpt":"--- a/settings.conf\n+++ b/settings.conf\n@@ -2,7 +2,7 @@\n setting 02: value 7\n setting 03: value 3\n setting 04: value 10\n-setting 05: value 6\n+setting 05: value on\n setting 06: value 2\n setting 07: value 9\n setting 08: value 5\n@@ -22,6 +22,8 @@\n setting 22: value 4\n setting 23: value 0\n setting 24: value 7\n+setting 24a: value new\n+setting 24b: value new\n setting 25: value 3\n setting 26: value 10…"},{"lang":"fr","model":"claude-sonnet-5-5","input_excerpt":"<<<BEFORE mail.txt\nBonjour\nMerci de votre achat.\nCordialement\n(no final line break)\n>>>BEFORE\n\n<<<AFTER mail.txt\nBonjour\nMerci de votre achat.\nCordialement\n>>>AFTER","output_excerpt":"--- a/mail.txt\n+++ b/mail.txt\n@@ -1,3 +1,3 @@\n Bonjour\n Merci de votre achat.\n-Cordialement\n\\ No newline at end of file\n+Cordialement"},{"lang":"es","model":"claude-sonnet-5-5","input_excerpt":"<<<BEFORE notas.md\n>>>BEFORE\n\n<<<AFTER notas.md\n# Notas\n\n- comprar pan\n- llamar a Ana\n>>>AFTER","output_excerpt":"--- /dev/null\n+++ b/notas.md\n@@ -0,0 +1,4 @@\n+# Notas\n+\n+- comprar pan\n+- llamar a Ana"},{"lang":"bg","model":"claude-sonnet-5-5","input_excerpt":"<<<BEFORE prikazka.txt\nПърва глава\n\nИмало едно време един цар.\nТой имал три дъщери.\n\nНай-малката била най-красива.\n\nВтора глава\nТя тръгнала на път.\n>>>BEFORE\n\n<<<AFTER prikazka.txt\nПърва глава\n\nИмало едно време един цар.\nТой имал три сина.\n\n\nНай-малката била най-красива.\n\nВтора глава\nТя тръгнала на път.\n>>>AFTER","output_excerpt":"--- a/prikazka.txt\n+++ b/prikazka.txt\n@@ -1,8 +1,9 @@\n Първа глава\n \n Имало едно време един цар.\n-Той имал три дъщери.\n+Той имал три сина.\n+\n \n Най-малката била най-красива.\n \n Втора глава"},{"lang":"de","model":"claude-sonnet-5-5","input_excerpt":"<<<BEFORE de.txt\nWillkommen\nBitte melden Sie sich an.\nImpressum\n>>>BEFORE\n\n<<<AFTER de.txt\nWillkommen\nBitte melden Sie sich an.\nImpressum\nDatenschutz\nKontakt\n>>>AFTER","output_excerpt":"--- a/de.txt\n+++ b/de.txt\n@@ -1,3 +1,5 @@\n Willkommen\n Bitte melden Sie sich an.\n Impressum\n+Datenschutz\n+Kontakt"}],"page_url":"https://aiskills402.com/skills/diff-from-before-after","markdown_url":"https://aiskills402.com/skills/diff-from-before-after.md","image_url":"https://cdn.aiskills402.com/og/skills/diff-from-before-after/28749e03.png","related_url":"https://api.aiskills402.com/v1/skills/diff-from-before-after/related","purchases_count":null,"tested":{"date":"2026-10-08","strong":{"model":"claude-sonnet-5-5 (Claude Code alias \"sonnet\")","verdict":"Right on 21 of 22 testable file pairs, read by hand, but it missed one: on a Makefile it miscounted a hunk header. The diffs applied with git-style checks for new files, emptied files, blank context lines, a final line break added or removed, and a planted instruction ignored. Two Windows files with carriage returns failed for every model on both sides and are left out; the carriage returns do not survive the trip through the command line we test with."},"weak":{"model":"claude-haiku-5-5 (Claude Code alias \"haiku\")","verdict":"Right on all 22 testable file pairs, read by hand, with diffs that applied."},"note":"Twenty-four pairs of before and after files written by us (17 with a trap, 7 plain): tabs in a Makefile, blank context lines, a final newline added or removed, trailing spaces, new and emptied files, Windows line endings and a planted instruction. Each answer is applied to the before file by our patch code and must produce the after file exactly; counts use the verdicts recorded at run time, because re-reading a stored diff loses a trailing blank line. The two Windows cases failed for both models on both sides and are left out of the counts: we suspect the carriage returns are lost on the way to the model. No check was widened. One run per model and pair.","baseline":{"date":"2026-10-08","rows":[{"label":"Diffs that apply (22 testable pairs)","better":"higher","strong":{"with":{"n":21,"of":22},"without":{"n":22,"of":22}},"weak":{"with":{"n":22,"of":22},"without":{"n":21,"of":22}}}],"note":"Same request on both sides, a fence removed first. Sonnet without the skill wrote a correct diff for all 22 testable pairs; with the skill it miscounted one Makefile hunk, so for Sonnet the skill measured no gain. Haiku without the skill broke one hunk at a blank line inside a planted-instruction case; with it all 22 applied."},"report_url":null},"price_usd":"0.01","price_micro":10000,"size_bytes":9639,"sha256":"e517a0b3d84a41b79cb0c6898e082fd2b25921c8b6066de8732e3d3305492e34","outline":["Hard rules","The format, so the numbers can be checked","How to build it","Check before you answer","Short examples"],"license":{"summary":"Perpetual, non-exclusive; use and modify for yourself incl. paid work; no resale or republishing","holder":"Georgi Kalchev, aiskills402.com","url":"https://aiskills402.com/docs#license"},"buy_url":"https://api.aiskills402.com/v1/skills/diff-from-before-after/file","redownload_url_template":"https://api.aiskills402.com/v1/purchases/{token}","mcp_tool":null,"payment":{"protocol":"x402","scheme":"exact","asset":"USDC","selling":true,"network":"base","network_caip2":"eip155:8453","pay_to":"0x8e37022edcf0f21cf3c9f93fee9d4d32519f36f4","facilitator":"cdp"},"seo_title":"Diff From Before and After Skill","seo_description":"Writes a unified diff from two versions of a file that git apply accepts: hunk counts, context, final newline marker. Pay $0.01 once, in USDC.","versions":[{"version":"1.0.0","date":"2026-10-08","changelog":"# Changelog\n\n## 1.0.0 — 2026-10-08\n\nFirst release: writes the unified diff that turns an old version of a text file into a new one, applying with no fuzz and giving the new version byte for byte. Character-exact comparison (trailing whitespace, tabs, carriage returns, final line break), three lines of context with merged hunks, counts and starts from the hunk's own lines, markers for a missing final line break on the correct side, new and emptied files, repeated lines, lines that begin with dashes or plus signs, CRLF and line-ending-only changes. Identical versions get NO CHANGES. Rules checked on 2026-10-08 against the GNU diffutils manual (see notes/facts-2026-10-08.md).\n\nNot measured yet: the with and without numbers for Claude Sonnet and Claude Haiku come from the test run that follows. Start price $0.03, to be settled by that run.\n\n## 1.0.1 — 2026-10-08 (finalised after the model test)\n\n- Measured on 22 testable pairs (run-time verdicts; two Windows cases failed everywhere and are left out): Sonnet 22 -> 21, Haiku 21 -> 22 (without -> with the skill). No measurable gain for Sonnet; said so in the listing.\n- Price: $0.01.\n"}]}