<?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; dotfiles</title>
	<atom:link href="http://blog.nelhage.com/tag/dotfiles/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>
	</channel>
</rss>

