<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="/stylesheets/rss.css" type="text/css"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
  <channel>
    <title>Tom Moertel's Weblog: Tag git</title>
    <link>http://blog.moertel.com/articles/tag/git?tag=git</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>Quality rants on programming theory and stuff geeks like</description>
    <item>
      <title>PXSL Tools now on Hackage and GitHub</title>
      <description>&lt;p&gt;I finally got around to releasing &lt;a href="http://hackage.haskell.org/cgi-bin/hackage-scripts/package/pxsl-tools"&gt;&lt;span class="caps"&gt;PXSL&lt;/span&gt; Tools on Hackage&lt;/a&gt;.  The package contains &lt;em&gt;pxslcc&lt;/em&gt;, a preprocessor that converts &lt;a href="http://community.moertel.com/ss/space/PXSL"&gt;Parsimonious &lt;span class="caps"&gt;XML&lt;/span&gt; Shorthand Language&lt;/a&gt; into &lt;span class="caps"&gt;XML&lt;/span&gt;, and supporting documentation.&lt;/p&gt;


	&lt;p&gt;If you want to hack on the Haskell sources, I&amp;#8217;ve put the project on GitHub, too.  See the &lt;a href="https://github.com/tmoertel/pxsl-tools/tree"&gt;pxsl-tools project page&lt;/a&gt; to browse the code, or just clone the repo and hack away:&lt;/p&gt;


&lt;pre&gt;$ git clone git://github.com/tmoertel/pxsl-tools.git
&lt;/pre&gt;</description>
      <pubDate>Sun, 24 Aug 2008 22:56:00 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:888e0d81-d509-4041-a75b-ee91ce921b4d</guid>
      <author>Tom Moertel</author>
      <link>http://blog.moertel.com/articles/2008/08/24/pxsl-tools-now-on-hackage-and-github</link>
      <category>haskell</category>
      <category>git</category>
      <category>pxsl</category>
      <trackback:ping>http://blog.moertel.com/articles/trackback/808</trackback:ping>
    </item>
    <item>
      <title>How I stopped missing Darcs and started loving Git</title>
      <description>&lt;p&gt;About three years ago, I &lt;a href="http://blog.moertel.com/articles/2005/02/12/source-code-management-with-darcs-a-first-look"&gt;switched to
Darcs&lt;/a&gt;
as my primary source-code management system.  It was simple,
intuitive, and powerful, and it made managing my projects more fun and
less frustrating than any centralized &lt;span class="caps"&gt;VCS&lt;/span&gt; ever had.  That it was
written in Haskell, one of my favorite programming languages, made
it even better.  I was hooked.&lt;/p&gt;


	&lt;p&gt;Since then, the distributed &lt;span class="caps"&gt;SCM&lt;/span&gt; landscape has changed.  Darcs hasn&amp;#8217;t
improved much, but its competitors have made long strides, especially
&lt;a href="http://git.or.cz/"&gt;Git&lt;/a&gt; and
&lt;a href="http://www.selenic.com/mercurial/"&gt;Mercurial&lt;/a&gt;.  Both
are crazy fast, vigorously developed, and widely used on large, highly
active real-world projects, such as the Linux kernel and Mozilla 2.
In comparison, Darcs has
stagnated.&lt;/p&gt;


	&lt;p&gt;When I started working for a new company recently, I had to consider
whether to advocate Darcs or something else.  In the end, I decided
that Darcs would be a hard sell.  Nobody else at the company uses
Haskell, and having to explain how to &lt;a href="http://wiki.darcs.net/DarcsWiki/ConflictsFAQ#head-476c7079246558936930568621a39f83295b3846"&gt;avoid the occasional corner
case&lt;/a&gt;
seemed liked a losing proposition.&lt;/p&gt;


	&lt;p&gt;After researching and playing around with Git and Mercurial, I settled
on Git.  I like Git&amp;#8217;s underlying hashed-blobs model better than
Mercurial&amp;#8217;s revlogs, and Git seems to have slightly more development
momentum.  Still, it was a close call.  Either choice would have been
completely reasonable.&lt;/p&gt;


	&lt;h3&gt;Missing Darcs&lt;/h3&gt;


	&lt;p&gt;When I started using Git on real projects, the one thing I &lt;em&gt;really&lt;/em&gt;
