<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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/" version="2.0">

<channel>
	<title>gitguru</title>
	
	<link>http://gitguru.com</link>
	<description>meditations on scm using git</description>
	<lastBuildDate>Wed, 25 Mar 2009 04:32:08 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.4.2</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/gitguru" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="gitguru" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>Git Enterprise Requirements</title>
		<link>http://gitguru.com/2009/03/18/git-enterprise-requirements/</link>
		<comments>http://gitguru.com/2009/03/18/git-enterprise-requirements/#comments</comments>
		<pubDate>Wed, 18 Mar 2009 18:01:23 +0000</pubDate>
		<dc:creator>long</dc:creator>
				<category><![CDATA[enterprise]]></category>
		<category><![CDATA[scm]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[workflow]]></category>

		<guid isPermaLink="false">http://gitguru.com/?p=220</guid>
		<description><![CDATA[If you&#8217;re an individual developer or a small team, I wouldn&#8217;t think twice before recommending using Git. But beyond that I have some reservations.  At least for where Git is right now. That hesitation is from the experience I&#8217;ve gained from performing start-to-finish installations of enterprise-class SCM tools including IBM Rational ClearCase and CA Software [...]]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;re an individual developer or a small team, I wouldn&#8217;t think twice before recommending using Git.</p>
<p>But beyond that I have some reservations.  At least for where Git is right now.</p>
<p>That hesitation is from the experience I&#8217;ve gained from performing start-to-finish installations of enterprise-class SCM tools including <a href="http://www-01.ibm.com/software/awdtools/clearcase/">IBM Rational ClearCase</a> and <a href="http://www.ca.com/us/products/product.aspx?ID=255">CA Software Change Manager</a>.  What separates these tools from Git (and SVN) is that they address processes and workflows, security and roles.  And the enterprise world is all about that.</p>
<p>A standard installation of Git, on the other hand, is a blank slate.  You can do what you will with it.  Which is great for a developer who dreams of having that flexibility but gives SCM admins nightmares because they usually have to clean up whatever goes horribly wrong.</p>
<p>What allows Git to have a chance of making serious inroads into the enterprise world is that it&#8217;s open, relies on standard mechanisms such as ssh and has a <a href="http://www.kernel.org/pub/software/scm/git/docs/githooks.html">hook system</a> that is triggered by actions on a repository.  New functionality can be constructed around the version engine core.</p>
<p>So what exactly does Git need to have built around it?</p>
<p>My minimum set of requirements would include</p>
<h4>1. Security and Access Control</h4>
<p>Git punts on security and relies directly on the OS/filesystem and transport protocol (git:, http:, or ssh:) to control read and write access to repositories.  And current add-ons such as <a href="http://scie.nti.st/2007/11/14/hosting-git-repositories-the-easy-and-secure-way">gitosis</a> only address access at the repository level, not the level of branches, tags, etc.</p>
<p>Implementation of a unified security and a fine-grain access/locking mechanism is an absolute necessity before Git can be even considered as a serious enterprise tool.</p>
<h4>2. Integration with the &#8220;typical&#8221; Development Environment</h4>
<p>My experience with Git is with <a href="http://rubyonrails.org/">Rails</a> and Mac OS X and Linux.  While this isn&#8217;t unusual in the startup world, it&#8217;s not the &#8220;typical&#8221; enterprise development environment.  That instead would be Visual Studio or an Eclipse-based IDE on Windows.</p>
<p>We need to support projects such as</p>
<ul>
<li> <a href="http://code.google.com/p/msysgit/">msysgit</a> &#8211; a native Windows implementation of Git</li>
<li><a href="http://www.jgit.org/">JGit</a> &#8211; a Java GIT library implementation</li>
<li><a href="http://code.google.com/p/egit/">EGit</a> &#8211; an Eclipse plugin based on JGit</li>
</ul>
<p>if Git is to gain traction in the enterprise.</p>
<h4>3. Repository Visualization</h4>
<p>If you have development of even the slightest complexity, having a visual tool to view the branch structure and where commits are located is a necessity.  Some existing GUI interfaces include:</p>
<ul>
<li><a href="http://www.kernel.org/pub/software/scm/git/docs/git-gui.html">git-gui</a> (multi-platform tcl/tk)</li>
<li><a href="http://www.kernel.org/pub/software/scm/git/docs/gitk.html">gitk</a> (multi-platform tcl/tk)</li>
<li><a href="http://git.kernel.org/?p=qgit/qgit4.git;a=summary">qgit</a> (multi-platform Qt)</li>
<li><a href="http://gitx.frim.nl/">GitX</a> (Mac OS X)</li>
<li><a href="http://code.google.com/p/gitextensions/">Git Extensions</a> (Windows)</li>
</ul>
<p>These tools, however, work on just local repositories.  Remote repository branching is only seen if you&#8217;ve fetched the information.</p>
<p>An enterprise tool will need to start from any &#8220;canonical&#8221; shared repository and then add branching information from local developer repositories in order to show the extended branch network.  This would provide a visualization of the development taking place across the organization.</p>
<h4>4. Example Workflows</h4>
<p>Git doesn&#8217;t mandate any particular development workflow.  Even the de-facto standard <a href="http://github.com/guides/pull-requests">pull-request</a> method of sharing updates is really a suggestion rather than an enforceable process (unless you&#8217;re working under a <a href="http://www.wired.com/wired/archive/11.11/linus_pr.html">benevolent dictatorship</a>).</p>
<p>Unfortunately you&#8217;re going to find that given <em>n</em> developers, you&#8217;ll likely see a minimum of <em>n+1</em> ways of using a tool.</p>
<p>Example enforceable workflows for common practices including agile development, lifecycle management and deployment need to be created via the hook mechanism and made widely available.  An enterprise SCM team can then use these workflows as a starting point for customizing their Git installation.</p>
<h4>5. Simplified Administration</h4>
<p>Installing and using Git for a local repository is reasonably straightforward.  Configuring a repository for remote access is a bit more complicated:</p>
<ul>
<li>How do I create a bare repository from an existing one?</li>
<li>Which protocol should I use? git, http, or ssh?</li>
<li>How do I restrict access?</li>
<li>How do I add and identify repository users?</li>
<li>What happens if I need to add a new repository?</li>
</ul>
<p>And if you have to host any appreciable number or sizeable sets of repositories, you need to start worrying about storage, load, and backups.</p>
<p>So is this at all possible? Can an enterprise-ready tool be built around a Git core?</p>
<p>Absolutely yes.</p>
<p>If you have any doubts, you just need to look at what <a href="http://github.com/">GitHub</a> has done with simplifying repository creation/forking, security and collaboration setup, and tools for visualizing the development network.  Or how <a href="http://heroku.com/">Heroku</a> has made Git a part of the <a href="http://heroku.com/docs#toc1">application deployment process</a>.</p>
<p>It&#8217;s just really a question of when someone&#8217;s going to put it all together for the enterprise.</p>
]]></content:encoded>
			<wfw:commentRss>http://gitguru.com/2009/03/18/git-enterprise-requirements/feed/</wfw:commentRss>
		<slash:comments>29</slash:comments>
		</item>
		<item>
		<title>Integrating Git with a Visual Merge Tool</title>
		<link>http://gitguru.com/2009/02/22/integrating-git-with-a-visual-merge-tool/</link>
		<comments>http://gitguru.com/2009/02/22/integrating-git-with-a-visual-merge-tool/#comments</comments>
		<pubDate>Mon, 23 Feb 2009 00:47:20 +0000</pubDate>
		<dc:creator>long</dc:creator>
				<category><![CDATA[commands]]></category>
		<category><![CDATA[merge]]></category>
		<category><![CDATA[mergetool]]></category>

		<guid isPermaLink="false">http://gitguru.com/?p=155</guid>
		<description><![CDATA[One of the first real points of frustration a developer encounters with Git is the initial unresolved merge conflict.  And it&#8217;s only a matter of when and not if it&#8217;ll happen. Merge Conflicts in Git The root cause of the conflicts is unavoidable in any kind of parallel development: Updates that are made independently may [...]]]></description>
			<content:encoded><![CDATA[<p>One of the first real points of frustration a developer encounters with Git is the initial unresolved merge conflict.  And it&#8217;s only a matter of when and not if it&#8217;ll happen.</p>
<h4>Merge Conflicts in Git</h4>
<p>The root cause of the conflicts is unavoidable in any kind of parallel development: Updates that are made independently may modify the same or overlapping regions of the codebase.  The longer the development remains independent, the greater the probability this will take place.  For a tool that is basically based on branching and parallelism, Git is essentially inviting this &#8220;trouble.&#8221;  (Rest assured that the benefits are still well worth it.)</p>
<p>As an example, in the course of <a href="http://insoshi.com">Insoshi</a> development, we&#8217;ve seen merge conflicts arise from</p>
<ul>
<li>Merging new edge features into contributions based on an earlier commit</li>
<li>Applying fixes made against our production code to edge</li>
</ul>
<p>And I&#8217;m sure Insoshi community developers encountered a number of conflicts when applying the new tabbed and AJAX-ified layout against code they&#8217;d developed against the original layout.</p>
<p>Here&#8217;s a re-creation of a recent merge conflict in the <a href="http://github.com/insoshi/insoshi/">Insoshi repository</a>:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">git checkout</span> <span style="color: #660033;">-b</span> edge_merge_example 757bf03d90be14fd393d457ec20455700a5fc751
Switched to a new branch <span style="color: #ff0000;">&quot;edge_merge_example&quot;</span>
$ <span style="color: #c20cb9; font-weight: bold;">git branch</span> exception_fix 07097a3b5a797b4c3d0e3ba53a0ad98a8861db79
$ <span style="color: #c20cb9; font-weight: bold;">git merge</span> exception_fix
Auto-merged app<span style="color: #000000; font-weight: bold;">/</span>controllers<span style="color: #000000; font-weight: bold;">/</span>people_controller.rb
CONFLICT <span style="color: #7a0874; font-weight: bold;">&#40;</span>content<span style="color: #7a0874; font-weight: bold;">&#41;</span>: Merge conflict <span style="color: #000000; font-weight: bold;">in</span> app<span style="color: #000000; font-weight: bold;">/</span>controllers<span style="color: #000000; font-weight: bold;">/</span>people_controller.rb
Auto-merged app<span style="color: #000000; font-weight: bold;">/</span>models<span style="color: #000000; font-weight: bold;">/</span>person.rb
CONFLICT <span style="color: #7a0874; font-weight: bold;">&#40;</span>content<span style="color: #7a0874; font-weight: bold;">&#41;</span>: Merge conflict <span style="color: #000000; font-weight: bold;">in</span> app<span style="color: #000000; font-weight: bold;">/</span>models<span style="color: #000000; font-weight: bold;">/</span>person.rb
Removed app<span style="color: #000000; font-weight: bold;">/</span>views<span style="color: #000000; font-weight: bold;">/</span>connections<span style="color: #000000; font-weight: bold;">/</span>show.html.erb
Auto-merged spec<span style="color: #000000; font-weight: bold;">/</span>models<span style="color: #000000; font-weight: bold;">/</span>person_spec.rb
Automatic merge failed; fix conflicts and <span style="color: #000000; font-weight: bold;">then</span> commit the result.</pre></td></tr></table></div>

<p><a href="http://www.kernel.org/pub/software/scm/git/docs/git-merge.html#_how_conflicts_are_presented">What Git presents in the event of a conflict</a> that requires manual resolution isn&#8217;t any different than what you would see in <a href="http://durak.org/cvswebsites/howto-cvs/node29.html">CVS</a> or <a href="http://svnbook.red-bean.com/en/1.5/svn.tour.cycle.html#svn.tour.cycle.resolve">SVN</a>:</p>
<p><strong>app/models/person.rb</strong></p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
</pre></td><td class="code"><pre class="ruby" style="font-family:monospace;">      <span style="color:#9966CC; font-weight:bold;">not</span> deactivated?
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#008000; font-style:italic;"># Return the common connections with the given person.</span>
<span style="color:#006600; font-weight:bold;">&lt;&lt;&lt;&lt;&lt;&lt;&lt;</span> HEAD:app<span style="color:#006600; font-weight:bold;">/</span>models<span style="color:#006600; font-weight:bold;">/</span>person.<span style="color:#9900CC;">rb</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> common_contacts_with<span style="color:#006600; font-weight:bold;">&#40;</span>person, options = <span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#008000; font-style:italic;"># I tried to do this in SQL for efficiency, but failed miserably.</span>
    <span style="color:#008000; font-style:italic;"># Horrifyingly, MySQL lacks support for the INTERSECT keyword.</span>
    <span style="color:#006600; font-weight:bold;">&#40;</span>contacts <span style="color:#006600; font-weight:bold;">&amp;</span> person.<span style="color:#9900CC;">contacts</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">paginate</span><span style="color:#006600; font-weight:bold;">&#40;</span>options<span style="color:#006600; font-weight:bold;">&#41;</span>
=======
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> common_contacts_with<span style="color:#006600; font-weight:bold;">&#40;</span>contact, options = <span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#008000; font-style:italic;"># I tried to do this in SQL for efficiency, but failed miserably.</span>
    <span style="color:#008000; font-style:italic;"># Horrifyingly, MySQL lacks support for the INTERSECT keyword.</span>
    <span style="color:#006600; font-weight:bold;">&#40;</span>contacts <span style="color:#006600; font-weight:bold;">&amp;</span> contact.<span style="color:#9900CC;">contacts</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">paginate</span><span style="color:#006600; font-weight:bold;">&#40;</span>options<span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#006600; font-weight:bold;">&gt;&gt;&gt;&gt;&gt;&gt;&gt;</span> exception_fix:app<span style="color:#006600; font-weight:bold;">/</span>models<span style="color:#006600; font-weight:bold;">/</span>person.<span style="color:#9900CC;">rb</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  protected
&nbsp;
    <span style="color:#008000; font-style:italic;">## Callbacks</span></pre></td></tr></table></div>

<p>The contents of conflicting lines from the current version and version to be merged are placed inline with the code separated by &#8220;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&#8221;, &#8220;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&#8221; and &#8220;=======&#8221; markers.  It&#8217;s ugly and depending on the extent of the conflicts, can be extremely confusing and time consuming to resolve.  Thankfully, the conflicts in this example appear to be easily manageable.  (And without delving back to far into the commit history, the conflict lines in the persons model probably were copied/cherry-picked from one branch to another and then an additional correction was made to one branch).</p>
<p>So for all of the things that Git does right, why doesn&#8217;t it offer a better way? The short answer is that it can&#8217;t by itself.  It needs help.</p>
<h4>Visual Merge Tools</h4>
<p>A manual 3-way merge is the way to resolve these conflict.  You&#8217;re using 3 versions of a file as the starting points: the version on the branch you&#8217;re on, the version on the branch you&#8217;re merging in, and their common ancestor.  The common ancestor is used as the base with updates from either of the other two are applied on top of as direct selections or edited combinations at each conflict point.</p>
<p>Visual merge tools provide the interface for processing the 3-way merge and reduce the time and effort required.  You&#8217;re presented with the three versions and can easily choose code from any and all of them to resolve conflicts.</p>
<p>If you&#8217;ve been using a VCS tool for a while, you&#8217;re probably already using a merge tool, either the one that came with it or one that you&#8217;ve picked up along the way out of necessity.  If you haven&#8217;t used one before, now&#8217;s a good time as any to start.</p>
<p>Merge tools that I know about include</p>
<ul>
<li><span style="text-decoration: underline;"><strong>Open Source</strong></span>
<ul>
<li><a href="http://kdiff3.sourceforge.net/">kdiff3</a></li>
<li><a href="http://sourceforge.net/projects/tkdiff/">tkdiff</a></li>
<li><a href="http://furius.ca/xxdiff/">xxdiff</a></li>
</ul>
</li>
<li><span style="text-decoration: underline;"><strong>Free from a commercial vendor</strong></span>
<ul>
<li><a href="http://www.sourcegear.com/diffmerge/">SourceGear DiffMerge</a></li>
<li><a href="http://developer.apple.com/DOCUMENTATION/Darwin/Reference/ManPages/man1/opendiff.1.html">FileMerge/opendiff</a></li>
<li><a href="http://www.perforce.com/perforce/products/merge.html">Perforce Visual Merge Tool (P4Merge)</a></li>
</ul>
</li>
<li><span style="text-decoration: underline;"><strong>Commercial </strong></span>
<ul>
<li>Araxis Merge (<a href="http://www.araxis.com/merge/index.html">Windows</a> | <a href="http://www.araxis.com/merge_mac/index.html">Mac OS X</a>)</li>
<li><a href="http://www.scootersoftware.com/index.php">Beyond Compare</a></li>
<li><a href="http://www.guiffy.com/">Guiffy SureMerge</a></li>
</ul>
</li>
</ul>
<p>This is by no means a complete list.  Be aware that some merge tools only offer a 2-way merge or require an upgraded/pro version to perform 3-way merges.</p>
<h4>git mergetool</h4>
<p>The <a href="http://www.kernel.org/pub/software/scm/git/docs/git-mergetool.html">git mergetool</a> command allows for the integration of those tools into the merge process.  Run after merge conflicts have been identified, it loops through the files that need to be resolved and provides the specified tool with the version information necessary to invoke the 3-way merge.</p>
<p>git mergetool already includes support for a number open source and freely available merge tools: kdiff3, tkdiff, meld, xxdiff, emerge, vimdiff, gvimdiff, ecmerge, and opendiff.</p>
<p>Support for additional tools including DiffMerge and Araxis Merge can be added via custom configuration settings provided a command-line call exists:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">git config</span> <span style="color: #660033;">--global</span> mergetool.<span style="color: #7a0874; font-weight: bold;">&#91;</span>tool<span style="color: #7a0874; font-weight: bold;">&#93;</span>.cmd <span style="color: #7a0874; font-weight: bold;">&#91;</span>command-line call<span style="color: #7a0874; font-weight: bold;">&#93;</span>
<span style="color: #c20cb9; font-weight: bold;">git config</span> <span style="color: #660033;">--global</span> mergetool.<span style="color: #7a0874; font-weight: bold;">&#91;</span>tool<span style="color: #7a0874; font-weight: bold;">&#93;</span>.trustExitCode <span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #c20cb9; font-weight: bold;">true</span><span style="color: #000000; font-weight: bold;">|</span><span style="color: #c20cb9; font-weight: bold;">false</span><span style="color: #7a0874; font-weight: bold;">&#93;</span></pre></td></tr></table></div>

<p>The &#8220;&#8211;global&#8221; flag is used so the setting will apply across all of your Git repositories.</p>
<p>The command line needs to accept the following file variables passed in as parameters:</p>
<ul>
<li><strong>$LOCAL</strong> &#8211; Current branch version</li>
<li><strong>$REMOTE</strong> &#8211; Version to be merged</li>
<li><strong>$BASE</strong> &#8211; Common ancestor</li>
<li><strong>$MERGED</strong> &#8211; File where results will be written</li>
</ul>
<p>git mergetool will create the versions as temporary files and set the variables appropriately before the tool command-line is executed.</p>
<p>If the tool returns a proper exit code after a successful or unsuccessful merge, then the trustExitCode setting can be set to true.  Otherwise set it as false so you will be prompted as to whether the merge conflicts for a file were resolved.</p>
<h4>Performing a Merge with Conflicts</h4>
<p>The sequence of commands for a merge using mergetool would be</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">git merge</span>
<span style="color: #c20cb9; font-weight: bold;">git mergetool</span> <span style="color: #660033;">-t</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span>tool<span style="color: #7a0874; font-weight: bold;">&#93;</span>
<span style="color: #c20cb9; font-weight: bold;">git add</span> .
<span style="color: #c20cb9; font-weight: bold;">git commit</span></pre></td></tr></table></div>

<p>You can specify a default tool via the merge.tool setting</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">git config</span> <span style="color: #660033;">--global</span> merge.tool <span style="color: #7a0874; font-weight: bold;">&#91;</span>tool<span style="color: #7a0874; font-weight: bold;">&#93;</span></pre></td></tr></table></div>

<p>This will allow you to just simply call</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">git mergetool</span></pre></td></tr></table></div>

<h4>Using a Supported Merge Tool</h4>
<p>My main machine is a MacBook Pro and since I have Apple Developer Tools installed, I have opendiff/FileMerge installed.  It&#8217;s one of the supported merge tools so I can immediately start using it:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">git mergetool</span> <span style="color: #660033;">-t</span> opendiff</pre></td></tr></table></div>

<p>For the Insoshi conflict example you&#8217;ll see</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">git mergetool</span> <span style="color: #660033;">-t</span> opendiff
Merging the files: app<span style="color: #000000; font-weight: bold;">/</span>controllers<span style="color: #000000; font-weight: bold;">/</span>people_controller.rb
app<span style="color: #000000; font-weight: bold;">/</span>models<span style="color: #000000; font-weight: bold;">/</span>person.rb
&nbsp;
Normal merge conflict <span style="color: #000000; font-weight: bold;">for</span> <span style="color: #ff0000;">'app/controllers/people_controller.rb'</span>:
 <span style="color: #7a0874; font-weight: bold;">&#123;</span><span style="color: #7a0874; font-weight: bold;">local</span><span style="color: #7a0874; font-weight: bold;">&#125;</span>: modified
 <span style="color: #7a0874; font-weight: bold;">&#123;</span>remote<span style="color: #7a0874; font-weight: bold;">&#125;</span>: modified
Hit <span style="color: #7a0874; font-weight: bold;">return</span> to start merge resolution tool <span style="color: #7a0874; font-weight: bold;">&#40;</span>opendiff<span style="color: #7a0874; font-weight: bold;">&#41;</span>:
&nbsp;
Normal merge conflict <span style="color: #000000; font-weight: bold;">for</span> <span style="color: #ff0000;">'app/models/person.rb'</span>:
 <span style="color: #7a0874; font-weight: bold;">&#123;</span><span style="color: #7a0874; font-weight: bold;">local</span><span style="color: #7a0874; font-weight: bold;">&#125;</span>: modified
 <span style="color: #7a0874; font-weight: bold;">&#123;</span>remote<span style="color: #7a0874; font-weight: bold;">&#125;</span>: modified
Hit <span style="color: #7a0874; font-weight: bold;">return</span> to start merge resolution tool <span style="color: #7a0874; font-weight: bold;">&#40;</span>opendiff<span style="color: #7a0874; font-weight: bold;">&#41;</span>:</pre></td></tr></table></div>

<p>The FileMerge window for app/models/person.rb looks like</p>
<p><img class="aligncenter size-full wp-image-197" title="opendiff" src="http://gitguru.com/wp-content/uploads/2009/02/opendiff.png" alt="opendiff" width="600" height="516" /></p>
<p>Because FileMerge is now handling the merge for this file, it&#8217;s processing all the differences and not just the conflict area.  You can see this on the bottom status:</p>
<ul>
<li>status: 12 differences (12 left, 1 right, 1 conflict)</li>
</ul>
<p>If you haven&#8217;t used FileMerge before, you&#8217;ll need to do a couple of things that aren&#8217;t immediately obvious:</p>
<ul>
<li>Drag up to reveal the &#8220;Ancestor&#8221; pane at the bottom of the window</li>
<li>Click on the conflict section numbers located between the LOCAL and REMOTE panes in order to select an action</li>
</ul>
<p>If you complete the merge and save it, mergetool will accept the result.</p>
<p>If you abort and quit out of the merge without saving, you will be prompted if the save was successful.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;">app<span style="color: #000000; font-weight: bold;">/</span>models<span style="color: #000000; font-weight: bold;">/</span>person.rb seems unchanged.
Was the merge successful? <span style="color: #7a0874; font-weight: bold;">&#91;</span>y<span style="color: #000000; font-weight: bold;">/</span>n<span style="color: #7a0874; font-weight: bold;">&#93;</span> n
merge of app<span style="color: #000000; font-weight: bold;">/</span>models<span style="color: #000000; font-weight: bold;">/</span>person.rb failed</pre></td></tr></table></div>

<p>If you&#8217;re in the middle of resolving conflicts in a number of files, this will exit out from the process.  You just need to re-run the mergetool command:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">git mergetool</span> <span style="color: #660033;">-t</span> opendiff</pre></td></tr></table></div>

<p>and it&#8217;ll pick up with the last unmerged file.</p>
<h4>Using a Configured Merge Tool</h4>
<p>DiffMerge is available for OS X.  The binary install is simple (the usual copy to the Application folder) and it comes with a shell script so it can be invoked from the command-line.  The minimal command to start a 3-way merge is</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;">diffmerge <span style="color: #660033;">--merge</span> <span style="color: #660033;">--result</span>=<span style="color: #007800;">$MERGED</span> <span style="color: #007800;">$LOCAL</span> <span style="color: #007800;">$BASE</span> <span style="color: #007800;">$REMOTE</span></pre></td></tr></table></div>

<p>The order of the files dictates which pane (left, middle or right) it be displayed in.  The middle pane is used as the editor for the merge and will need to start off with the common BASE version.  You can explicitly set the title of each pane via -t1=, -t2=, -t3= flags if you like (see the DiffMerge documentation [<a href="http://download-us.sourcegear.com/DiffMerge/3.2.0.18185/Linux/Ubuntu/DiffMergeManual.pdf">PDF</a>]).</p>
<p>I&#8217;ve tested the return code for successful and aborted merge scenarios and found that it returns 0 if the DiffMerge application ran successfully, not if the actual merge was successful.  Git will rely on a comparison between the temporary $MERGED file to determine if any changes were saved.  It will prompt you in the event the file is unchanged.</p>
<p>The configuration settings will be</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">git config</span> <span style="color: #660033;">--global</span> mergetool.diffmerge.cmd \
                    <span style="color: #ff0000;">&quot;diffmerge --merge --result=<span style="color: #000099; font-weight: bold;">\$</span>MERGED <span style="color: #000099; font-weight: bold;">\$</span>LOCAL <span style="color: #000099; font-weight: bold;">\$</span>BASE <span style="color: #000099; font-weight: bold;">\$</span>REMOTE&quot;</span>
<span style="color: #c20cb9; font-weight: bold;">git config</span> <span style="color: #660033;">--global</span> mergetool.diffmerge.trustExitCode <span style="color: #c20cb9; font-weight: bold;">false</span></pre></td></tr></table></div>

<p>You need to escape the $&#8217;s in the variables otherwise the shell will try the do the substitution before command gets placed in the configuration.</p>
<p>The .gitconfig entries will look like</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="text" style="font-family:monospace;">[mergetool &quot;diffmerge&quot;]
        cmd = diffmerge --merge --result=$MERGED $LOCAL $BASE $REMOTE
        trustExitCode = false</pre></td></tr></table></div>

<p>Running</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">git mergetool</span> <span style="color: #660033;">-t</span> diffmerge</pre></td></tr></table></div>

<p>starts DiffMerge showing the current version in the left pane, the merge result in the middle pane and the remote version in the right pane:</p>
<p><img class="aligncenter size-full wp-image-198" title="diffmerge" src="http://gitguru.com/wp-content/uploads/2009/02/diffmerge.png" alt="diffmerge" width="600" height="481" /></p>
<p>This may be easier for you to use to visualize the merge process than opendiff/FileMerge.</p>
<p>You should see the same basic output from execution of git mergetool with DiffMerge as was seen from opendiff/FileMerge:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">git mergetool</span> <span style="color: #660033;">-t</span> diffmerge
Merging the files: app<span style="color: #000000; font-weight: bold;">/</span>controllers<span style="color: #000000; font-weight: bold;">/</span>people_controller.rb
app<span style="color: #000000; font-weight: bold;">/</span>models<span style="color: #000000; font-weight: bold;">/</span>person.rb
&nbsp;
Normal merge conflict <span style="color: #000000; font-weight: bold;">for</span> <span style="color: #ff0000;">'app/controllers/people_controller.rb'</span>:
  <span style="color: #7a0874; font-weight: bold;">&#123;</span><span style="color: #7a0874; font-weight: bold;">local</span><span style="color: #7a0874; font-weight: bold;">&#125;</span>: modified
  <span style="color: #7a0874; font-weight: bold;">&#123;</span>remote<span style="color: #7a0874; font-weight: bold;">&#125;</span>: modified
Hit <span style="color: #7a0874; font-weight: bold;">return</span> to start merge resolution tool <span style="color: #7a0874; font-weight: bold;">&#40;</span>diffmerge<span style="color: #7a0874; font-weight: bold;">&#41;</span>: 
&nbsp;
Normal merge conflict <span style="color: #000000; font-weight: bold;">for</span> <span style="color: #ff0000;">'app/models/person.rb'</span>:
  <span style="color: #7a0874; font-weight: bold;">&#123;</span><span style="color: #7a0874; font-weight: bold;">local</span><span style="color: #7a0874; font-weight: bold;">&#125;</span>: modified
  <span style="color: #7a0874; font-weight: bold;">&#123;</span>remote<span style="color: #7a0874; font-weight: bold;">&#125;</span>: modified
Hit <span style="color: #7a0874; font-weight: bold;">return</span> to start merge resolution tool <span style="color: #7a0874; font-weight: bold;">&#40;</span>diffmerge<span style="color: #7a0874; font-weight: bold;">&#41;</span>:</pre></td></tr></table></div>

<p>If you&#8217;re using Git on Windows, definitely check out these posts on configuring DiffMerge and Git:</p>
<ul>
<li><a href="http://www.therightstuff.de/2009/01/28/Setting-Up-SourceGear-DiffMerge-With-Git.aspx">Setting up SourceGear DiffMerge with Git</a></li>
<li><a href="http://davesquared.blogspot.com/2009/02/setting-up-diff-and-merge-tools-for-git.html">Setting up diff and merge tools for Git on Windows</a></li>
</ul>
<p>There&#8217;s always a few extra things to be aware of on the Windows platform, especially when it comes to passing in command-line arguments in mixed UNIX shell/Windows CMD context.</p>
<p>A few final notes:</p>
<ul>
<li>git mergetool saves the merge-conflict version of the file with a &#8220;.orig&#8221; suffix.  Make sure to delete it before adding and committing the merge or add *.orig to your .gitignore</li>
<li>A <a href="http://www.kernel.org/pub/software/scm/git/docs/gitattributes.html#_defining_a_custom_merge_driver">custom merge driver</a> can be configured and set in order to override the built-in behavior of the git merge command.  This could be useful in order to deal with additional filetypes via an external diff/merge tool or if you wanted to invoke a visual merge tool for all merges.</li>
<li>IDE integrations for handling merges will depend both on the level of integration that&#8217;s possible with Git and the merge tool.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://gitguru.com/2009/02/22/integrating-git-with-a-visual-merge-tool/feed/</wfw:commentRss>
		<slash:comments>31</slash:comments>
		</item>
		<item>
		<title>Branching Strategies in Git – Overview</title>
		<link>http://gitguru.com/2009/02/18/branching-strategies-overview/</link>
		<comments>http://gitguru.com/2009/02/18/branching-strategies-overview/#comments</comments>
		<pubDate>Wed, 18 Feb 2009 18:00:58 +0000</pubDate>
		<dc:creator>long</dc:creator>
				<category><![CDATA[workflow]]></category>
		<category><![CDATA[branches]]></category>
		<category><![CDATA[lifecycle]]></category>
		<category><![CDATA[team]]></category>

		<guid isPermaLink="false">http://gitguru.com/?p=73</guid>
		<description><![CDATA[Creating a branch in Git is simple: $ git branch new_branch That&#8217;s all that&#8217;s absolutely required (see the man page for all the options).  And with that you now have a new branch to work on whose starting point is where you just were in your Git repository. So what can you do with it? [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: left;">Creating a branch in Git is simple:</p>
<p style="text-align: left; padding-left: 30px;"><code>$ git branch <em>new_branch</em></code></p>
<p style="text-align: left;">That&#8217;s all that&#8217;s absolutely required (see <a href="http://www.kernel.org/pub/software/scm/git/docs/git-branch.html">the man page</a> for all the options).  And with that you now have a new branch to work on whose starting point is where you just were in your Git repository.</p>
<p style="text-align: left;">So what can you do with it? Or more to the point, what should you do with it?<strong></strong></p>
<p style="text-align: left;"><strong>For a single developer</strong>, you can work on an experimental code path: You&#8217;ve got an idea about how a feature should be implemented and want to get started.  But you&#8217;ve also got some regular development that needs to take place at the same time (fixes, other features, etc.).  So create a branch and code away:</p>
<p style="text-align: left; padding-left: 30px;"><code>$ git branch feature_x dev<br />
$ git checkout feature_x<br />
# add/commit... add/commit... add/commit</code>
</p>
<p style="text-align: center;"><img class="size-full wp-image-81" title="Feature branch created off dev branch" src="http://gitguru.com/wp-content/uploads/2009/02/sd_branch.png" alt="Feature branch created off dev branch" width="500" height="175" /></p>
<p style="text-align: left;">If the feature code works out, you merge it back into your development branch.</p>
<p style="padding-left: 30px; text-align: left;"><code>$ git checkout dev<br />
$ git merge feature_x<br />
</code>
</p>
<p style="text-align: center;"><img class="alignnone size-full wp-image-95" title="Feature branch merged into dev branch" src="http://gitguru.com/wp-content/uploads/2009/02/sd_merge.png" alt="Feature branch merged into dev branch" width="500" height="175" /></p>
<p style="text-align: left;">If not, you just go back to the dev branch and delete feature_x:</p>
<p style="text-align: left; padding-left: 30px;"><code>$ git checkout dev<br />
$ git branch -D feature_x</code>
</p>
<p style="text-align: center;"><img class="size-full wp-image-120 aligncenter" title="Feature branch left unmerged" src="http://gitguru.com/wp-content/uploads/2009/02/sd_no_merge.png" alt="Feature branch left unmerged" width="500" height="175" /></p>
<p style="text-align: left;">Actually, you really don&#8217;t have to delete the branch.  You can leave it as is in case you want to easily go back to take a look at that work.</p>
<p style="text-align: left;"><strong>For a team</strong>, branches separate each developer&#8217;s individual updates.  The distributed nature of Git sets up a default branch structure: Each repository creates a new branch in the extended repository network.</p>
<p style="text-align: left;">For a set of repositories configured as</p>
<p style="text-align: center;"><img class="aligncenter size-full wp-image-123" title="Team repositories" src="http://gitguru.com/wp-content/uploads/2009/02/team_repositories.png" alt="Team repositories" width="500" height="275" /></p>
<p style="text-align: left;">the extended branch structure would look like</p>
<p style="text-align: center;"><img class="aligncenter size-full wp-image-124" title="Team branches" src="http://gitguru.com/wp-content/uploads/2009/02/team_branches.png" alt="Team branches" width="500" height="300" /></p>
<p style="text-align: left;">From your local repository, you&#8217;ll be limited to seeing only the branches on the remotes you&#8217;re connected to.</p>
<p style="text-align: left;">For Alice who&#8217;s connected to shared and Bob, the branches that her repository knows about are</p>
<p style="text-align: left; padding-left: 30px;"><code>alpha:alice $ git branch -a</code><code><br />
dev<br />
bob/dev<br />
shared/dev</code>
</p>
<p style="text-align: left;">For Bob who&#8217;s connected to shared and Alice,</p>
<p style="text-align: left; padding-left: 30px;"><code>beta:bob $ git branch -a</code><code><br />
dev<br />
alice/dev<br />
shared/dev</code>
</p>
<p style="text-align: left;">And for Chris,</p>
<p style="text-align: left; padding-left: 30px;"><code>gamma:chris $ git branch -a<br />
dev<br />
shared/dev<br />
</code>
</p>
<p style="text-align: left;"><strong>For a project</strong>, a branch could represent a new feature set or version of an application.  Updates are pushed up to an &#8220;integration&#8221; branch by developers as they are completed.  This is similar to the use of branching by a single developer but on a more formalized, process-driven basis.</p>
<p style="text-align: center;"><img class="aligncenter size-full wp-image-127" title="Project integration" src="http://gitguru.com/wp-content/uploads/2009/02/prj_integration.png" alt="Project integration" width="500" height="300" /></p>
<p style="text-align: left;">In this case, Alice has already merged her changes for Project A into the shared integration branch.  Bob and Chris are still working on their changes and will need to pull in the updates before they&#8217;ll be able to push up to shared/integration.</p>
<p style="text-align: left;">Branches can also be used to represent the application&#8217;s lifecycle, with separate branches for each state such as development, test, and production.</p>
<p style="text-align: center;"><img class="aligncenter size-full wp-image-128" title="Lifecycle via branches" src="http://gitguru.com/wp-content/uploads/2009/02/lifecycle.png" alt="Lifecycle via branches" width="600" height="200" /></p>
<p style="text-align: left;">This is the ideal case where changes flow from development to test and then from test to production.</p>
<p style="text-align: left;">These strategies are, of course, only a starting point.  Your actual branching structure will depend on your team and where you are in your application development cycle.  And odds are it&#8217;ll evolve along the way.</p>
<p style="text-align: left;">We&#8217;ll be going into more detail in future posts.</p>
]]></content:encoded>
			<wfw:commentRss>http://gitguru.com/2009/02/18/branching-strategies-overview/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Rebase v Merge in Git</title>
		<link>http://gitguru.com/2009/02/03/rebase-v-merge-in-git/</link>
		<comments>http://gitguru.com/2009/02/03/rebase-v-merge-in-git/#comments</comments>
		<pubDate>Tue, 03 Feb 2009 20:04:56 +0000</pubDate>
		<dc:creator>long</dc:creator>
				<category><![CDATA[commands]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[merge]]></category>
		<category><![CDATA[rebase]]></category>

		<guid isPermaLink="false">http://gitguru.com/?p=22</guid>
		<description><![CDATA[If you haven&#8217;t worked with a version control tool that allows for easy branching, you&#8217;re probably wondering what the difference is between rebase and merge and why you&#8217;d choose one over the other. From the standpoint of the end result, a merge and a rebase in Git appear to do the same thing: A + [...]]]></description>
			<content:encoded><![CDATA[<p>If you haven&#8217;t worked with a version control tool that allows for easy branching, you&#8217;re probably wondering what the difference is between rebase and merge and why you&#8217;d choose one over the other.</p>
<p>From the standpoint of the end result, a <a href="http://www.kernel.org/pub/software/scm/git/docs/git-merge.html">merge</a> and a <a href="http://www.kernel.org/pub/software/scm/git/docs/git-rebase.html">rebase</a> in Git appear to do the same thing:</p>
<p style="padding-left: 30px;"><strong>A</strong> + <strong>B</strong> + <strong>A&#8217;</strong> (merge) = <strong>A</strong> + <strong>A&#8217;</strong> + <strong>B</strong> (rebase)</p>
<p>Wouldn&#8217;t it be simpler to just choose one operation and stick with it?</p>
<p>The answer of course is no.  Otherwise you wouldn&#8217;t have the option.  (If you feel completely contrary, best of luck.  And choose merge.)</p>
<p>It really only becomes apparent once your development effort becomes hierarchical, either in terms of application lifecycle (such as dev, test and release versions) or in a team structure.  You&#8217;re now dealing with multiple branches, each with non-trivial changes that can and will occur independently.</p>
<p>Rebases are how changes should pass from the top of hierarchy downwards and merges are how they flow back upwards.</p>
<p>Let&#8217;s take a look in more detail at what is actually taking place in each operation for a parent branch <strong>A</strong> and a child branch <strong>B</strong>:</p>
<p style="padding-left: 30px;"><span style="text-decoration: underline;">Merge</span><strong></strong></p>
<p style="padding-left: 30px;"><strong>A</strong> + <strong>B</strong> + <strong>A&#8217;</strong> + <strong>dA&#8217;B</strong></p>
<p style="padding-left: 30px;">where <strong>A&#8217;</strong> are the changes being merged in and <strong>dA&#8217;B</strong> the resolution of merge conflicts from <strong>A&#8217;</strong> and the set of commits <strong>B</strong> on the current branch</p>
<p style="padding-left: 30px;">The changes introduced by <strong>A&#8217;</strong> and <strong>dA&#8217;B</strong> are grouped together into one merge commit <strong>A&#8221;</strong> = <strong>A&#8217;</strong> + <strong>dA&#8217;B</strong> that is added on top of the existing set of commits (<strong>A</strong> + <strong>B</strong>) and becomes the head of the current branch:</p>
<p style="padding-left: 30px;"><strong>A</strong> + <strong>B</strong> + <strong>A&#8221;</strong></p>
<p style="padding-left: 30px;"><strong></strong><span style="text-decoration: underline;">Rebase</span></p>
<p style="padding-left: 30px;"><strong>A</strong> + <strong>A&#8217;</strong> + <strong>B</strong> + <strong>dA&#8217;B</strong></p>
<p style="padding-left: 30px;">The rebase resets the starting point the branch and reapplies the set of commits <strong>B</strong>.  Merge conflicts <strong>dA&#8217;B</strong> are combined with these commits so they become grouped together <strong>B&#8217;</strong> = <strong>B</strong> + <strong>dA&#8217;B</strong>:</p>
<p style="padding-left: 30px;"><strong>A</strong> + <strong>A&#8217;</strong> + <strong>B&#8217;</strong></p>
<p>If you stare at it, you&#8217;ll realize that the rebase guarantees that the changes being brought it in from the other branch come in exactly as-is: <strong>A</strong> + <strong>A&#8217;</strong>.  Any conflicts are resolved and contained with the associated commits <strong>B&#8217;</strong> on the current branch.</p>
<p>Using merge to pull in changes from the higher-level branch mixes those changes with the resolved merge conflicts.  This means that the current branch won&#8217;t necessarily have the same state as the one it was based on (from the hierarchical structure).  And since the resolved conflicts are grouped all together in one merge commit, you&#8217;ve also made it harder to cleanly cherry-pick individual changes.</p>
<p>Having development lifecycle tracks and each local developer branch start from known consistent states is critical to reducing and resolving code issues.  Where a change occurs (or suddenly becomes missing) and who is responsible become easier to determine.  By using the rebase to pull in changes, you have that.</p>
<p>When you&#8217;re submitting changes back up the chain, you only want to add your changes on top of the existing commits of the higher-level branch.  Merge is clearly the operation for that.</p>
<p>Even if you&#8217;re a single developer with only a few branches, it&#8217;s worth it to get in the habit of using rebase and merge properly.  The basic work pattern will look like:</p>
<ol>
<li>Create new branch <strong>B</strong> from existing branch <strong>A</strong></li>
<li>Add/commit changes on branch <strong>B</strong></li>
<li>Rebase updates from branch <strong>A</strong></li>
<li>Merge changes from branch <strong>B</strong> onto branch <strong>A</strong></li>
</ol>
<p><strong><br />
</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://gitguru.com/2009/02/03/rebase-v-merge-in-git/feed/</wfw:commentRss>
		<slash:comments>20</slash:comments>
		</item>
		<item>
		<title>Git is just a tool</title>
		<link>http://gitguru.com/2009/01/29/git-is-just-a-tool/</link>
		<comments>http://gitguru.com/2009/01/29/git-is-just-a-tool/#comments</comments>
		<pubDate>Fri, 30 Jan 2009 07:15:20 +0000</pubDate>
		<dc:creator>long</dc:creator>
				<category><![CDATA[git]]></category>
		<category><![CDATA[scm]]></category>

		<guid isPermaLink="false">http://gitguru.com/?p=3</guid>
		<description><![CDATA[Repeat after me: Git is just a tool. That&#8217;s not a bad thing.  It simply means that it&#8217;s not any more or any less than what it claims to be: a distributed version control system.  And it&#8217;s very good at what it does. But once you get beyond the initial repository setup and the standard [...]]]></description>
			<content:encoded><![CDATA[<p>Repeat after me: <a href="http://git-scm.com/">Git</a> is just a tool.</p>
<p>That&#8217;s not a bad thing.  It simply means that it&#8217;s not any more or any less than what it claims to be: a distributed version control system.  And it&#8217;s very good at what it does.</p>
<p>But once you get beyond the initial repository setup and the standard add/commit cycle, you&#8217;re inevitably going to have a few questions:</p>
<ul>
<li> How often should I commit my changes?</li>
<li> When should I create a new branch?</li>
<li> What do I need to do to share my updates?</li>
</ul>
<p>And these lead to a few more</p>
<ul>
<li> How do I manage all these branches?</li>
<li> When should I merge the changes from my branches together?</li>
<li> What&#8217;s the difference between a merge and rebase?</li>
</ul>
<p>If you&#8217;re working in a team, you&#8217;ll probably also have</p>
<ul>
<li> What&#8217;s everyone working on?</li>
<li> Do I have the latest updates?</li>
<li> When do I submit my changes to the team?</li>
</ul>
<p>And if you&#8217;ve been going for a while, you&#8217;ll want to know</p>
<ul>
<li>How do I simultaneously manage a release and a development version?</li>
<li>Did that production fix get back into development?</li>
<li>What did I just release?</li>
</ul>
<p>At this point, you&#8217;re starting to slip into the realm of <a href="http://en.wikipedia.org/wiki/Software_configuration_management">software configuration management (SCM)</a>.  Version control is just a small part of that.</p>
<p>The bad news is that Git doesn&#8217;t say anything about how you should do any of this (FYI, the <a href="http://github.com/guides/pull-requests">pull request</a> is more a suggestion than a formal required process even if it&#8217;s what <a href="http://www.youtube.com/watch?v=4XpnKHJAok8">Linus does</a>).  It&#8217;s also the good news: You have all the technical capabilities you need but you&#8217;re not tied to a rigid one-size-fits-all process.</p>
<p>The key thing to remember is that Git isn&#8217;t the first VCS tool out there, even if it might be the first one you&#8217;re using.  There&#8217;s an amazing wealth of SCM knowledge to tap into.  It&#8217;s a matter of starting with what works and figuring out how Git fits into that.</p>
]]></content:encoded>
			<wfw:commentRss>http://gitguru.com/2009/01/29/git-is-just-a-tool/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss><!-- Dynamic page generated in 1.152 seconds. --><!-- Cached page generated by WP-Super-Cache on 2013-05-18 19:18:19 --><!-- Compression = gzip -->
