<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Made of Bugs &#187; git</title>
	<atom:link href="http://blog.nelhage.com/tag/git/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.nelhage.com</link>
	<description>It's software. It's made of bugs.</description>
	<lastBuildDate>Thu, 18 Aug 2011 21:57:23 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Versioning dotfiles in git</title>
		<link>http://blog.nelhage.com/2010/02/versioning-dotfiles-in-git/</link>
		<comments>http://blog.nelhage.com/2010/02/versioning-dotfiles-in-git/#comments</comments>
		<pubDate>Mon, 15 Feb 2010 00:03:15 +0000</pubDate>
		<dc:creator>nelhage</dc:creator>
				<category><![CDATA[git]]></category>
		<category><![CDATA[dotfiles]]></category>
		<category><![CDATA[unix]]></category>

		<guid isPermaLink="false">http://blog.nelhage.com/?p=134</guid>
		<description><![CDATA[I&#8217;ve been looking for a good solution for versioning and synchronizing my dotfiles between machines for some time. I experimented with keeping all of ~ in subversion for a while, but it never worked out well for me. I&#8217;ve finally settled on a solution that I like using git, and so this is a writeup [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been looking for a good solution for versioning and synchronizing
my dotfiles between machines for some time. I experimented with
keeping all of <code>~</code> in subversion for a while, but it never worked out
well for me.</p>

<p>I&#8217;ve finally settled on a solution that I like using git, and so this
is a writeup of my workflows for working with my dotfiles in git, in
the hopes that someone else might find it useful. You will not find
any scripts here, only a description of a workflow: It&#8217;s simple enough that I have not felt the need to script any of the pieces, even though I potentially could.</p>

<h2>On the machines</h2>

<p>On each machine, I have the dotfiles directory checked out into
<code>~/.dotfiles/</code>, and a symlink farm from the actual files in <code>~/</code> into
<code>~/.dotfiles</code>. If I need to edit files, I just edit them in place and
commit in <code>~/.dotfiles</code>. When adding new dotfiles, I just manually
create them in the checkout and create the symlink &#8212; no fancy
scripts. I do this rarely enough that I find it doesn&#8217;t bug me.</p>

<h2>Branches</h2>

<p>I maintain one branch for each machine or group of machines I keep
dotfiles on. For instance, my laptop has a branch, my desktop has a
branch, and all of the machines I have accounts on at work share a
branch. In addition there is a &#8220;master&#8221; branch, which contains a
prototypical set of dotfiles without any machine-specific
customizations.</p>

<p>In an ideal world, any change to my dotfiles would go to either
<code>master</code> (if it is common to all machines) or to a specific machine
branch, and I could then merge <code>master</code> into each machine branch to
sync the state of my dotfiles around. Unfortunately, one of my main
desiderata is that I can edit and commit dotfiles in place. And
committing to a non-checked-out branch is awkward at best, and
checking out <code>master</code> in the <code>~/.dotfiles/</code> working copy is
undesirable, since that might disrupt other programs that are using my
dotfiles at the time. So in practice, I make commits to the branch of
whichever machine I made a given change on, and then push them to that
branch in the master repository on my server.</p>

<h2>Synchronizing</h2>

<p>Periodically, I fetch that repository into another working copy, and
synchronize the branches. I check out <code>master</code>, and <code>git cherry-pick</code>
any commits off of each per-machine branch that should be shared among
all the machines. Once that&#8217;s done, I check out each per-machine
branch in turn, and <code>git merge</code> master back into it. With that done, I
push the branches back, and pull them on each machine.</p>

<p>It&#8217;s very important that this process &#8212; including the merging back
from master &#8212; be done in a separate working copy. Otherwise, a
conflicted merge results in conflict markers in your dotfiles. It was
particularly fun when I did this once and had a conflict in
<code>.gitconfig</code>, as <code>git</code> then immediately stopped working, and so I
couldn&#8217;t <code>reset --hard</code> out of the merge or inspect history until I
either resolved the merge or moved the broken file aside.</p>

<p>In practice, this sequence happens maybe once a month, and takes half
an hour or so. I could probably script some of that away, but I find
it mostly acceptable as is.</p>

<h2>Final thoughts</h2>

<p>I find the &#8220;commit and cherry-pick&#8221; workflow somewhat unfortunate, in that it results in two copies of every commit, and it makes &#8220;synchronize my dotfiles&#8221; a sufficiently expensive operation (in terms of effort) that it doesn&#8217;t happy continually. It&#8217;s conceivable that I would be better served by being disciplined about, after testing any change, immediately copying the files to another repository and comitting onto master and merging into the appropriate branch. However, I haven&#8217;t experimented with that because I intensely dislike any workflow that turns a common, simple operation (&#8220;make a stupid fix to my dotfiles&#8221;) into a more complex one. The current workflow does include a complex operation (the cherry-pick and merge step), but it&#8217;s a batch job, so I don&#8217;t mind scheduling it periodically, and it is an additional task I perform on top of the normal work of &#8220;messing with dotfiles&#8221;, which has specific additional benefit (&#8220;keeping my dotfiles in sync&#8221;), so I find it much more palatable.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.nelhage.com/2010/02/versioning-dotfiles-in-git/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Git in pictures</title>
		<link>http://blog.nelhage.com/2010/01/git-in-pictures/</link>
		<comments>http://blog.nelhage.com/2010/01/git-in-pictures/#comments</comments>
		<pubDate>Mon, 25 Jan 2010 03:30:02 +0000</pubDate>
		<dc:creator>nelhage</dc:creator>
				<category><![CDATA[git]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[pictures]]></category>
		<category><![CDATA[ui]]></category>

		<guid isPermaLink="false">http://blog.nelhage.com/?p=74</guid>
		<description><![CDATA[In my previous blog post, I discussed how git is distinctive among version control system in the way in which it makes the backend model that is being used to store data the most important element of the tool, and that experts use it by having the complete model in their head, and thinking in [...]]]></description>
			<content:encoded><![CDATA[<p>In my <a href="http://blog.nelhage.com/archives/64">previous blog post</a>, I discussed how git is distinctive among version control system in the way in which it makes the backend model that is being used to store data the most important element of the tool, and that experts use it by having the complete model in their head, and thinking in terms of operations on this object model, rather than just in terms of knowing specific commands to accomplish specific tasks.</p>

<p>Learning to use git in this way requires two steps. First, you need to understand the git object model, so that you know how to express whatever you are trying to do in terms of operations on that object model. In general, I tend to recommend <a href="http://eagain.net/articles/git-for-computer-scientists/">Git for Computer Scientists</a> as an excellent quick introduction to the git object model for hackers who are basically familiar with concepts like graphs and trees. I&#8217;ve also given a talk for SIPB entitled <a href="http://cluedumps.mit.edu/wiki/2009/09-29">Understanding Git</a>, which attempt to explain git starting from an understanding of the object model. I recommend either or both of those documents to anyone who wants to understand the backend git object model.</p>

<p>The second step, of course, is learning the git commands so that you can actually carry out the operations on the git objects and working copy that you want to accomplish. Git for Computer Scientists falls short on this point, although I think this is mostly because that&#8217;s not its goal. This blog post is an attempt to provide a quick graphical reference for a number of common git commands, in the hopes of helping users who have gotten comfortable with the git model, but occasionally find themselves groping for the command they want to carry out some operation. I hope that the first image especially will also be useful as a reference for those already comfortable with git.</p>

<h2>Working Trees, Indexes, and HEADs, Oh My!</h2>

<p>Personally, I find that the commands that often trip me up the most in git are the various commands for moving data between the working tree, index, and HEAD. I can always remember the basic ones like &#8220;add&#8221; and &#8220;commit&#8221;, of course, but if I, say, want to update some files in the index to match some commit, it often takes a minute to remember I want <code>git reset</code>. The following image attempts to diagram the working tree, the index, and HEAD, the last commit, and show the common commands for moving data between any pair of them:</p>

<p><a href="http://blog.nelhage.com/wp-content/uploads/2010/01/index-3.png"><img src="http://blog.nelhage.com/wp-content/uploads/2010/01/index-3.png" alt="Moving data around the git working copy." title="Git Index" class="aligncenter size-full wp-image-77" /></a></p>

<p>The command above each pair of arrows moves data from left to right, and the one on the bottom from right to left. As you can see from the diagram, moving data directly between the working tree and the latest commit generally also updates the index, which is what makes it possible to mostly pretend that the index doesn&#8217;t exist during normal usage, if you so choose. Also, of course, anywhere in this diagram where a command accepts <code>HEAD</code>, you can instead specify a an arbitrary commit object.</p>

<h2>Working with branches and commits</h2>

<p>The next pair of diagrams, will both be starting from the following image, showing part of a git repository that contains two branches (<code>master</code> and <code>topic</code>), which refer to some commits within the git object store:</p>

<p><a href="http://blog.nelhage.com/wp-content/uploads/2010/01/base.png"><img src="http://blog.nelhage.com/wp-content/uploads/2010/01/base.png" alt="A Git Repository" title="base" class="aligncenter size-full wp-image-80" /></a></p>

<p>Starting from this image, we can adjust master by adding new commits in several ways. The following diagram shows how the picture would change after each of <code>git commit</code>, <code>git commit --amend</code> or <code>git merge topic</code>:</p>

<p><a href="http://blog.nelhage.com/wp-content/uploads/2010/01/creating.png"><img src="http://blog.nelhage.com/wp-content/uploads/2010/01/creating.png" alt="Committing to the git repository" title="Committing" class="aligncenter size-full wp-image-81" /></a></p>

<p>Note that these three commands aren&#8217;t quite parallel &#8212; the first two, assuming you&#8217;ve staged some files into the index, will both result in the same tree object, whereas the third will execute a merge and construct its tree that way.</p>

<p>Instead of committing to the repository, we might want to create new branches, or move refs around. The fourth diagram, below, shows various commands we could execute to create a branch, move to another branch, or move around the <code>master</code> pointer:
<a href="http://blog.nelhage.com/wp-content/uploads/2010/01/branching.png"><img src="http://blog.nelhage.com/wp-content/uploads/2010/01/branching.png" alt="Manipulating git refs." title="Branching"  class="aligncenter size-full wp-image-83" /></a></p>

<p>Hopefully someone finds some of these useful as a quick reference, or perhaps feels inspired to do something similar but better &#8212; my graphic design abilities are limited at best. Let me know if you find any of these helpful!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.nelhage.com/2010/01/git-in-pictures/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>On git and usability</title>
		<link>http://blog.nelhage.com/2010/01/on-git-and-usability/</link>
		<comments>http://blog.nelhage.com/2010/01/on-git-and-usability/#comments</comments>
		<pubDate>Mon, 18 Jan 2010 04:57:31 +0000</pubDate>
		<dc:creator>nelhage</dc:creator>
				<category><![CDATA[git]]></category>
		<category><![CDATA[subversion]]></category>
		<category><![CDATA[svn]]></category>
		<category><![CDATA[ui]]></category>
		<category><![CDATA[usability]]></category>

		<guid isPermaLink="false">http://blog.nelhage.com/?p=64</guid>
		<description><![CDATA[I&#8217;ve been helping a number of people get started working with git over the last couple of weeks, as Ksplice has brought on some new interns, and we&#8217;ve had to get them up to speed on our internal git repositories. (As you might expect from a bunch of kernel hackers, we use git for absolutely [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been helping a number of people get started working with <code>git</code>
over the last couple of weeks, as <a href="http://ksplice.com/">Ksplice</a> has
brought on some new interns, and we&#8217;ve had to get them up to speed on
our internal git repositories. (As you might expect from a bunch of
kernel hackers, we use git for absolutely everything). While that
experience is what prompted this post, it wasn&#8217;t really anything I
haven&#8217;t seen before as <a href="http://sipb.mit.edu">SIPB</a> transitioned from a
group that mostly versioned code in SVN or
<a href="http://svk.bestpractical.com/">SVK</a> to one that used git almost
exclusively, practically overnight, as these things go.</p>

<p>I love git, and use it everywhere. One of the things I particularly
love about git is the fact that I understand essentially every element
of git&#8217;s data model and how it works, which means that I can invent
odd workflows or script git to do things that I never could have with
SVN or even SVK. Part of the reason for this is that git, internally,
really is fundamentally simple in a way subversion isn&#8217;t. There&#8217;s some
complexity (which I don&#8217;t and don&#8217;t have to understand) behind
implementing its model efficiently, but I can describe the basic git
data model in about a single slide (And in fact <a href="http://web.mit.edu/nelhage/Public/git-slides-2009.pdf">I have</a>).</p>

<p>At the same time, though, I consistently find that people who come to
git from subversion find it insufferably complex and hard to learn,
and spend quite a while wrangling with it, before they eventually
fight it to a draw where they only need to ask their local git expert
to dig them out of a hole every once in a while, or else until they
just give up and declare git to be space-alien and go back to
something they &#8220;understand&#8221;.</p>

<h2>The problem</h2>

<p>Having helped enough of these people, I&#8217;ve begun to understand the
problem. Fundamentally, the way (most) people learn and think about
subversion is different from the way git experts think about
git. subversion&#8217;s internal model is fairly complex, but <strong>you are not
expected to understand it</strong>. You just have to know the half dozen
commands you&#8217;ll ever need, and you use them, and everything is fine.</p>

<p>Git&#8217;s model is fundamentally fairly simple (a DAG of immutable commit
objects where branches are named mutable pointers into it), but <strong>you
are expected to understand it fully</strong> to use git effectively.</p>

<p>A subversion user who wants to get the latest updates from the server
just knows to run <code>svn up</code> and go back to their life. A git user has
to (in general) think about whether they want to rebase their local
changes onto the remote changes or merge them, and which remote branch
they want (this is all, of course, expressed essentially in terms of
the git data model), and then maps that back into the commands they
want to perform this task.</p>

<p>Subversion users aren&#8217;t used to thinking like this, and so when they
ask a git user for help, they get one of two classes of answers,
neither of which they like. Either they just get back a list of half a
dozen possible commands they could choose (since the git user has
mapped their request into the git object model, and can think of a
bunch of ways to implement that operation, depending on your mood and
the phase of the moon), or else they get a &#8220;What are you really trying
to?&#8221;, since their request has multiple interpretations in the language
of git objects. Neither answer is a single command that will always
solve their problem, which is what they want, so they can just go back to whatever they were trying to do, and so they end concluding that git is needlessly strange and confusing.</p>

<p>I think there are at least two reasons for this different perspective
from git users. One is historical &#8212; git was designed to work this
way. Linus wrote git as a dumb content tracker, and intended other
people to write various UIs on top of it, but not really for anyone to
use it as-is. So fundamentally, git is designed to just implement this
basic model, and not to export a single way to do anything.  The
other, perhaps more fundamental reason, is that git is designed to be
infinitely flexible, and so it&#8217;s fairly rare that you <em>can</em> give an
answer for &#8220;How do I do X with git?&#8221;, since the answer will often
depend on, &#8220;Well, what are your project&#8217;s conventions?&#8221;</p>

<h2>What do we do about this?</h2>

<p>So, as git users, hackers, and evangelists, what can we do to improve
this situation? I think that basically, we need to understand what&#8217;s
going on here, and try to have better answers for what the subversion
users regard as simple questions. We should encourage people to get to
know and love the git object model, but realize that most of the time,
they just want to get work done, and we need to try to have simple
answers to simple questions.</p>

<p>To that end, I think there are three main remaining areas in the git UI
that I think new users find confusing, and that we need to figure out
how to improve. These are pulling and pushing changes, and the whole
issue of the git index. Here are my thoughts on what&#8217;s wrong, and what
we can improve on:</p>

<ul>
<li><p>&#8221;git-push&#8221;: This command is a disaster in a number of
ways. <code>matching</code> is utterly the wrong default for <code>push.default</code> (I
believe 1.7 is going to fix this). The <code>git push $REMOTE $BRANCH</code>
syntax is not optimized for the common &#8220;subversion-like&#8221; case of a
single remote, and leads countless users to attempt to <code>git push
master</code>, at which point they get the less than totally helpful
error message:</p>

<pre><code>fatal: 'master' does not appear to be a git repository
fatal: The remote end hung up unexpectedly
</code></pre>

<p>In general, the error messages are pretty bad. I believe it was
<a href="http://twitter.com/defunkt"><code>@defunkt</code></a> who nominated &#8220;src refspec
does not match any&#8221; as the &#8220;worst error message of all time&#8221;, and
it&#8217;s hard not to see his point.</p></li>
<li><p>&#8221;git-pull&#8221; is also problematic. The vast majority of users in a
project live at the edges, pushing code inwards, and they almost
never actually want to create a merge commit. I almost always end up
telling users &#8220;No, really, you always just want <code>pull --rebase</code>&#8220;,
which leaves them with a poor impression of git&#8217;s UI (if you always
want that flag, why isn&#8217;t it just mandatory?), and which is hard to
explain, because the whole concept of &#8220;rebasing&#8221; is difficult to
really grok without really understanding the commit DAG.</p>

<p><code>branch.&lt;name&gt;.rebase</code> and <code>branch.autosetuprebase</code> are a partial solution, but is there a reason I can&#8217;t just have a repository wide default option that makes <code>--rebase</code> the default? With the former solution, I&#8217;m never confident I&#8217;ve actually set it on all of my branches, or that it will get set if some script creates a branch without using <code>git-branch</code> or <code>git-checkout</code>.</p>

<p>Similarly, it sucks that you can&#8217;t pull if you have any uncommitted
changes at all, especially for subversion users who are used to this
Just Working.</p></li>
<li><p>Finally, we really need to improve the story with the index. As an
experienced git user, I love the index, and use it for many reasons
all the time. However, as anyone who has tried to explain it (or
even to learn git) probably knows, it&#8217;s a confusing idea at first.</p>

<p>Generally, when someone is starting out with git, I try to ignore
the index, and suggest they just always use <code>git commit</code> with a
path. I then have to handwave, of course, over why they need <code>git
commit -a</code> instead of <code>git commit</code>, but that&#8217;s a mostly minor
problem.</p>

<p>The bigger issue comes when a user finds themselves in a merge
conflict, and finds that it&#8217;s basically impossible to do anything
without fully understanding the index, and all of the weird commands
for moving content between the index, the working tree, and
<code>HEAD</code>. Just the other day, three of us git experts had to stop and
think for a while about how to answer the question &#8220;So, if I&#8217;m in a
conflicted merge, and I want to just conditionally take “their”
changes, what the hell do I do?&#8221;. That&#8217;s not a good sign for new
users being able to figure out what to do here.</p>

<p>I don&#8217;t fully know what the right answer is, but I think it&#8217;s clear
the tools need some help here.</p></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.nelhage.com/2010/01/on-git-and-usability/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>