missed was the ability to easily amend earlier patches, something
Darcs made trivial.  Let me
explain.  The typical development workflow goes something like this:&lt;/p&gt;


	&lt;ol&gt;
	&lt;li&gt;Checkout copy of upstream code base.&lt;/li&gt;
		&lt;li&gt;Implement feature X.&lt;/li&gt;
		&lt;li&gt;Commit.&lt;/li&gt;
		&lt;li&gt;Implement independent feature Y.&lt;/li&gt;
		&lt;li&gt;Commit.&lt;/li&gt;
		&lt;li&gt;Implement independent feature Z.&lt;/li&gt;
		&lt;li&gt;Commit.&lt;/li&gt;
		&lt;li&gt;Push new features back upstream.&lt;/li&gt;
	&lt;/ol&gt;


	&lt;p&gt;Now, what really happens is that when I&amp;#8217;m implementing Y or Z,
I&amp;#8217;ll realize that I made a mistake in X.  The trick is then
fixing X so that my fix is part of the changeset/patch for X that
ultimately gets pushed upstream in the last step.  That way, the
upstream folks will see only a single, clean patch for feature X &amp;#8211; not
a mishmash of patches that together represent X.&lt;/p&gt;


	&lt;p&gt;In Darcs, amending the original patch is easy because its patch theory
lets me tweak the patch for X independently of the other patches.
Darcs will simply ask me which patch I want to amend, and I&amp;#8217;ll select
the orignal patch for X:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;$ emacs               # fix X
$ darcs amend-record  # amend original patch for X

Mon Dec 10 14:43:13 EST 2007  Tom Moertel &amp;lt;tom@moertel.com&amp;gt;
  * Implemented Z
Shall I amend this patch? [yNvpq], or ? for help: n

Mon Dec 10 14:42:12 EST 2007  Tom Moertel &amp;lt;tom@moertel.com&amp;gt;
  * Implemented Y
Shall I amend this patch? [yNvpq], or ? for help: n

Mon Dec 10 14:41:46 EST 2007  Tom Moertel &amp;lt;tom@moertel.com&amp;gt;
  * Implemented X
Shall I amend this patch? [yNvpq], or ? for help: y
hunk ./x 1
-X1
+X2
Shall I add this change? (1/?)  [ynWsfqadjkc], or ? for help: y
Finished amending patch:
Mon Dec 10 14:43:25 EST 2007  Tom Moertel &amp;lt;tom@moertel.com&amp;gt;
  * Implemented X
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;That&amp;#8217;s it.  The exact same process will work regardless of when I
realize I need to fix X: before I start Y, while I&amp;#8217;m implementing Y,
after I&amp;#8217;ve committed Y, while I&amp;#8217;m working on Z, or after I&amp;#8217;ve committed
Z.&lt;/p&gt;


	&lt;h3&gt; Learning to love Git&lt;/h3&gt;


	&lt;p&gt;With Git, however, I can amend a commit only if I haven&amp;#8217;t committed anything else before making my fix. In Git&amp;#8217;s mind, Y depends on X, and Z
depends on Y, even if they really are independent of one another.&lt;/p&gt;


	&lt;p&gt;So if I commit the original patch for X and then immediately realize I
need to make a fix, before I start working on Y or Z, it&amp;#8217;s easy:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;$ emacs               # implement X
$ git commit -m 'Implemented X'

# discover problem in X

$ emacs               # fix X
$ git commit --amend  # amend original patch
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;More typically, it&amp;#8217;s only while I&amp;#8217;m working on Y that I&amp;#8217;ll
realize I need to fix X.  Then it&amp;#8217;s more complicated
to amend the original commit:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;$ emacs               # implement X
$ git commit -m 'Implemented X'
$ emacs               # start working on Y

# discover problem in X

$ git stash           # stash away half-completed work on Y
$ emacs               # fix X
$ git commit --amend  # amend original patch for X
$ git stash apply     # restore work on Y
$ emacs               # continue working on Y
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;While not as convenient as Darcs&amp;#8217;s workflow, it&amp;#8217;s perfectly workable.&lt;/p&gt;


Now let&amp;#8217;s consider another fairly typical case:  I commit X and Y and
then start working on Z before I notice the problem in X.  I used to
think that Git couldn&amp;#8217;t handle this  case, but it can, thanks to
&lt;code&gt;git rebase --interactive&lt;/code&gt;:

&lt;pre&gt;&lt;code&gt;$ emacs               # implement X
$ git commit -m 'Implemented X'
$ emacs               # implement Y
$ git commit -m 'Implemented Y'
$ emacs               # start working on Z

# discover problem in X

