{"id":10001,"date":"2025-03-24T06:42:18","date_gmt":"2025-03-24T10:42:18","guid":{"rendered":"https:\/\/www.both.org\/?p=10001"},"modified":"2025-03-24T07:53:51","modified_gmt":"2025-03-24T11:53:51","slug":"create-a-patch-from-differences-in-a-file-with-the-diff-and-patch-commands","status":"publish","type":"post","link":"https:\/\/www.both.org\/?p=10001","title":{"rendered":"Create a patch from differences in a file with the diff and patch commands"},"content":{"rendered":"<div class=\"pld-like-dislike-wrap pld-template-1\">\r\n    <div class=\"pld-like-wrap  pld-common-wrap\">\r\n    <a href=\"javascript:void(0)\" class=\"pld-like-trigger pld-like-dislike-trigger  \" title=\"\" data-post-id=\"10001\" data-trigger-type=\"like\" data-restriction=\"cookie\" data-already-liked=\"0\">\r\n                        <i class=\"fas fa-thumbs-up\"><\/i>\r\n                <\/a>\r\n    <span class=\"pld-like-count-wrap pld-count-wrap\">    <\/span>\r\n<\/div><\/div>\n<p>When you collaborate on a digital project with someone, it&#8217;s a guarantee that eventually someone&#8217;s going to need to send you changes they&#8217;ve made to a file.<\/p>\n\n\n\n<p>As websites and web browsers have become more complex, some useful methods have been developed to help you track and apply changes to a file. There&#8217;s live collaborative editing, there are source code management systems like Git, and version tracking systems. But there&#8217;s an older system that&#8217;s less interactive than many of the tools you find in a web browser, but it&#8217;s also not dependent on a complex software stack. Instead, you can use the local <code>diff<\/code> and <code>patch<\/code>commands to generate differentials (a &#8220;diff&#8221;) and then merge (or &#8220;patch&#8221;) changes into an existing file.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Setup<\/h2>\n\n\n\n<p>First, create an example file containing every other like of the first two stanzas of William Blake&#8217;s poem <a href=\"https:\/\/en.wikipedia.org\/wiki\/The_Tyger\">Tyger<\/a>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>In the forests of the knight;\nCould frame thy fearful symmetry?\n\nIn what distant deeps or skies.\nOn what wings dare he aspire?<\/code><\/pre>\n\n\n\n<p>For a little extra variety, I&#8217;ve introduced a typo in the first line.<br>Instead of <code>night<\/code>, I&#8217;ve typed <code>knight<\/code>.<\/p>\n\n\n\n<p>Save this file as <code>poem.txt<\/code> in a directory called <code>blake<\/code>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">1. Make a copy of the file, and modify it<\/h2>\n\n\n\n<p>Suppose you were collaborating on a project and noticed that William Blake&#8217;s poem had been incorrectly transcribed.<\/p>\n\n\n\n<p>First, make a copy of the project directory. This usually happens as a natural part of sharing files collaboratively. When someone makes a file available on a shared server or sends you a file over email, they don&#8217;t delete their copy of the file. You&#8217;re working on a copy because that&#8217;s just how digital technology works. Git, for example, stores a copy of every committed file whether you think about it or not. You need the original version of the file handy in order to make a diff, however, so for this example, make a copy of the project directory <em>as you received it<\/em> so you can compare your end result with the directory as it was before you started working on it:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ cp -r blake blake-revision<\/code><\/pre>\n\n\n\n<p>Change directory to your version of the project:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ cd blake-revision<\/code><\/pre>\n\n\n\n<p>Add the missing lines of the poem:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Tyger Tyger, burning bright,\nIn the forests of the night;\nWhat immortal hand or eye,\nCould frame thy fearful symmetry?\n\nIn what distant deeps or skies.\nBurnt the fire of thine eyes?\nOn what wings dare he aspire?\nWhat the hand, dare seize the fire?<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">2. Create a diff<\/h2>\n\n\n\n<p>You can create a diff of a single file or for an entire directory. It&#8217;s usually easiest to make a diff of an entire directory.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ diff --unified --recursive --new-file \\\nblake blake-revision &gt; my.patch<\/code><\/pre>\n\n\n\n<p>One of the nice things about a patch file is that it&#8217;s human-readable. The recipient technically doesn&#8217;t even need to use <code>patch<\/code> to apply the changes, because the changes are provided as plain text notation. You can look at it for yourself:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ cat my.patch \ndiff --unified --recursive --new-file blake\/poem.txt blake-revision\/poem.txt\n--- blake\/poem.txt      2025-03-18 15:44:51.382188010 +1300\n+++ blake-revision\/poem.txt     2025-03-18 15:02:57.398577083 +1300\n@@ -1,4 +1,9 @@\n-In the forests of the knight;\n+Tyger Tyger, burning bright,\n+In the forests of the night;\n+What immortal hand or eye,\n Could frame thy fearful symmetry?\n+\n In what distant deeps or skies.\n+Burnt the fire of thine eyes?\n On what wings dare he aspire?\n+What the hand, dare seize the fire?<\/code><\/pre>\n\n\n\n<p>As you can see, the patch file identifies the location of the two files compared, and then details what must be done to <code>blake\/poem.txt<\/code> to make it match the <code>blake-revision\/poem.txt<\/code> file. A minus sign (<code>-<\/code>) at the start of a line indicates that the line must be removed. A plus sign (<code>+<\/code>) at the start of a line indicates that a line must be added. It&#8217;s entirely linear, moving from line to line and making whatever adjustment is necessary.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">3. Patch<\/h2>\n\n\n\n<p>Move the <code>blake-revision<\/code> directory to your system trash. Assume that instead of creating <code>my.patch<\/code>, you&#8217;ve just received it from a collaborator, along with an email noting that your copy of William Blake&#8217;s poem was incomplete (and contained a typo). Don&#8217;t worry, though, your collaborator has made the necessary corrections, contained in <code>my.patch<\/code>.<\/p>\n\n\n\n<p>To make your version of Blake&#8217;s poem match your collaborator&#8217;s version, you use the <code>patch<\/code> command. There&#8217;s a catch, though. Your collaborator was working in a directory called <code>blake-revision<\/code>, which doesn&#8217;t exist on your system. You have a directory named <code>blake<\/code>. This produces a non-fatal error, which you can see for yourself by running <code>patch<\/code> with no extra options. Run the command from the directory <em>containing<\/em> the <code>blake<\/code> folder (do not change directory into <code>blake<\/code>):<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ patch &lt; my.patch\n\ncan't find file to patch at input line 4\nPerhaps you should have used the -p or --strip option?\nThe text leading up to this was:\n--------------------------\n|diff --unified --recursive --new-file blake\/poem.txt blake-revision\/poem.txt\n|--- blake\/poem.txt     2025-03-18...\n|+++ blake-revision\/poem.txt    2025-03-18...\n--------------------------\nFile to patch:<\/code><\/pre>\n\n\n\n<p>Press <strong>Ctrl+C<\/strong> to cancel.<\/p>\n\n\n\n<p>The <code>patch<\/code> command is robust and can recover from small path errors, but it&#8217;s even easier to avoid the error altogether. When the base directory of the <em>new<\/em> version of a file doesn&#8217;t exist on your system, you can make <code>patch<\/code> ignore (or &#8220;strip&#8221;) one or more directories leading up to your target file. Confusingly, <code>patch<\/code> starts counting at zero, so to strip the first directory from the path, you must actually strip the zeroeth directory.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ patch --strip 0 &lt; my.patch\npatching file blake\/poem.txt<\/code><\/pre>\n\n\n\n<p>Take a look at the new version of your file:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ cat blake\/poem.txt\nTyger Tyger, burning bright,\nIn the forests of the night;\nWhat immortal hand or eye,\nCould frame thy fearful symmetry?\n\nIn what distant deeps or skies.\nBurnt the fire of thine eyes?\nOn what wings dare he aspire?\nWhat the hand, dare seize the fire?<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Diff and patches tips and tricks<\/h2>\n\n\n\n<p>If you&#8217;re a Git user, then creating diffs and applying patches is technically already part of your daily workflow. If you&#8217;re accustomed to working in LibreOffice or Google Doc files, then this might seem inconvenient. As someone who uses diffs and patches both inside and outside of Git, I have a few tips on how to make diffs and patches <em>easier<\/em> than tracking changes in word processor documents.<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Write in Commonmark (Markdown) or Asciidoc. These formats don&#8217;t require a word processor, just a text editor.<\/li>\n\n\n\n<li>It feels strange at first, but write each sentence on a new line. This way, your diff can make small corrections by replacing just a line, instead of having to replace a whole paragraph.<\/li>\n\n\n\n<li>Make a working copy early. I&#8217;ve definitely been guilty of opening a project directory with the intent to make no changes, but of course that never happens. There&#8217;s always a mistake somewhere.<\/li>\n\n\n\n<li>Use source control management, like Git or Fossil, and let it handle diffs and patches!<\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\">Daily workflow<\/h2>\n\n\n\n<p>Make a copy, make your changes, make a diff.<\/p>\n\n\n\n<p>That&#8217;s the workflow, and it really is that simple.<\/p>\n\n\n\n<p>There have been times when I&#8217;ve received a proposed patch for a project that&#8217;s 90% good, and 10% not something I want to incorporate. I use GNU Emacs to edit the patch file because it calculates and updates the unified patch header data for me, so I can change the patch and apply it. You can selectively accept changes with Git, but this is a direct method of cherry-picking, and sometimes the direct method is faster.<\/p>\n\n\n\n<p>If you&#8217;re tired of the overhead of tracking changes your current collaboration solution imposes, consider giving <code>diff<\/code> and <code>patch<\/code> a try.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>When you collaborate on a digital project with someone, it&rsquo;s a guarantee that eventually someone&rsquo;s going to need<\/p>\n","protected":false},"author":31,"featured_media":9101,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_lmt_disableupdate":"","_lmt_disable":"","footnotes":""},"categories":[149,402,218,80,178],"tags":[104,108],"class_list":["post-10001","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-bash","category-documentation","category-text-editors","category-tips-and-tricks","category-tools","tag-command-line","tag-open-source"],"modified_by":"David Both","_links":{"self":[{"href":"https:\/\/www.both.org\/index.php?rest_route=\/wp\/v2\/posts\/10001","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.both.org\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.both.org\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.both.org\/index.php?rest_route=\/wp\/v2\/users\/31"}],"replies":[{"embeddable":true,"href":"https:\/\/www.both.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=10001"}],"version-history":[{"count":3,"href":"https:\/\/www.both.org\/index.php?rest_route=\/wp\/v2\/posts\/10001\/revisions"}],"predecessor-version":[{"id":10015,"href":"https:\/\/www.both.org\/index.php?rest_route=\/wp\/v2\/posts\/10001\/revisions\/10015"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.both.org\/index.php?rest_route=\/wp\/v2\/media\/9101"}],"wp:attachment":[{"href":"https:\/\/www.both.org\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=10001"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.both.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=10001"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.both.org\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=10001"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}