<?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>Joe Maller &#187; workflow</title>
	<atom:link href="http://joemaller.com/tag/workflow/feed/" rel="self" type="application/rss+xml" />
	<link>http://joemaller.com</link>
	<description>.com</description>
	<lastBuildDate>Tue, 15 May 2012 03:40:33 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>A web-focused Git workflow</title>
		<link>http://joemaller.com/990/a-web-focused-git-workflow/</link>
		<comments>http://joemaller.com/990/a-web-focused-git-workflow/#comments</comments>
		<pubDate>Tue, 25 Nov 2008 17:04:30 +0000</pubDate>
		<dc:creator>Joe Maller</dc:creator>
				<category><![CDATA[misc.]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[web]]></category>
		<category><![CDATA[web design]]></category>
		<category><![CDATA[workflow]]></category>

		<guid isPermaLink="false">http://joemaller.com/?p=990</guid>
		<description><![CDATA[After months of looking, struggling through Git-SVN glitches and letting things roll around in my head, I&#8217;ve finally arrived at a web-focused Git workflow that&#8217;s simple, flexible and easy to use. Some key advantages: Pushing remote changes automatically updates the live site Server-based site edits won&#8217;t break history Simple, no special commit rules or requirements [...]]]></description>
			<content:encoded><![CDATA[<p>After months of looking, struggling through Git-SVN glitches and letting things roll around in my head, I&#8217;ve finally arrived at a web-focused Git workflow that&#8217;s simple, flexible and easy to use.</p>
<p>Some key advantages:</p>
<ul>
<li>Pushing remote changes automatically updates the live site</li>
<li>Server-based site edits won&#8217;t break history</li>
<li>Simple, no special commit rules or requirements</li>
<li>Works with existing sites, no need to redeploy or move files</li>
</ul>
<h3>Overview</h3>
<p>The key idea in this system is that the web site exists on the server as a pair of repositories; a bare repository alongside a conventional repository containing the live site. Two simple Git hooks link the pair, automatically pushing and pulling changes between them.</p>
<p><img src="http://joemaller.com/wordpress/wp-content/uploads/2008/11/hub-prime2.jpg" alt="" title="hub, prime, clones" width="500" height="247" /></p>
<p>The two repositories:</p>
<ul>
<li><strong>Hub</strong> is a bare repository. All other repositories will be cloned from this.</li>
<li><strong>Prime</strong> is a standard repository, the live web site is served from its working directory.</li>
</ul>
<p>Using the pair of repositories is simple and flexible. Remote clones with ssh-access can update the live site with a simple <strong>git push </strong>to Hub. Any files edited directly on the server are instantly mirrored into Hub upon commit. The whole thing pretty much just works &#8212; whichever way it&#8217;s used.</p>
<p><strong>Getting ready</strong></p>
<p>Obviously <a href="http://git.or.cz/">Git</a> is required on the server and any local machines. My shared web host doesn&#8217;t offer Git, but it&#8217;s easy enough to <a href="http://joemaller.com/2008/08/13/how-to-install-git-on-a-shared-host/">install Git yourself</a>.</p>
<p>If this is the first time running Git on your webserver, remember to <a href="http://rails.wincent.com/wiki/Git_quickstart ">setup your global configuration info</a>. I set a different Git user.name to help distinguish server-based changes in project history.</p>
<pre><code>$ git config --global user.name "Joe, working on the server"</code></pre>
<h3>Getting started</h3>
<p>The first step is to initialize a new Git repository in the live web site directory on the server, then to add and commit all the site&#8217;s files. This is the <strong>Prime</strong> repository and working copy. Even if history exists in other places, the contents of the live site will be the baseline onto which all other work is merged.</p>
<pre><code>$ cd ~/www
$ git init
$ git add .
$ git commit -m"initial import of pre-existing web files"</code></pre>
<p>Initializing in place also means there is no downtime or need to re-deploy the site, Git just builds a repository around everything that&#8217;s  already there.</p>
<p>With the live site now safely in Git, create a bare repository outside the web directory, this is <strong>Hub</strong>.</p>
<pre><code>$ cd; mkdir site_hub.git; cd site_hub.git
$ git --bare init
<span class="response">Initialized empty Git repository in /home/joe/site_hub.git</span></code></pre>
<p>Then, from inside Prime&#8217;s working directory, add Hub as a remote and push Prime&#8217;s master branch:</p>
<pre><code>$ cd ~/www
$ git remote add hub ~/site_hub.git
$ git remote show hub
<span class="response">* remote hub
  URL: /home/joe/site_hub.git</span>
$ git push hub master</code></pre>
<h3>Hooks</h3>
<p>Two simple Git hooks scripts keep Hub and Prime linked together.</p>
<p>An oft-repeated rule of Git is to <a href="http://git.or.cz/gitwiki/GitFaq#head-b96f48bc9c925074be9f95c0fce69bcece5f6e73">never push into a repository that has a work tree attached to it</a>. I tried it, and things do get weird fast. The hub repository exists for this reason. Instead of pushing changes to Prime from Hub, which wouldn&#8217;t affect the working copy anyway, Hub uses a hook script which tells Prime to pull changes from Hub.</p>
<h4>post-update &#8211; Hub repository</h4>
<p>This hook is called when Hub receives an update. The script changes directories to the Prime repository working copy then runs a pull from Prime. Pushing changes doesn&#8217;t update a repository&#8217;s working copy, so it&#8217;s necessary to execute this from inside the working copy itself.</p>
<pre><code>#!/bin/sh

echo
echo "**** Pulling changes into Prime [Hub's post-update hook]"
echo

cd $HOME/www || exit
unset GIT_DIR
git pull hub master

exec git-update-server-info</code></pre>
<h4>post-commit &#8211; Prime repository</h4>
<p>This hook is called after every commit to send the newly commited changes back up to Hub. Ideally, it&#8217;s not common to make changes live on the server, but automating this makes sure site history won&#8217;t diverge and create conflicts.</p>
<pre><code>#!/bin/sh

echo
echo "**** pushing changes to Hub [Prime's post-commit hook]"
echo

git push hub</code></pre>
<p>With this hook in place, all changes made to Prime&#8217;s master branch are immediately available from Hub. Other branches will also be cloned, but won&#8217;t affect the site. Because all remote repository access is via SSH urls, only users with shell access to the web server will be able to push and trigger a site update.</p>
<h3>Conflicts</h3>
<p>This repository-hook arrangement makes it very difficult to accidentally break the live site. Since every commit to Prime is automatically pushed to Hub, all conflicts will be immediately visible to the clones when pushing an update. </p>
<p>However there are a few situations where Prime can diverge from Hub which will require additional steps to fix. If an uncommitted edit leaves Prime in a dirty state, Hub&#8217;s post-update pull will fail with an &#8220;Entry &#8216;foo&#8217; not uptodate. Cannot merge.&#8221; warning. Committing changes will clean up Prime&#8217;s working directory, and the post-update hook will then merge the un-pulled changes. </p>
<p>If a conflict occurs where changes to Prime can&#8217;t be merged with Hub, I&#8217;ve found the best solution is to push the current state of Prime to a new branch on Hub. The following command, issued from inside Prime, will create a remote &#8220;fixme&#8221; branch based on the current contents of Prime:</p>
<pre><code>$ git push hub master:refs/heads/fixme</code></pre>
<p>Once that&#8217;s in Hub, any remote clone can pull down the new branch and resolve the merge. Trying to resolve a conflict on the server would almost certainly break the site due to Git&#8217;s conflict markers.</p>
<h3>Housekeeping</h3>
<p>Prime&#8217;s .git folder is at the root level of the web site, and is probably publicly accessible. To protect the folder and prevent unwanted clones of the repository, add the following to your top-level .htaccess file to forbid web access:</p>
<pre><code># deny access to the top-level git repository:
RewriteEngine On
RewriteRule \.git - [F,L]</code></pre>
<h3>Troubleshooting</h3>
<p>If you&#8217;re seeing this error when trying to push to a server repository:
<pre><code><span class="response nocode">git-receive-pack: command not found
fatal: The remote end hung up unexpectedly</span></code></pre>
<p>Add <code>export PATH=${PATH}:~/bin</code> to your .bashrc file on the server. Thanks to Robert for <a href="http://www.bluestatic.org/blog/2007/08/01/git-public-push-ing/">finding and posting the fix</a>.</p>
<h3>Links</h3>
<p>These didn&#8217;t fit in anywhere else:</p>
<ul>
<li>Toolman Tim has a very good introductory walkthrough of <a href="http://toolmantim.com/article/2007/12/5/setting_up_a_new_remote_git_repository">setting up a new remote git repository</a>.
</li>
<li>This ended up being somewhat similar to the <a href="http://ikiwiki.info/rcs/git/"> update mechanism in Ikiwiki</a>, wish I&#8217;d found that page earlier.</li>
<li><a href="http://www.linuxworld.com/community/?q=node/3057"> Getting a static web site organized with git </a> came up with a different solution, but calling <code>git reset --hard</code> from a hook on the server could cause a lot of trouble when committing server-side changes.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://joemaller.com/990/a-web-focused-git-workflow/feed/</wfw:commentRss>
		<slash:comments>89</slash:comments>
		</item>
	</channel>
</rss>

<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Page Caching using disk: enhanced
Database Caching 3/9 queries in 0.003 seconds using disk: basic
Object Caching 212/217 objects using disk: basic

Served from: joemaller.com @ 2012-05-24 03:35:40 -->