$ git stash           # stash away half-completed work on Z
$ emacs               # fix X
$ git commit -m 'Fixed X'
$ git rebase --interactive HEAD~3  # see comments below
$ git stash apply     # restore work on Z
$ emacs               # continue working on Z
&lt;/code&gt;&lt;/pre&gt;

The &lt;code&gt;git rebase --interactive&lt;/code&gt; command is &lt;em&gt;powerful&lt;/em&gt;.  What the
command does, as called in the snippet above, is invoke my editor of
choice on a text file describing the last 3 commits (that&amp;#8217;s the
&lt;code&gt;HEAD~3&lt;/code&gt; part):

&lt;pre&gt;&lt;code&gt;# Rebasing 3ad99a7..b9a8405 onto 3ad99a7
#
# Commands:
#  pick = use commit
#  edit = use commit, but stop for amending
#  squash = use commit, but meld into previous commit
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
pick 0885540 Implemented X
pick 320b115 Implemented Y
pick b9a8405 Fixed X
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;I can then edit the file to reorder, merge (squash), and/or remove
the commits.  In this example, I want to merge the fix for X into
the original commit that implemented X.  So I edit the file like so:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;pick 0885540 Implemented X
squash b9a8405 Fixed X
pick 320b115 Implemented Y
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Then I save the file, at which point Git takes over and makes the
requested changes, merging the fix for X into the
original commit for X.  Now the log shows the original implementation
and fix as one commit:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;$ git log
commit f387d650976246c0854d028b040cca40e542be56
Author: Tom Moertel &amp;lt;tom@moertel.com&amp;gt;
Date:   Mon Dec 10 15:11:26 2007 -0500

    Implemented Y

commit 82a1c849ffd1bd688d5bc9d99be0e63548a89c4c
Author: Tom Moertel &amp;lt;tom@moertel.com&amp;gt;
Date:   Mon Dec 10 15:13:03 2007 -0500

    Implemented X

    Fixed X

commit 3ad99a7ef537b7ae99e435e0d2b4b0d03de92c65
Author: Tom Moertel &amp;lt;tom@moertel.com&amp;gt;
Date:   Mon Dec 10 15:11:14 2007 -0500

    Initial checkin
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Once I figured out how to use &lt;code&gt;git rebase --interactive&lt;/code&gt;, I stopped
missing Darcs and started loving Git.&lt;/p&gt;</description>
      <pubDate>Mon, 10 Dec 2007 16:52:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:65f0fc3e-71c6-4f9e-9100-3d1333b7967a</guid>
      <author>Tom Moertel</author>
      <link>http://blog.moertel.com/articles/2007/12/10/how-i-stopped-missing-darcs-and-started-loving-git</link>
      <category>programming</category>
      <category>haskell</category>
      <category>scm</category>
      <category>darcs</category>
      <category>git</category>
      <category>dvcs</category>
      <trackback:ping>http://blog.moertel.com/articles/trackback/655</trackback:ping>
    </item>
    <item>
      <title>Practical differences between Darcs and Git/Mercurial</title>
      <description>&lt;p&gt;On the Darcs Users mailing list, I ran across an interesting thread: &lt;a href="http://thread.gmane.org/gmane.comp.version-control.darcs.user/11201"&gt;practical differences between darcs&amp;#8217; patch model and git/mercurial&amp;#8217;s?&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;Among the interesting points of discussion:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;Do the mechanics that give rise to Darcs&amp;#8217;s strong cherry-picking abilities also make it susceptible to naughty time-complexity behavior?&lt;/li&gt;
		&lt;li&gt;When you merge non-conflicting changes in Git or Mercurial, you must record a merge patch, which binds the two in the development timeline, but in Darcs the respective patches are free to commute. Which behavior is better for real-world development?&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;If you&amp;#8217;re interested in distributed source-code management, it&amp;#8217;s an interesting thread to follow.&lt;/p&gt;</description>
      <pubDate>Thu, 25 Oct 2007 16:26:00 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:9bd93d19-ad1f-4462-9210-11df880ad696</guid>
      <author>Tom Moertel</author>
      <link>http://blog.moertel.com/articles/2007/10/25/practical-differences-between-darcs-and-git-mercurial</link>
      <category>programming</category>
      <category>vcs</category>
      <category>darcs</category>
      <category>mercurial</category>
      <category>git</category>
      <category>patches</category>
      <trackback:ping>http://blog.moertel.com/articles/trackback/606</trackback:ping>
    </item>
  </channel>
</rss>
