{"id":14,"date":"2006-08-22T17:13:00","date_gmt":"2006-08-23T00:13:00","guid":{"rendered":"http:\/\/porkrind.org\/missives2\/?p=14"},"modified":"2015-02-20T22:58:38","modified_gmt":"2015-02-21T06:58:38","slug":"commit-patch-managing-your-mess","status":"publish","type":"post","link":"https:\/\/porkrind.org\/missives\/commit-patch-managing-your-mess\/","title":{"rendered":"&#8220;Commit Patch&#8221;: Managing your mess"},"content":{"rendered":"<p>I consider myself to be chaotically organized. If you look at my workbench you&#8217;ll see stacks of papers and half finished projects. However, when I finally clean up I end up filing things away meticulously.<\/p>\n<p>The same chaos applies to my development work. If I&#8217;m working on a bug or a new feature I end up making other random enhancements or fixes that aren&#8217;t at all related (except for the fact that they exist in the same file). Judging from other people I&#8217;ve worked with, I&#8217;m hardly alone in this behavior.<\/p>\n<p>The problem comes when I&#8217;m ready to become organized and check in my work (the software equivalent of &#8220;file things away meticulously&#8221;). Version control systems don&#8217;t cater to the messy development model. Take CVS and Mercurial: They only let you commit a whole file at a time, not just pieces of it. Darcs is better, as it allows you to commit pieces of a file, but even it doesn&#8217;t let you commit just one part of a single line.<\/p>\n<p>Why would anyone want to do this? Look at this made up example:<\/p>\n<pre><code class=\"language-c\"> void player_died()\r\n {\r\n     game_over(score);\r\n     char x[50];\r\n     get_name(x);\r\n     add_high_score(x, score);\r\n }\r\n<\/code><\/pre>\n<p>Say I need to change the way get_name() works\u2014I need to make sure I don&#8217;t overrun my buffer. While I&#8217;m doing that I decide that &#8220;x&#8221; is a really stupid name for the variable, so I fix that too. The code now looks like:<\/p>\n<pre><code class=\"language-c\"> void player_died()\r\n {\r\n     game_over(score);\r\n     char name[50];\r\n     get_name(name, sizeof(name));\r\n     add_high_score(name, score);\r\n }\r\n<\/code><\/pre>\n<p>Fine. But now I have 2 unrelated changes that touch the same source line. In the past I&#8217;d just check them both in with a comment like this:<\/p>\n<pre><code> - Pass in length with high score string storage.\r\n - x -&gt; name for clarity.\r\n<\/code><\/pre>\n<p>Enter <a href=\"http:\/\/porkrind.org\/commit-patch\/.\">commit-patch<\/a> With <a href=\"http:\/\/porkrind.org\/commit-patch\/,\">commit-patch<\/a> I now can precisely specify the patch I want to commit and leave the rest behind as uncommitted changes in my working directory.<\/p>\n<h2>Ok, so how does it work?<\/h2>\n<p>First I use emacs to get a diff (I make sure I have an emacs library for whatever version control system I&#8217;m using). Here&#8217;s an example of what darcs might show me:<\/p>\n<pre><code> diff -rN -u old-test\/game.c new-test\/game.c\r\n --- old-test\/game.c     2006-08-22 23:09:44.000000000 -0700\r\n +++ new-test\/game.c     2006-08-22 23:09:44.000000000 -0700\r\n @@ -1,8 +1,8 @@\r\n  void player_died()\r\n  {\r\n      game_over(score);\r\n -    char x[50];\r\n -    get_name(x);\r\n -    add_high_score(x, score);\r\n +    char name[50];\r\n +    get_name(name, sizeof(name));\r\n +    add_high_score(name, score);\r\n  }\r\n<\/code><\/pre>\n<p>Emacs has diff-mode which makes editing patches trivial. I now edit it down to this:<\/p>\n<pre><code> --- old-test\/game.c 2006-08-22 23:11:52.000000000 -0700\r\n +++ new-test\/game.c 2006-08-22 23:11:52.000000000 -0700\r\n @@ -1,8 +1,8 @@\r\n  void player_died()\r\n  {\r\n      game_over(score);\r\n      char x[50];\r\n -    get_name(x);\r\n +    get_name(x, sizeof(x));\r\n      add_high_score(x, score);\r\n  }\r\n<\/code><\/pre>\n<p>Now I can check this in with <a href=\"http:\/\/porkrind.org\/commit-patch\/\">commit-patch<\/a> (along with the corresponding change in the get_name() function&#8217;s file). Since I&#8217;m using emacs I can just use the &#8220;C-c C-c&#8221; key sequence in any diff-mode buffer which runs <a href=\"http:\/\/porkrind.org\/commit-patch\/\">commit-patch<\/a> for me. Or I could save the patch out to a file and run <a href=\"http:\/\/porkrind.org\/commit-patch\/\">commit-patch<\/a> from the command line. Either way, it commits only what was in the the patch and leaves the working directory effectively untouched. To demonstrate, my diff after I&#8217;ve committed the above patch looks like this:<\/p>\n<pre><code> diff -rN -u old-test\/game.c new-test\/game.c\r\n --- old-test\/game.c     2006-08-23 14:58:54.000000000 -0700\r\n +++ new-test\/game.c     2006-08-23 14:58:54.000000000 -0700\r\n @@ -1,8 +1,8 @@\r\n  player_died()\r\n  {\r\n      game_over(score);\r\n -    char x[50];\r\n -    get_name(x, sizeof(x));\r\n -    add_high_score(x, score);\r\n +    char name[50];\r\n +    get_name(name, sizeof(name));\r\n +    add_high_score(name, score);\r\n  }\r\n<\/code><\/pre>\n<p>Now I can check in the file again, this time for just the variable name change.<\/p>\n<p><a href=\"http:\/\/porkrind.org\/commit-patch\/\">commit-patch<\/a> allows you to keep your commits short and to the point instead of forcing you to check in a bunch of unrelated changes just because they happen to be in the same file (or the same line). It relies on you editing patches which I admit can be scary at first, but after a few times you really start to get the hang of it. I now always look over the diff of my uncommitted changes and weed out stupid changes in my code\u2014debug prints, commented out dead code, and all the other junk I shouldn&#8217;t check in.<\/p>\n<h2>Ok, sounds great, what are the downsides?<\/h2>\n<p>Glad I asked. Checking in patches effectively means checking in untested code. Despite your best intentions, you can screw up the code when editing a patch. Generally the projects I work on where this really matters all have internal infrastructure to make sure builds work. One project I am involved with that uses CVS has an auto-builder to check for broken code. Another large darcs project I deal with requires &#8216;make&#8217; to run successfully before it accepts a patch. Both of these provide good enough insulation for bad patches. The truth is, I&#8217;ve been using <a href=\"http:\/\/porkrind.org\/commit-patch\/\">commit-patch<\/a> for a few years now and I <em>rarely<\/em> have accidental errors checked in that were caused by bad patch editing. I would say I&#8217;m more likely to forget to check in a file completely than I am to check in a bad patch.<\/p>\n<p>The only other downside is that it requires you to be able to edit patches. I use emacs which makes it pretty trivial. If you are not an emacs user then you&#8217;d have to look around and see what other patch editing options are out there. I honestly don&#8217;t know what other tools exists. So if you consider needing to use emacs a downside, then there you go. If you don&#8217;t, well then I salute you. \ud83d\ude42<\/p>\n<h2>Conclusion<\/h2>\n<p><a href=\"http:\/\/porkrind.org\/commit-patch\/\">commit-patch<\/a> fits my development style like a glove. I frankly cannot imagine working on a project without it any more. That is an interesting statement because before we wrote it, Jim and I felt that it would be a script we would use only occasionally. But once I started using it I found more and more situations where it would be useful.<\/p>\n<p>I think <a href=\"http:\/\/porkrind.org\/commit-patch\/\">commit-patch<\/a> is one of those tools that you don&#8217;t realize you need until it suddenly becomes indispensable. So do yourself a favor and try it out for a week or two.<\/p>\n<h1><a href=\"http:\/\/porkrind.org\/commit-patch\/\">Get commit-patch here<\/a><\/h1>\n","protected":false},"excerpt":{"rendered":"<p>If I&#8217;m working on a bug or a new feature I end up making other random enhancements or fixes that aren&#8217;t at all related. With commit-patch, I now can precisely specify the patch I want to commit and leave the rest behind as uncommitted changes in my working directory.<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[3],"tags":[],"class_list":["post-14","post","type-post","status-publish","format-standard","hentry","category-software"],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/porkrind.org\/missives\/wp-json\/wp\/v2\/posts\/14","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/porkrind.org\/missives\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/porkrind.org\/missives\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/porkrind.org\/missives\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/porkrind.org\/missives\/wp-json\/wp\/v2\/comments?post=14"}],"version-history":[{"count":8,"href":"https:\/\/porkrind.org\/missives\/wp-json\/wp\/v2\/posts\/14\/revisions"}],"predecessor-version":[{"id":169,"href":"https:\/\/porkrind.org\/missives\/wp-json\/wp\/v2\/posts\/14\/revisions\/169"}],"wp:attachment":[{"href":"https:\/\/porkrind.org\/missives\/wp-json\/wp\/v2\/media?parent=14"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/porkrind.org\/missives\/wp-json\/wp\/v2\/categories?post=14"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/porkrind.org\/missives\/wp-json\/wp\/v2\/tags?post=14"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}