<?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>Dariusz on Software Quality &#187; vcs</title>
	<atom:link href="http://blog.aplikacja.info/tag/vcs/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.aplikacja.info</link>
	<description>Software Engineering Process and Tools</description>
	<lastBuildDate>Tue, 31 Jan 2012 23:44:29 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Bazaar to GIT migration</title>
		<link>http://blog.aplikacja.info/2011/10/bazaar-to-git-migration/</link>
		<comments>http://blog.aplikacja.info/2011/10/bazaar-to-git-migration/#comments</comments>
		<pubDate>Mon, 17 Oct 2011 20:47:00 +0000</pubDate>
		<dc:creator>dariusz.cieslak</dc:creator>
				<category><![CDATA[en]]></category>
		<category><![CDATA[bzr]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[s-u]]></category>
		<category><![CDATA[vcs]]></category>

		<guid isPermaLink="false">http://blog.aplikacja.info/?p=1632</guid>
		<description><![CDATA[Today I moved using site-uptime.net development from Bazaar repository to GIT using elegant bzr2git script. The why:

In-place branches (I used to use them heavily)
Faster (no Python libs loading during &#8220;cold&#8221; start)
Can&#8217;t live without &#8220;git rebase -i&#8221; now  

]]></description>
			<content:encoded><![CDATA[<p>Today I moved using <a href="http://site-uptime.net">site-uptime.net</a> development from Bazaar repository to GIT using elegant <a href="http://blog.coldtobi.de/1_coldtobis_blog/archive/277_bzr2git_--_make_a_git_repositpry_out_of_a_bazaar_one.html">bzr2git</a> script. The why:</p>
<ul>
<li>In-place branches (I used to use them heavily)<a href="http://blog.aplikacja.info/wp-content/uploads/2011/07/git.gif"><img style=' float: right; padding: 4px; margin: 0 0 2px 7px;'  class="alignright size-full wp-image-1571" title="git" src="http://blog.aplikacja.info/wp-content/uploads/2011/07/git.gif" alt="" width="500" height="67" /></a></li>
<li>Faster (no Python libs loading during &#8220;cold&#8221; start)</li>
<li>Can&#8217;t live without &#8220;<a href="http://book.git-scm.com/4_interactive_rebasing.html">git rebase -i</a>&#8221; now <img src='http://blog.aplikacja.info/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.aplikacja.info/2011/10/bazaar-to-git-migration/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Fixing invalid comment / branch name in GIT</title>
		<link>http://blog.aplikacja.info/2011/09/fixing-invalid-comment-branch-name-in-git/</link>
		<comments>http://blog.aplikacja.info/2011/09/fixing-invalid-comment-branch-name-in-git/#comments</comments>
		<pubDate>Wed, 14 Sep 2011 22:35:33 +0000</pubDate>
		<dc:creator>dariusz.cieslak</dc:creator>
				<category><![CDATA[en]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[vcs]]></category>

		<guid isPermaLink="false">http://blog.aplikacja.info/?p=1602</guid>
		<description><![CDATA[Recently I was asked to help with fixing branch that had:

invalid name (wrong artifact number)
invalid comment inside (also based on wrong artifact number)

it was a mistake and programmer wanted to preserve changes done on branch, but using different name.
The solution I proposed was to:


clone existing branch under different name
&#8220;amend&#8221; last commit on this new branch [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://blog.aplikacja.info/wp-content/uploads/2011/07/git.gif"><img style=' float: right; padding: 4px; margin: 0 0 2px 7px;'  class="alignright size-full wp-image-1571" title="git" src="http://blog.aplikacja.info/wp-content/uploads/2011/07/git.gif" alt="" width="500" height="67" /></a>Recently I was asked to help with fixing branch that had:</p>
<ul>
<li>invalid name (wrong artifact number)</li>
<li>invalid comment inside (also based on wrong artifact number)</li>
</ul>
<p>it was a mistake and programmer wanted to preserve changes done on branch, but using different name.</p>
<p>The solution I proposed was to:</p>
<p><span id="more-1602"></span></p>
<ol>
<li><strong>clone</strong> existing branch under different name</li>
<li><strong>&#8220;amend&#8221;</strong> last commit on this new branch (to fix comment)</li>
<li><strong>push</strong> new branch into correct location</li>
<li><strong>drop</strong> old branch</li>
</ol>
<p>Sequence of GIT commands was:</p>
<pre style="padding-left: 30px;">$ git branch corect-name origin/invalid-name
(We saved desired SHA with new name)
$ git checkout corect-name
$ git commit --amend
(Fix comment of last commit in editor)
$ git push origin corect-name
(Fixed branch published on our default remote)
$ git push origin :invalid-name
(Weird GIT syntax for deleting remote branches)
</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.aplikacja.info/2011/09/fixing-invalid-comment-branch-name-in-git/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>GIT: importing remote branches</title>
		<link>http://blog.aplikacja.info/2011/01/git-importing-remote-branches/</link>
		<comments>http://blog.aplikacja.info/2011/01/git-importing-remote-branches/#comments</comments>
		<pubDate>Tue, 25 Jan 2011 23:19:00 +0000</pubDate>
		<dc:creator>dariusz.cieslak</dc:creator>
				<category><![CDATA[en]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[vcs]]></category>

		<guid isPermaLink="false">http://blog.aplikacja.info/?p=1429</guid>
		<description><![CDATA[GIT is a fast version control system that handles branching very efficiently and allow for most operations to be done offline (is a distributed VCS). Of course sometimes you have to exchange code with external GIT repos (maybe central storage). Being distributed forces some design decisions: local/remote branches distrinction were introduced.
Remote branch in GIT is [...]]]></description>
			<content:encoded><![CDATA[<p>GIT is a fast version control system that handles branching very efficiently and allow for most operations to be done offline (is a distributed VCS). Of course sometimes you have to exchange code with external GIT repos (maybe central storage). Being distributed forces some design decisions: <strong>local/remote branches distrinction</strong> were introduced.</p>
<p><strong>Remote branch</strong> in GIT is a head that tracks branch stored on server. You shouldn&#8217;t update (commit) directly that branch. You can update local branches instead then use &#8220;push&#8221; to publish changes from local branch to remote. Remote branch can be used to answer the following questions:</p>
<ul>
<li>is my local branch up to date regarding to server state?</li>
<li>what changes (diff/log) were added to my local branch and aren&#8217;t submitted (push) yet?</li>
</ul>
<p>In order to use properly remote branches you have to <strong>create maching local branch</strong> for every remote branch. Boring and error-prone task. Let&#8217;s automate it:!</p>
<pre style="padding-left: 30px;">git branch -a | awk \
    '/RELEASE/ { sub("remotes/origin/", "", $1); \
    print "git branch --track " $1 " origin/" $1 }' | sh
</pre>
<p>Above command <strong>imports all branches</strong> that contain string &#8220;RELEASE&#8221; (I assume we may be interested in checking release status).</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.aplikacja.info/2011/01/git-importing-remote-branches/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>&#8220;git cherry-pick&#8221; for Perforce</title>
		<link>http://blog.aplikacja.info/2010/11/git-cherry-pick-for-perforce/</link>
		<comments>http://blog.aplikacja.info/2010/11/git-cherry-pick-for-perforce/#comments</comments>
		<pubDate>Thu, 11 Nov 2010 22:30:38 +0000</pubDate>
		<dc:creator>dariusz.cieslak</dc:creator>
				<category><![CDATA[en]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[perforce]]></category>
		<category><![CDATA[vcs]]></category>

		<guid isPermaLink="false">http://blog.aplikacja.info/?p=1390</guid>
		<description><![CDATA[Cherry-picking is a technique of porting only selected commits from one branch to another. It&#8217;s directly supported in GIT by special command:
git cherry-pick &#60;SHA-COMMIT-ID&#62;
Also SVN has simple merge mode that supports selecting of single commit:
svn merge -c &#60;REV-NO&#62; &#60;URL&#62;
What about Perforce? After checking Perforce documentation for merging I hit the following syntax for selecting subset [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://blog.aplikacja.info/wp-content/uploads/2010/09/perforce.gif"><img style=' float: right; padding: 4px; margin: 0 0 2px 7px;'  class="alignright size-full wp-image-1281" title="perforce" src="http://blog.aplikacja.info/wp-content/uploads/2010/09/perforce.gif" alt="" width="200" height="46" /></a>Cherry-picking is a technique of <strong>porting only selected commits</strong> from one branch to another. It&#8217;s directly supported in GIT by <a href="http://www.kernel.org/pub/software/scm/git/docs/git-cherry-pick.html">special command</a>:</p>
<pre style="padding-left: 30px;">git cherry-pick &lt;SHA-COMMIT-ID&gt;</pre>
<p>Also SVN has <strong>simple merge mode</strong> that supports <a href="http://stackoverflow.com/questions/126320/subversion-cherry-picking">selecting of single commit</a>:</p>
<pre style="padding-left: 30px;">svn merge -c &lt;REV-NO&gt; &lt;URL&gt;</pre>
<p>What about Perforce? After checking <a href="http://www.perforce.com/perforce/doc.current/manuals/p4guide/06_codemgmt.html">Perforce documentation for merging</a> I hit the following <strong>syntax for selecting subset of changelists</strong> to merge:</p>
<p><span id="more-1390"></span></p>
<pre style="padding-left: 30px;">p4 integrate //depot/release/jam/...@30,@30 ...</pre>
<p>That&#8217;s it: add <strong>the same change list id twice</strong> (separated by comma) to source URL and you will get cherry-pick!</p>
<p>[2011-04-20] Update: looks like sometimes @CL,@CL will not merge change properly, it&#8217;s better to use <strong>SVN-style revision range mode</strong> (@CL-1,@CL):</p>
<pre style="padding-left: 30px;">p4 integrate //depot/release/jam/...@29,@30 ...</pre>
<p>Perforce has additional step to perform:</p>
<pre style="padding-left: 30px;">p4 resolve -af</pre>
<p>that walks thru all changes from integrate step and allow to <strong>check for conflicts</strong>. Of course in the end you have to commit changes.</p>
<pre style="padding-left: 30px;">p4 submit
</pre>
<p>BTW. I (still) don&#8217;t see <strong>any benefit from using Perforce</strong> over well-known SVN. Anyone?</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.aplikacja.info/2010/11/git-cherry-pick-for-perforce/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Software Releases Using GIT</title>
		<link>http://blog.aplikacja.info/2010/11/software-releases-using-git/</link>
		<comments>http://blog.aplikacja.info/2010/11/software-releases-using-git/#comments</comments>
		<pubDate>Mon, 08 Nov 2010 22:31:05 +0000</pubDate>
		<dc:creator>dariusz.cieslak</dc:creator>
				<category><![CDATA[en]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[svn]]></category>
		<category><![CDATA[vcs]]></category>

		<guid isPermaLink="false">http://blog.aplikacja.info/?p=1376</guid>
		<description><![CDATA[Releasing Software is not just packing latest version to tarball and send to SFTP server. It requires preparation and some planning to be done properly. I&#8217;ll describe release procedure I applied on one of my latest projects. Supporting version control system is GIT.
The aims for releasing procedure designed:

allow for testing window before release date
have the [...]]]></description>
			<content:encoded><![CDATA[<p><strong><a href="http://blog.aplikacja.info/wp-content/uploads/2010/11/floppy-disk.jpg"><img style=' float: right; padding: 4px; margin: 0 0 2px 7px;'  class="alignright size-full wp-image-1377" title="floppy-disk" src="http://blog.aplikacja.info/wp-content/uploads/2010/11/floppy-disk.jpg" alt="" width="250" height="225" align="right"/></a>Releasing Software is not just packing latest version</strong> to tarball and send to SFTP server. It requires preparation and some planning to be done properly. I&#8217;ll describe release procedure I applied on one of my latest projects. Supporting version control system is <a href="http://git-scm.com/">GIT</a>.</p>
<p>The aims for releasing procedure designed:</p>
<ul>
<li>allow for <strong>testing window</strong> before release date</li>
<li>have the possibility for <strong>examine released version</strong> to test for reported bugs</li>
<li>possibility to manage existing releases (<strong>hot-fixing</strong> critical bugs)</li>
</ul>
<p><span id="more-1376"></span></p>
<h2>Prepare Release Candidate Branch</h2>
<p><a href="http://blog.aplikacja.info/wp-content/uploads/2010/11/branch.jpg"><img style=' float: right; padding: 4px; margin: 0 0 2px 7px;'  class="alignright size-full wp-image-1382" title="branch" src="http://blog.aplikacja.info/wp-content/uploads/2010/11/branch.jpg" alt="" width="200" height="143"  align="right"/></a>We want to stabilize and test some snapshot of current development branch. That&#8217;s why I&#8217;m <strong>forking few days before release RC branch</strong> from &#8220;master&#8221; and switch (it will be used for hot-fixing):</p>
<pre style="padding-left: 30px;">git branch RELEASE_0.2.1_branch
git push origin RELEASE_0.2.1_branch
git co RELEASE_0.2.1_branch
</pre>
<p>I&#8217;m marking RC state (RC=Release Candidate) to be able to see changes done for released version:</p>
<pre style="padding-left: 30px;">git tag RELEASE_0.2.1_RC
git push --tags</pre>
<p>Anyone familiar with advanced CVS usage will see similarities to <a href="http://kb.wisc.edu/middleware/page.php?id=4087">tagging for CVS merge purposes</a>. GIT tracks merges automatically, however marking branch starting point is a good idea.</p>
<p>As you can see I created simple naming convention schema to manage releases.</p>
<h2>Prepare Release</h2>
<p>Time after creating RC branch and before releasing from this branch is the <strong>time for testers to do their job</strong> and sweep out as many defects as possible. Fixes are added directly on release branch (we will port them to master later).</p>
<p>When tests are done we are preparing release and tag current version by RELEASE_0.2.1</p>
<pre style="padding-left: 30px;">git commit -a -m "version number changed (#XYZ)"
git tag RELEASE_0.2.1
git push --tags</pre>
<p>By this tag we will be able to inspect exact version that was sent to our clients.</p>
<h2>Prepare hotfix</h2>
<p>Sometimes out safety net composed of automated test suite and testing team fails and we have to fix errors reported from production. That is the purpose for release candidate branch. First, switch to correct branch that supports hot-fixed release:</p>
<pre style="padding-left: 30px;">git branch --track RELEASE_0.2.1_branch origin/RELEASE_0.2.1_branch
==OR==: git co RELEASE_0.2.1_branch; git pull origin
</pre>
<p>Tag current version that goes in this hotfix by RELEASE_0.2.1_hotfix_YYYYMMDD:</p>
<pre style="padding-left: 30px;">git commit -a -m "version number changed (#XYZ)"
git tag RELEASE_0.2.1_hotfix_YYYYMMDD
git push --tags</pre>
<p>As you might noticed naming convention is based on branch name. Thanks to this convention we can answer the following questions:</p>
<ul>
<li>what hot-fixes were prepared for release X?</li>
<li>what is the latest hotfix for release X?</li>
<li>what was delivered in latest hotifix of release X?</li>
<li>etc.</li>
</ul>
<h2>Porting back changes from branch to master</h2>
<p>Sometimes changes made on branch will be useful for next releases. You can easily merge them back to master:</p>
<pre style="padding-left: 30px;">$ git co master
$ git merge RELEASE_0.2.1
$ git push
</pre>
<p>GIT tracks what have been merged already so you can merge/cherry-pick in both directions.</p>
<h2>Typical Usage</h2>
<p>What changes were included in latest hotfix compared to previous one:</p>
<pre style="padding-left: 30px;"> $ git diff RELEASE_0.2.1_hotfix_date1 RELEASE_0.2.1_hotfix_date2</pre>
<p>What changes were added in new release:</p>
<pre style="padding-left: 30px;">$ git log  RELEASE_0.2..RELEASE_0.2.1
$ git diff RELEASE_0.2..RELEASE_0.2.1</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.aplikacja.info/2010/11/software-releases-using-git/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Git: &#8220;pull &#8211;rebase&#8221; by default</title>
		<link>http://blog.aplikacja.info/2010/11/git-pull-rebase-by-default/</link>
		<comments>http://blog.aplikacja.info/2010/11/git-pull-rebase-by-default/#comments</comments>
		<pubDate>Mon, 08 Nov 2010 21:44:12 +0000</pubDate>
		<dc:creator>dariusz.cieslak</dc:creator>
				<category><![CDATA[en]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[vcs]]></category>

		<guid isPermaLink="false">http://blog.aplikacja.info/?p=1370</guid>
		<description><![CDATA[GIT is a distributed version control system that allows to share codebase between developers. Born in Linux kernel world proved to be very useful for any programming task. &#8220;Distributed&#8221; means you can commit locally (during flight), syncing commits to some external repository is done in separate step (at the airport, waiting for luggage).
During watching my [...]]]></description>
			<content:encoded><![CDATA[<p>GIT is a <strong>distributed version control system</strong> that allows to share codebase between developers. Born in Linux kernel world proved to be very useful for any programming task. &#8220;Distributed&#8221; means you can commit locally (during flight), syncing commits to some external repository is done in separate step (at the airport, waiting for luggage).</p>
<p>During watching my commit list using gitk I noticed many developers are <strong>accidentially merging their changes</strong> without so called &#8220;fast forward&#8221; (additional commit is created and the history is not linear). Why? The cause is that they are pulling changes from server AFTER local commit. A example commit tree taken from this <a href="http://www.gitready.com/advanced/2009/02/11/pull-with-rebase.html">worth-reading article</a>:</p>
<p><a href="http://blog.aplikacja.info/wp-content/uploads/2010/11/pull4.png"><img style=' display: block; margin-right: auto; margin-left: auto;'  class="aligncenter size-full wp-image-1372" title="pull4" src="http://blog.aplikacja.info/wp-content/uploads/2010/11/pull4.png" alt="" width="441" height="201"  align="center" /></a></p>
<p><span id="more-1370"></span></p>
<p>The solution for this problem is to use <strong>&#8220;git pull &#8211;rebase&#8221;</strong> when downloading changes from repository. Existing local commits will be &#8220;rebased&#8221; (SHA-ids will change) and the history will be left linear. It looks much better:</p>
<p><a href="http://blog.aplikacja.info/wp-content/uploads/2010/11/pull2.png"><img style=' display: block; margin-right: auto; margin-left: auto;'  class="aligncenter size-full wp-image-1373" title="pull2" src="http://blog.aplikacja.info/wp-content/uploads/2010/11/pull2.png" alt="" width="469" height="136"  align="center"/></a></p>
<p>&#8220;Rebasing&#8221; can be requested during pull by using this syntax:</p>
<pre style="padding-left: 30px;">git pull --rebase</pre>
<p>I bet you will forget that after n-th commit <img src='http://blog.aplikacja.info/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' />  That&#8217;s why GIT allows to make rebase default option. Just do for every branch you have (including &#8220;master&#8221;):</p>
<pre style="padding-left: 30px;">git config branch.master.rebase true
git config branch.branch_10.rebase true
...</pre>
<p>And tell GIT to setup such rule for every new branch:</p>
<pre style="padding-left: 30px;">git config branch.autosetuprebase always</pre>
<p>Of course you can disable automatic &#8220;rebasing&#8221; when needed:</p>
<pre style="padding-left: 30px;">git pull --no-rebase</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.aplikacja.info/2010/11/git-pull-rebase-by-default/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>&#8220;svn status&#8221; for Perforce</title>
		<link>http://blog.aplikacja.info/2010/10/svn-status-for-perforce/</link>
		<comments>http://blog.aplikacja.info/2010/10/svn-status-for-perforce/#comments</comments>
		<pubDate>Wed, 20 Oct 2010 18:54:48 +0000</pubDate>
		<dc:creator>dariusz.cieslak</dc:creator>
				<category><![CDATA[en]]></category>
		<category><![CDATA[perforce]]></category>
		<category><![CDATA[scripts]]></category>
		<category><![CDATA[vcs]]></category>

		<guid isPermaLink="false">http://blog.aplikacja.info/?p=1351</guid>
		<description><![CDATA[Status command is very important part of  any VCS (Version Control System) local interface. It allows you to check your workspace state and ensure correct commit will be created.
Perforce is a commercial VCS that is similar to CVS (revisions per file) and SVN (global revisions of whole tree). It&#8217;s support for status command is very [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://blog.aplikacja.info/wp-content/uploads/2010/09/perforce.gif"><img style=' float: right; padding: 4px; margin: 0 0 2px 7px;'  class="alignright size-full wp-image-1281" title="perforce" src="http://blog.aplikacja.info/wp-content/uploads/2010/09/perforce.gif" alt="" width="200" height="46" align="right" /></a>Status command is very important part of  any VCS (Version Control System) local interface. It allows you to <strong>check your workspace state</strong> and ensure correct commit will be created.</p>
<p><strong>Perforce is a commercial VCS</strong> that is similar to CVS (revisions per file) and SVN (global revisions of whole tree). It&#8217;s support for status command is very clumsy. Let&#8217;s check how we can emulate status with this tool using small script:</p>
<pre style="padding-left: 30px;">echo === extra files not tracked by Perforce ===
find . '!' -type d '!' -executable | p4 -x - have 2&gt;&amp;1 | grep 'not on client' | \
 sed '/\/moc_/d;/\.so/d;/\.o /d;/Makefile /d;/\.a /d'

echo === Current changelist ===
p4 changelist -o</pre>
<p>As you can see we implemented <strong>&#8220;ignore&#8221; mechanism</strong> in above script (by sed filtering). &#8220;Extra files not tracked by Perforce&#8221; reflects &#8220;?&#8221;-status from CVS/SVN. &#8220;Current changelist&#8221; reflects &#8220;A,D,U&#8221;-statuses from CVS/SVN.</p>
<p>By using such script you can ensure your <strong>commit contains all files</strong> from your workspace, thus will be buildable on other developers&#8217; machines.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.aplikacja.info/2010/10/svn-status-for-perforce/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Codebase Integration Scenarios</title>
		<link>http://blog.aplikacja.info/2010/10/codebase-integration-scenarios/</link>
		<comments>http://blog.aplikacja.info/2010/10/codebase-integration-scenarios/#comments</comments>
		<pubDate>Sat, 16 Oct 2010 14:28:02 +0000</pubDate>
		<dc:creator>dariusz.cieslak</dc:creator>
				<category><![CDATA[en]]></category>
		<category><![CDATA[c++]]></category>
		<category><![CDATA[integration]]></category>
		<category><![CDATA[perforce]]></category>
		<category><![CDATA[pm]]></category>
		<category><![CDATA[vcs]]></category>

		<guid isPermaLink="false">http://blog.aplikacja.info/?p=1311</guid>
		<description><![CDATA[Last week I&#8217;ve been observing details of integrating source code coming from three different development teams (located in different countries). Each team owns some subset of modules and has R/W access only to those modules. Of course compile dependencies cross the borders in many places, so global changes usually done in one commit had to [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://blog.aplikacja.info/wp-content/uploads/2010/10/integration-1.png"><img style=' float: right; padding: 4px; margin: 0 0 2px 7px;'  class="alignright size-full wp-image-1318" title="integration-1" src="http://blog.aplikacja.info/wp-content/uploads/2010/10/integration-1.png" alt="" width="300" height="271" align="right" /></a>Last week I&#8217;ve been observing details of <strong>integrating source code</strong> coming from three different development teams (located in different countries). Each team owns some subset of modules and has R/W access only to those modules. Of course compile dependencies cross the borders in many places, so global changes usually done in one commit had to be split into at least two commits (because of missing W permission for someone).</p>
<p>There was one development branch and one integration branch. Development branch most of this time was in not &#8220;buildable&#8221; state (permanent build error), so no one was able to ensure changes are not breaking the build before commit until stabilisation. Integration branch was loaded using files copied from development branch when stable state was achieved (I know, lame). This integration style (allowing for non-buildable commits on development branch) <strong>blocks parallel integrations</strong> (one have to wait for stable state on development branch).</p>
<p>Are there better ways to organise such integration?<br />
<span id="more-1311"></span></p>
<h2>Shared Codebase Ownership</h2>
<p>In this scenario every team has <strong>full write access to all modules</strong> and it&#8217;s possible to create single commit by team T1 that spans module boundaries: refactors module A (owned by T2) AND calling code from module B (owned by T1).</p>
<p>There will be only one &#8220;a must&#8221; rule: <strong>all codebase should be compilable</strong> after every commit. Modifications to &#8220;not owned&#8221; modules should be minimised (only to make code compilable), probably with some &#8220;FIXME&#8221; left in code.</p>
<p>Doing that operations in single commit allows you (1) to inspect that commit afterwards (2) retain &#8220;green build&#8221; property after every commit.</p>
<p>Having always-compilable head we will be able to schedule such operations in paralell. Nobody will be blocked (of course teams have to communicate/consult such cross-border changes before commit).</p>
<p>In this case applied changes are visible by <strong>diff-ing selected changesets</strong>.</p>
<h2>Topic Branches</h2>
<p>If globally shared codebase is not an idea to be considered we could use <strong>short-living branches</strong> (called sometimes &#8220;topic branches&#8221;) that get updates from both teams and after stabilisation they are merged back into main branch (and deleted).</p>
<p>Code on topic branch could be unstable, on development branch must be always stable.</p>
<p>Note that merging person should have write access to all &#8220;dev&#8221; branch (in this aspect this strategy is similar to previous one). I used to place at this point code review process.</p>
<p>In this case pending changes are visible by doing a <strong>diff on existing topic branch</strong>.</p>
<h2>Moving &#8220;Stable&#8221; Tag</h2>
<p>This strategy can be used for file-tracking systems like CVS or Perforce. For those VCS-es one can move tag to new version for subset of files (SVN, GIT, Bazaar will not allow that).</p>
<p>Person that created &#8220;stable&#8221; commit should create/move some tag to current revision.</p>
<pre style="padding-left: 30px;">$ p4 tag -l STABLE ...</pre>
<p>Then anyone interested in stable state would sync to that state:</p>
<pre style="padding-left: 30px;">$ p4 sync ...@STABLE</pre>
<p>Then I can fetch fresh (from head) files I&#8217;m going to change:</p>
<pre style="padding-left: 30px;">$ p4 sync P1/...</pre>
<p>After adding fixes I&#8217;m committing the change:</p>
<pre style="padding-left: 30px;">$ p4 submit</pre>
<p>and moving stable label for files I&#8217;ve changed (I must check if full build is green before):</p>
<pre style="padding-left: 30px;">$ p4 tag -l STABLE P1/...</pre>
<p>In this case pending changes are visible by <strong>diff-ing STABLE..head revisions range.</strong></p>
<h2>Summary</h2>
<p>If some independent activities cannot be <strong>performed in paralell</strong> it&#8217;s a bad sign. It means some artificial dependencies were introduced and it results in slower progress for project (caused by serialisation).</p>
<p>In this case <strong>missing &#8220;W&#8221; access</strong> was the cause for additional burden. Unstable main branch was a global semaphore that blocked everyone (at least in integration terms).</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.aplikacja.info/2010/10/codebase-integration-scenarios/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to push local GIT branch to a remote repository</title>
		<link>http://blog.aplikacja.info/2010/09/how-to-push-local-git-branch-to-remote-repository/</link>
		<comments>http://blog.aplikacja.info/2010/09/how-to-push-local-git-branch-to-remote-repository/#comments</comments>
		<pubDate>Thu, 23 Sep 2010 08:56:18 +0000</pubDate>
		<dc:creator>dariusz.cieslak</dc:creator>
				<category><![CDATA[en]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[vcs]]></category>

		<guid isPermaLink="false">http://blog.aplikacja.info/?p=1288</guid>
		<description><![CDATA[GIT is a Distributed Version Control System (DVCS) that was &#8220;born&#8221; for Linux kernel development. It&#8217;s not the easiest to use for novices, but it fast and allows to create advanced code sharing scenarios.
Sometimes you want to share locally created GIT branch with other developers (code review, collaborative development on branch, etc). You can do [...]]]></description>
			<content:encoded><![CDATA[<p>GIT is a <strong>Distributed Version Control System</strong> (DVCS) that was &#8220;born&#8221; for Linux kernel development. It&#8217;s not the easiest to use for novices, but it fast and allows to create advanced code sharing scenarios.</p>
<p>Sometimes you want to <strong>share locally created GIT branch</strong> with other developers (code review, collaborative development on branch, etc). You can do it easily by issuing a command:</p>
<pre style="padding-left: 30px;">$ git push origin local_branch_name</pre>
<p>If you decide to drop remote branch just issue:</p>
<pre style="padding-left: 30px;">$ git push origin :local_branch_name
</pre>
<p>Happy GIT-ing!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.aplikacja.info/2010/09/how-to-push-local-git-branch-to-remote-repository/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Subtree checkout in Perforce</title>
		<link>http://blog.aplikacja.info/2010/09/subtree-checkout-in-perforce/</link>
		<comments>http://blog.aplikacja.info/2010/09/subtree-checkout-in-perforce/#comments</comments>
		<pubDate>Wed, 22 Sep 2010 20:30:07 +0000</pubDate>
		<dc:creator>dariusz.cieslak</dc:creator>
				<category><![CDATA[en]]></category>
		<category><![CDATA[vcs]]></category>

		<guid isPermaLink="false">http://blog.aplikacja.info/?p=1278</guid>
		<description><![CDATA[Perforce is a commercial, centralised VCS (Version Control System). I started using it to exchange data with customer&#8217;s codebase. Internal development is using GIT, snapshots are stored inside Perforce.
Checkout of full tree requires to download many gigabytes of data thus was not an option. I was interested only in small part of whole repository. Subtree [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.perforce.com/"><img style=' float: right; padding: 4px; margin: 0 0 2px 7px;'  class="alignright size-full wp-image-1281" title="perforce" src="http://blog.aplikacja.info/wp-content/uploads/2010/09/perforce.gif" alt="" width="200" height="46" />Perforce</a> is a commercial, centralised VCS (Version Control System). I started using it to exchange data with customer&#8217;s codebase. Internal development is using <a href="http://git-scm.com/">GIT</a>, snapshots are stored inside Perforce.</p>
<p>Checkout of full tree requires to download many gigabytes of data thus was not an option. I was interested only in small part of whole repository. <strong>Subtree checkout syntax</strong> is not very obvious (had to google for it):</p>
<pre style="padding-left: 30px;">p4 sync //path/to/directory/...</pre>
<p>I think, this hint may be useful to someone that must (want?)* use this VCS implementation.</p>
<p>(*) Who will pay <a href="http://www.perforce.com/perforce/price.html">700 USD per user</a> for Subversion replacement? Am I missing something valuable in P4 that is worth of this money? Commercial support <img src='http://blog.aplikacja.info/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> ?</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.aplikacja.info/2010/09/subtree-checkout-in-perforce/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Switch &#8220;origin&#8221; of your GIT repository</title>
		<link>http://blog.aplikacja.info/2010/08/switch-origin-of-your-git-repository/</link>
		<comments>http://blog.aplikacja.info/2010/08/switch-origin-of-your-git-repository/#comments</comments>
		<pubDate>Tue, 10 Aug 2010 20:16:30 +0000</pubDate>
		<dc:creator>dariusz.cieslak</dc:creator>
				<category><![CDATA[en]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[vcs]]></category>

		<guid isPermaLink="false">http://blog.aplikacja.info/?p=1253</guid>
		<description><![CDATA[GIT is a distributed version control system &#8211; that means it doesn&#8217;t require to have any central repository. It&#8217;s possible to build system by exchanging commits between equal nodes. It&#8217;s convenient, however, to mark one repository as central one. Of course you can change your decision at any time. I&#8217;ll show you how to do [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://git-scm.com/"></a><a href="http://blog.aplikacja.info/wp-content/uploads/2010/08/139.png"><img style=' float: right; padding: 4px; margin: 0 0 2px 7px;'  class="alignright size-full wp-image-1256" title="139" src="http://blog.aplikacja.info/wp-content/uploads/2010/08/139.png" alt="" width="300" height="236" /></a>GIT is a distributed version control system &#8211; that means it doesn&#8217;t require to have any central repository. It&#8217;s possible to build system by exchanging commits between equal nodes. It&#8217;s convenient, however, to <strong>mark one repository as central one</strong>. Of course you can change your decision at any time. I&#8217;ll show you how to do that.</p>
<p><span id="more-1253"></span></p>
<p>If you created your repo copy by &#8220;clone&#8221; operation you will have &#8220;origin&#8221; remote branch defined. This remote can be used to pull/push changes.</p>
<pre style="padding-left: 30px;">$ git remote -v
origin zeus.aplikacja.info:cust-proj1</pre>
<p>If you decide to change this definition later you can issue the following commands:</p>
<pre style="padding-left: 30px;">$ git remote rm origin
$ git remote add origin git@github.com:aplikacjainfo/proj1.git
$ git config master.remote origin
$ git config master.merge refs/heads/master
</pre>
<p>After this change you can <strong>push your commits</strong> to new repository location (origin is selected as default remote branch for master, it&#8217;s configured in .git/config):</p>
<pre style="padding-left: 30px;">$ git push</pre>
<p>That&#8217;s all. Much simpler than moving Subversion repository.</p>
<p>UPDATE 2011-12-09: replaced sed command with much simpler &#8220;git config&#8221; replacement.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.aplikacja.info/2010/08/switch-origin-of-your-git-repository/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Coloured GIT output</title>
		<link>http://blog.aplikacja.info/2010/06/coloured-git-output/</link>
		<comments>http://blog.aplikacja.info/2010/06/coloured-git-output/#comments</comments>
		<pubDate>Sun, 13 Jun 2010 06:33:00 +0000</pubDate>
		<dc:creator>dariusz.cieslak</dc:creator>
				<category><![CDATA[en]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[vcs]]></category>

		<guid isPermaLink="false">http://blog.aplikacja.info/?p=1206</guid>
		<description><![CDATA[Coloured git output on console is a very helpful feature. It was enabled by default on git interface cogito. I liked it, but had to switch to raw git few years ago (cogito is deprecated now).
Fortunately current version of GIT supports that nice feature. It can be enabled with few settings in ~/.gitconfig file:
[diff]
color = [...]]]></description>
			<content:encoded><![CDATA[<p>Coloured <a href="http://git-scm.com/">git</a> output on console is a very helpful feature. It was enabled by default on git interface <a href="http://git.or.cz/cogito/">cogito</a>. I liked it, but had to switch to raw git few years ago (cogito is deprecated now).</p>
<p>Fortunately current version of GIT supports that nice <a href="http://jblevins.org/log/git-colors">feature</a>. It can be enabled with few settings in ~/.gitconfig file:</p>
<pre style="padding-left: 30px;">[diff]
color = true

[pager]
color = true

[status]
color = true
</pre>
<p>Additionally pager used (less in my case) should support ANSI colors (~/.bash_profile):</p>
<pre style="padding-left: 30px;">export LESS="-R"</pre>
<p>And now diffs are rendered using colors that improve readability (anyone who doesn&#8217;t review changesets before commit? <img src='http://blog.aplikacja.info/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' />  ). Now diffs look much better on a X terminal:</p>
<p><a href="http://blog.aplikacja.info/wp-content/uploads/2010/06/132.png"><img style=' display: block; margin-right: auto; margin-left: auto;'  class="aligncenter size-full wp-image-1207" title="132" src="http://blog.aplikacja.info/wp-content/uploads/2010/06/132.png" alt="" width="400" height="315" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.aplikacja.info/2010/06/coloured-git-output/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Subversion: How To Revert Single Commit</title>
		<link>http://blog.aplikacja.info/2010/06/subversion-how-to-revert-single-commit/</link>
		<comments>http://blog.aplikacja.info/2010/06/subversion-how-to-revert-single-commit/#comments</comments>
		<pubDate>Wed, 09 Jun 2010 12:35:18 +0000</pubDate>
		<dc:creator>dariusz.cieslak</dc:creator>
				<category><![CDATA[en]]></category>
		<category><![CDATA[svn]]></category>
		<category><![CDATA[vcs]]></category>

		<guid isPermaLink="false">http://blog.aplikacja.info/?p=1187</guid>
		<description><![CDATA[Let&#8217;s say you tracked someone broke HEAD of trunk and you want to reverse that single commit from main branch. Subversion makes very handy syntax for reverse merges:
svn merge -c -19203 https://REPO_URL
In example above you do reverse merge of 19203 revision (note &#8220;-&#8221; sign before revision number). After that merge:

Inspect if workspace compiles without errors
If [...]]]></description>
			<content:encoded><![CDATA[<p>Let&#8217;s say you tracked someone broke HEAD of trunk and you want to <strong>reverse that single commit</strong> from main branch. Subversion makes very handy syntax for reverse merges:</p>
<pre style="padding-left: 30px;">svn merge -c -19203 https://REPO_URL</pre>
<p>In example above you do <strong>reverse merge</strong> of 19203 revision (note &#8220;-&#8221; sign before revision number). After that merge:</p>
<ul>
<li>Inspect if workspace compiles without errors</li>
<li>If it&#8217;s OK: commit local changeset</li>
<li>Notify 19203 committer about the change</li>
</ul>
<p><a href="http://blog.aplikacja.info/wp-content/uploads/2010/06/subversion.png"><img style=' display: block; margin-right: auto; margin-left: auto;'  class="aligncenter size-full wp-image-1191" title="subversion" src="http://blog.aplikacja.info/wp-content/uploads/2010/06/subversion.png" alt="" width="468" height="64" /></a></p>
<p>In order to <strong>fix broken commit</strong> original author should do the opposite:</p>
<pre style="padding-left: 30px;">svn merge -c 19203 https://REPO_URL
</pre>
<p>(note there&#8217;s no &#8220;-&#8221; before revision number). Then:</p>
<ul>
<li>Correct changeset and test if workspace is not broken</li>
<li>If it&#8217;s OK: commit local changeset (it will be nice to show original revision number in a comment)</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.aplikacja.info/2010/06/subversion-how-to-revert-single-commit/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Why svn:mime-type does matter?</title>
		<link>http://blog.aplikacja.info/2010/04/why-svnmime-type-does-matter/</link>
		<comments>http://blog.aplikacja.info/2010/04/why-svnmime-type-does-matter/#comments</comments>
		<pubDate>Fri, 23 Apr 2010 11:36:57 +0000</pubDate>
		<dc:creator>dariusz.cieslak</dc:creator>
				<category><![CDATA[en]]></category>
		<category><![CDATA[svn]]></category>
		<category><![CDATA[vcs]]></category>

		<guid isPermaLink="false">http://blog.aplikacja.info/?p=1007</guid>
		<description><![CDATA[You probably already know that Subversion stores some kind of metadata for all files added to repository. It&#8217;s called &#8220;properties&#8221; in Subversion vocabulary. This key-value map is responsible for registering ingored files masks, file attributes, internal file content type etc.
The property I&#8217;m going to present today is &#8220;mime-type&#8220;. It describes file content in similar way [...]]]></description>
			<content:encoded><![CDATA[<p>You probably already know that Subversion stores some kind of <strong>metadata</strong> for all files added to repository. It&#8217;s called &#8220;<a href="http://svnbook.red-bean.com/en/1.5/svn.ref.properties.html">properties</a>&#8221; in Subversion vocabulary. This key-value map is responsible for registering ingored files masks, file attributes, internal file content type etc.</p>
<p>The property I&#8217;m going to present today is &#8220;<strong>mime-type</strong>&#8220;. It describes file content in similar way to HTTP header &#8220;Content-type&#8221; telling svn client how to handle the file. Typical values are: &#8220;text/plain&#8221;, &#8220;application/octet-stream&#8221;. Especially first part of mime-type is important:</p>
<ul>
<li>text/*: line-by-line merges are used, diffs are generated</li>
<li>any other prefix: no text merges prepared</li>
</ul>
<p>If you do not <strong>set this properly right</strong> you may end up with messed binary file (end-of-line conversions) or non-mergable changes in text file (that is marked as binary by mistake).</p>
<p>Of course during adding a file to workspace <strong>one can forget to set those properties correctly</strong>. Here auto-props comes with help. Auto-props are applied when &#8220;svn add&#8221; command (from command line or from GUI) is issued. Configuration is placed inside &#8220;~/.subversion/config&#8221; file. Here&#8217;s my config fragment from one of projects.</p>
<pre style="padding-left: 30px;">[auto-props]
*.csv = svn:mime-type=text/plain
*.java = svn:mime-type=text/plain
*.sql = svn:mime-type=text/plain
*.sql = svn:keywords=Author Date Id Revision URL
*.jar = svn:mime-type=application/octet-stream</pre>
<p>Besides mime-type svn:keywords is being set in the example. It controls which keywords are expanded in source files.</p>
<p style="text-align: center;"><img style=' display: block; margin-right: auto; margin-left: auto;'  class="aligncenter" src="http://subversion.tigris.org/images/subversion_logo_hor-468x64.png" alt="" width="468" height="64" /></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.aplikacja.info/2010/04/why-svnmime-type-does-matter/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Do not reformat whole files on commit, PLEASE!</title>
		<link>http://blog.aplikacja.info/2010/02/do-not-reformat-whole-files-on-commit-please/</link>
		<comments>http://blog.aplikacja.info/2010/02/do-not-reformat-whole-files-on-commit-please/#comments</comments>
		<pubDate>Wed, 17 Feb 2010 22:22:32 +0000</pubDate>
		<dc:creator>dariusz.cieslak</dc:creator>
				<category><![CDATA[en]]></category>
		<category><![CDATA[svn]]></category>
		<category><![CDATA[vcs]]></category>

		<guid isPermaLink="false">http://blog.aplikacja.info/?p=865</guid>
		<description><![CDATA[What&#8217;s the purpose of internal project documentation? To help people do their jobs. Developers need the knowledge to be distributed across the team, testers need definition of proper system behaviour, marketing needs information on product features to sell it.
Questions
Important knowledge that may be required by developers doing updates may be summarized in few sentences:

Who changed [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://blog.aplikacja.info/wp-content/uploads/2010/02/paper.jpg"><img style=' float: right; padding: 4px; margin: 0 0 2px 7px;'  class="size-full wp-image-868 alignright" title="paper" src="http://blog.aplikacja.info/wp-content/uploads/2010/02/paper.jpg" alt="" width="300" height="224" /></a>What&#8217;s the <strong>purpose of internal project documentation</strong>? To help people do their jobs. Developers need the knowledge to be distributed across the team, testers need definition of proper system behaviour, marketing needs information on product features to sell it.</p>
<h2>Questions</h2>
<p>Important knowledge that may be <strong>required by developers</strong> doing updates may be summarized in few sentences:</p>
<ul>
<li><strong>Who</strong> changed recently that line of code?</li>
<li><strong>When</strong> this method have been changed?</li>
<li><strong>Why</strong> algorithm works that way?</li>
</ul>
<p>There&#8217;s simple method of <strong>automatically saving and retrieving</strong> this kind of information: Subversion (or any other version control system). How?</p>
<p><span id="more-865"></span></p>
<h2>Answers</h2>
<p>There&#8217;s nice feature of version control system that is not the most frequent used but is very useful: <strong>annotation/blame</strong>. This special view shows you for a file:</p>
<ul>
<li><strong>Who</strong> changed this line?</li>
<li><strong>When</strong> this line was changed?</li>
<li>Revision number of commit =&gt; Log entry =&gt; Bug tracker task ID =&gt; rationale (<strong>Why</strong>)</li>
</ul>
<p>After locating such information you may have better understanding of source code.</p>
<p>How to check annotation using different tools:</p>
<ul>
<li>svn annotate filename</li>
<li>git annotate filename</li>
<li>bzr annotate filename</li>
<li>Eclipse: Team / Show Annotation</li>
</ul>
<h2>The problem</h2>
<p>Looks simple, but there&#8217;s a &#8220;quirk&#8221; here. If you are doing massive code changes (to enforce n+1th coding standard) you are <strong>overwriting original source code authors and information</strong>. Thus annotation (and log) becomes useless.</p>
<p>That&#8217;s why I&#8217;m asking you:</p>
<p style="text-align: center;"><strong>Do not reformat whole files on commit, PLEASE!</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.aplikacja.info/2010/02/do-not-reformat-whole-files-on-commit-please/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Peer code reviews with Subversion</title>
		<link>http://blog.aplikacja.info/2010/02/peer-code-reviews-with-subversion/</link>
		<comments>http://blog.aplikacja.info/2010/02/peer-code-reviews-with-subversion/#comments</comments>
		<pubDate>Sat, 06 Feb 2010 22:33:06 +0000</pubDate>
		<dc:creator>dariusz.cieslak</dc:creator>
				<category><![CDATA[en]]></category>
		<category><![CDATA[agile]]></category>
		<category><![CDATA[svn]]></category>
		<category><![CDATA[vcs]]></category>

		<guid isPermaLink="false">http://blog.aplikacja.info/?p=741</guid>
		<description><![CDATA[Aplikacja.info believes in continuous integration and frequent reases, so uses so-called stable trunk policy. That means: at any time any developer can make installation from trunk to production systems. How stable trunk can be achieved?

any commit done to trunk is protected by set of     automated tests that should run 100% clean [...]]]></description>
			<content:encoded><![CDATA[<p><img style=' float: right; padding: 4px; margin: 0 0 2px 7px;'  class="alignright size-full wp-image-744" title="13" src="http://blog.aplikacja.info/wp-content/uploads/2010/02/13.png" alt="13" width="227" height="290" /><a href="http://aplikacja.info/">Aplikacja.info</a> believes in continuous integration and frequent reases, so uses so-called <strong>stable trunk</strong> policy. That means: at any time any developer can make installation from trunk to production systems. How stable trunk can be achieved?</p>
<ul>
<li>any commit done to trunk is protected by set of     <strong>automated tests</strong> that should run 100% clean     (more critical project will use     framework for a continuous build process     like <a href="http://aplikacja.info/en/view.php?page=Developer+Guide">Cruise Control</a> or <a href="http://bazaar-vcs.org/PatchQueueManager">PQM</a>).</li>
<li>&#8220;risky&#8221; tasks are done using     peer code review process based on version control software</li>
</ul>
<h2>What to review?</h2>
<p>We believe the most efficient method of reviewing code is to look at <strong>changesets</strong> (unified diffs). Then reviewer can see exact changes done by another developer to meet task criteria and codebase to review is minimized to really important parts of code (changes with some lines of context). That&#8217;s why we believe <a href="http://blog.aplikacja.info/2009/12/subversion-best-practices/">forming proper changesets</a> is very important requirement.</p>
<h2>Commit methods</h2>
<p>There are mainly three methods of inserting new commits into trunk (specified in our implementation by special <strong>&#8220;target&#8221; field in bug tracker</strong>):</p>
<p><span id="more-741"></span></p>
<ul>
<li><strong>Direct commit</strong> (target=master) without code review: used mainly for simplest functionality without much risk involved. Minimal administration burden, minimal merge conflict.</li>
<li><strong>Patch Based Review</strong> (target=patch) using <a href="http://pmsvcs.sourceforge.net/">PMS</a> functionality for one-way code review: in this scenario only one developer is supposed to modify patch, another one is only reviewing. At least two developers are involved, merge conflict minimized by basing on trunk (patch is always re-based on trunk during development).</li>
<li><strong>Shared branch</strong> (target=branch) using VCS: Development is branched on separate branch and reviewved on this branch. Many developers can commit on this branch/review before merge. There is higher merge conflict risk for long development on branch.</li>
</ul>
<p>A convention used by us: patch / branch name should contain noun from task summary and task id separated by a dash:</p>
<pre>noun-task_id</pre>
<p>for example: <em>invoice-2351</em>. This way we can easily find topic branches and <strong>precisely point to taks specification</strong> (by a task id).</p>
<h2>Peer Code Review</h2>
<p>Where&#8217;s peer code review here? Three modes of commit, three review configurations follows:</p>
<ul>
<li>Direct commit: changeset is <strong>reviewed after commit</strong> on trunk (as I said lower risk encourages us to be flexible)</li>
<li>Patch-based (read-only) changeset view: <strong>patch is sent</strong> to another team member for review by email or shared patches repository</li>
<li>Classical &#8220;topic branch&#8221;: read/write review: team member <strong>switches to topic branch</strong> and checks latest commits, he may also place comments in source code</li>
</ul>
<h2>Old, Good TODOs</h2>
<p>What is <strong>a result of code review</strong>? The most efficient way to track problems found is to insert comments inside source code (in comments, near problematic code location). We prepared a convention of well-known TODO tags in source code: <em>TODO:nick description</em>. &#8220;nick&#8221; is abbreviation of comment recipient, description should be short and valuable. Here&#8217;s the example:</p>
<pre>/*
TODO:DCI VAT report summary should show taxes grouped by rates,
not the case now
*/</pre>
<p>Recipient then <strong>scans all source code</strong> for such TODOs and fix problems found (thus removes TODO in the same commit). This way:</p>
<ul>
<li>we can <strong>connect</strong> problem report with problem fix in one changeset</li>
<li>we can <strong>track</strong> who entered comment and who fixed it (from SVN history)</li>
</ul>
<h2>Summary</h2>
<p>Code inspections were found to be very effective method of raising quality of software (<a href="http://domino.watson.ibm.com/tchjr/journalindex.nsf/0/0b0da213f326b51385256bfa00685d97?OpenDocument">the IBM story</a>). I believe informal implementation called <strong>peer review plays very well with other agile tools</strong> we are using for developing better software.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.aplikacja.info/2010/02/peer-code-reviews-with-subversion/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Is &#8220;commit freeze&#8221; really required for software development?</title>
		<link>http://blog.aplikacja.info/2010/02/is-commit-freeze-really-required-for-software-development/</link>
		<comments>http://blog.aplikacja.info/2010/02/is-commit-freeze-really-required-for-software-development/#comments</comments>
		<pubDate>Sat, 06 Feb 2010 14:12:46 +0000</pubDate>
		<dc:creator>dariusz.cieslak</dc:creator>
				<category><![CDATA[en]]></category>
		<category><![CDATA[agile]]></category>
		<category><![CDATA[svn]]></category>
		<category><![CDATA[vcs]]></category>

		<guid isPermaLink="false">http://blog.aplikacja.info/?p=714</guid>
		<description><![CDATA[During software development (especially done in agile way) there are often time when working software release must be prepared for customer evaluation of internal testing. I found many software release managers use a feature called &#8220;commit freeze&#8220;: no one can commit to main branch of development (trunk/master) until release is packaged. I doubt if it [...]]]></description>
			<content:encoded><![CDATA[<p><img style=' float: right; padding: 4px; margin: 0 0 2px 7px;'  class="alignright size-full wp-image-724" title="1162385_yellow_icicles" src="http://blog.aplikacja.info/wp-content/uploads/2010/02/1162385_yellow_icicles.jpg" alt="1162385_yellow_icicles" width="300" height="224" />During software development (especially done in agile way) there are often time when working software release must be prepared for customer evaluation of internal testing. I found many software release managers use a feature called &#8220;<strong>commit freeze</strong>&#8220;: no one can commit to main branch of development (trunk/master) until release is packaged. I doubt if it is really required.</p>
<p>The possible reason for freezing commits:</p>
<ul>
<li>creating <a href="http://www.mail-archive.com/hibernate-dev@lists.jboss.org/msg04037.html">releases from trunk</a></li>
<li>creating <a href="http://mail-archives.apache.org/mod_mbox/hadoop-hbase-dev/201001.mbox/%3C31a243e71001161015q2752404fme1d0aff7b08b1f8b@mail.gmail.com%3E">releases from branch</a></li>
<li>commit freeze <a href="http://marc.info/?l=phpdoc&amp;m=119722997021322&amp;w=2">during merge</a> from different branch</li>
<li>move to <a href="http://marc.info/?l=php-qa&amp;m=124695424521785&amp;w=2">different</a> version control system</li>
<li><a href="http://old.nabble.com/DocBook-5-upgrade---commit-freeze!-tc11205209.html">massive changes</a> expected that may cause many conflicts</li>
</ul>
<h2><span id="more-714"></span>Creating releases</h2>
<p>If you want to make minor changes related to release and block any other (probably more risky) changes to be accidentially introduced you needn&#8217;t freeze commits. The more efficient solution here is to <strong>fork a branch</strong>. On separate branch you can do any justification you need to build the binaries for release.</p>
<h2>Merging</h2>
<p>For time-consuming merges (especially when many conflicts are present) it&#8217;s tempting to prevent commits on target branch to minimize problems related to local development during merged changes commit. I think merging person should perform <strong>frequent updates insted</strong> from current branch and match merged changes to current trunk state.</p>
<h2>Switch version control software / repositories</h2>
<p>Switching between version control system is a big change in development team. One has to learn new toolset to operate efficiently with new version control system. Postponing commits on old repository is not required. Those changes <strong>could be reapplied later by creating patch</strong> from missing changesets and applying them on new repository. <a href="http://en.wikipedia.org/wiki/Diff">Path format</a> is a standard that allow to move changesets beteen different repositories.</p>
<h2>Summary</h2>
<p>In my opinion temporary blocking commits (so called &#8220;commit freeze&#8221;) is <strong>not a good idea</strong>. Agile methodology (the one we use at Aplikacja.info) requires frequent information sharing. There are alternatives that have lower impact on development and not get in the way for normal code flow.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.aplikacja.info/2010/02/is-commit-freeze-really-required-for-software-development/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>How to correct comment after commit in Subversion</title>
		<link>http://blog.aplikacja.info/2009/12/how-to-correct-comment-after-commit-in-subversion/</link>
		<comments>http://blog.aplikacja.info/2009/12/how-to-correct-comment-after-commit-in-subversion/#comments</comments>
		<pubDate>Wed, 23 Dec 2009 14:09:05 +0000</pubDate>
		<dc:creator>dariusz.cieslak</dc:creator>
				<category><![CDATA[en]]></category>
		<category><![CDATA[svn]]></category>
		<category><![CDATA[vcs]]></category>

		<guid isPermaLink="false">http://blog.aplikacja.info/?p=582</guid>
		<description><![CDATA[Correcting comments of existing commits is easy if you have enough privileges on subversion repository:
svn propedit -r &#60;revision-number-here&#62; --revprop svn:log "&#60;new log message&#62;" &#60;url&#62;
That&#8217;s all. Pretty simple.
http://subversion.tigris.org/faq.html#change-log-msg
]]></description>
			<content:encoded><![CDATA[<p><a href="http://subversion.tigris.org/faq.html#change-log-msg">Correcting comments of existing commits</a> is easy if you have enough privileges on subversion repository:</p>
<pre style="padding-left: 30px;">svn propedit -r &lt;revision-number-here&gt; --revprop svn:log "&lt;new log message&gt;" &lt;url&gt;</pre>
<p>That&#8217;s all. Pretty simple.</p>
<div id="_mcePaste" style="overflow: hidden; position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px;">http://subversion.tigris.org/faq.html#change-log-msg</div>
]]></content:encoded>
			<wfw:commentRss>http://blog.aplikacja.info/2009/12/how-to-correct-comment-after-commit-in-subversion/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Subversion Best Practices</title>
		<link>http://blog.aplikacja.info/2009/12/subversion-best-practices/</link>
		<comments>http://blog.aplikacja.info/2009/12/subversion-best-practices/#comments</comments>
		<pubDate>Fri, 11 Dec 2009 21:15:55 +0000</pubDate>
		<dc:creator>dariusz.cieslak</dc:creator>
				<category><![CDATA[en]]></category>
		<category><![CDATA[svn]]></category>
		<category><![CDATA[vcs]]></category>

		<guid isPermaLink="false">http://blog.aplikacja.info/?p=539</guid>
		<description><![CDATA[I&#8217;ve been using many version control systems in software development projects. I&#8217;m aware Subversion is not the best version control system out there, but it&#8217;s most popular (at least among enterprise projects I&#8217;ve been working on).
I&#8217;m describing here Subversion usage best practices that come from my experience with Subversion (or other version control systems) collected [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been using many version control systems in software development projects. I&#8217;m aware Subversion is not the best version control system out there, but it&#8217;s <strong>most popular</strong> (at least among enterprise projects I&#8217;ve been working on).</p>
<p>I&#8217;m describing here <strong>Subversion usage best practices</strong> that come from my experience with Subversion (or other version control systems) collected on many projects. Some suggestions are related strictly to Subversion, some are general.</p>
<h2><span id="more-539"></span>Commit complete, logical changesets</h2>
<p>Always commit <strong>complete</strong> patch. &#8220;Complete&#8221; means the commit:</p>
<ul>
<li>shouldn&#8217;t have <strong>compilation errors</strong></li>
<li>shouldn&#8217;t lower successful <strong>test cases</strong> counter</li>
<li>should have precise <strong>purpose</strong> (one fixed bug, implemented feature, as so on&#8230;)</li>
</ul>
<p>Why complete changesets are <strong>so important</strong>? You can easily then:</p>
<ul>
<li><strong>reapply</strong> only selected bugfixes on another branch (sometimes it&#8217;s called cherry-picking)</li>
<li><strong>undo change</strong> that made system unstable by simple reverted merge</li>
</ul>
<p>Sometimes you have <strong>many different changes</strong> (example: two bugfixes, one feature added) in your workspace and it seems the easiest way is to commit them in one big commit. DON&#8217;T. You can use &#8220;svn diff&#8221;, &#8220;patch&#8221; commands to split your local changeset into few parts and commit them separately. How? It&#8217;s simple (but not obvious at first glance):</p>
<ol>
<li>svn diff &gt; ../changeset.diff</li>
<li>$EDITOR ../changeset.diff</li>
<li>Leave only <strong>changes to be removed</strong> from working copy, delete remaining changes</li>
<li>patch -p0 -R &lt;  ../changeset.diff</li>
<li>Now you have yor workspace without changes to be removed, retest, commit</li>
<li>patch -p0 &lt;  ../changeset.diff</li>
<li>Now you have only <strong>changed that previously were skipped</strong>, retest, commit</li>
</ol>
<p>Special tool have been implemented that can automate above flow: <a href="http://code.google.com/p/pmsvcs/">PMS</a> (Patch Management System).</p>
<h2>Do not commit workspace partially</h2>
<p>If you commit only subset of files from your working copy you <strong>risk breaking the build</strong>. The proper way for splitting working copy into separate commits is to reverse patch your changeset (see previous practice examples).</p>
<p>Similar problem appears when you <strong>forget to add to versioned files</strong> new file (and it appears as &#8220;?&#8221; on &#8220;svn status&#8221; listing). Use &#8220;svn status&#8221; frequently and properly set svn:ignored where necessary.</p>
<h2>Continuous integration simplified: commit often, update very often</h2>
<p>If you postpone your changes more that two days it&#8217;s very likely someone will use obsolete API that you&#8217;re refactoring and someone will get compilation errors. Try to make <strong>atomic but small commit</strong> to minimize such risk.</p>
<p>When you develop a feature it&#8217;s very likely you will use obsolete API that some other developer is refactoring now. <strong>Update very often</strong> to see fresh system state.</p>
<p>Have you noticed above paragraphs are very similar? You have to <strong>make fast information flow</strong>. Making long-living branches will postpone new code from being integrated. Frequent merges and commits are implementation of continuous integration. Every integration problem (as API change mentioned in this section) will be visible as soon as possible (when it is stable enough to be committed).</p>
<p>Someone can point out that frequent commits can destroy trunk stability &#8211; see next section for answer.</p>
<h2>Shared branches must be stable, Really</h2>
<p>When you are working on isolated topic branch you don&#8217;t need to ensure it&#8217;s stable enough to be committed. It&#8217;s not needed to compiler, either. But if anyone will have access with you to this branch/trunk you must ensure it will remain stable. <strong>Stable branch encourage frequent updates</strong> and it&#8217;s base to Continuous integration.</p>
<p>How can we define <strong>&#8220;stable&#8221; criteria</strong> for local changeset to be committed:</p>
<ul>
<li>Code compiles with <strong>no errors</strong></li>
<li>No additional failing tests (<strong>no regression</strong>!)</li>
<li>Ensure <strong>no accidental whole-file reformatting</strong> by viewing diffs (svn di)</li>
<li>Ensure <strong>no forgotten unversioned files</strong> (svn status = ?) in your repository (it may break compilation for someone else)</li>
</ul>
<h2>Use meaningful commit comments</h2>
<p>A typical error (yes, error) made by novice programmers is <strong>empty or &#8220;asdf&#8221;-style commit comments</strong>. The information what was committed is hidden in commit changeset only. It will make code inspection harder. I suggest to enter at least in commit comment:</p>
<ul>
<li>Issue tracker ID if preset (to link commit to issue fixed)</li>
<li>short one-line description (can be copied from issue tracker)</li>
</ul>
<p>Then anyone can look at fresh commits:</p>
<p style="padding-left: 30px;">svn log -l 10</p>
<p>and see what&#8217;s going on now in the project.</p>
<h2>Care about merge and annotate &#8211; DO NOT reformat whole file</h2>
<p>Sometimes when I want to trace who are responsible for particular change in file I&#8217;m discovering by <strong>annotate</strong> that whole file have been changed recently by one person. Why? This programmer reformatted whole file and committed big changeset. Now file looks better but at what price? Original committer information is <strong>lost</strong>.</p>
<p>Similar problem occurs when you <strong>merge such changeset</strong> (from topic branch to trunk for instance). There are many conflicts because merge changeset overlap with changesets committed previously on trunk.</p>
<p>Subversion like many other popular version control systems <span style="text-decoration: line-through;"><strong>loses commit information</strong> on merge </span>(merged person is visible instead of original authors of merged changesets). If you expect to preserve such information <a href="http://git-scm.com/">use GIT</a>. (Thanks Michal to pointing this out: Subversion &gt;= 1.5 <a href="http://subversion.tigris.org/merge-tracking/requirements.html">tracks merges</a>).</p>
<h2>Setup auto properties correctly</h2>
<p>In mixed systems environment there are many formats of storing files. EOL (end of line) standards differs between operating systems. Subversion allows to convert-on-fly EOL style. In order to make use of such feature you have to set &#8220;<a href="http://svnbook.red-bean.com/en/1.2/svn.advanced.props.html#svn.advanced.props.special.mime-type">svn:mime-type: text/plain</a>&#8220;.</p>
<p>Setting such properties on every added files can be boring, so <a href="http://http://svnbook.red-bean.com/en/1.2/svn.advanced.props.html#svn.advanced.props.auto">auto properties</a> have been introduced in Subversion. You can map (locally) properties to extensions in your ~/.subversion/config:</p>
<pre>[auto-props]
*.csv = svn:mime-type=text/plain
*.java = svn:mime-type=text/plain
*.sql = svn:mime-type=text/plain</pre>
<h2>Setup svn:ignore in repository</h2>
<p>Some files are required to live in project directory but <strong>shouldn&#8217;t be committed</strong> into SVN (*.class, *.ear, &#8230;). General &#8220;ignore&#8221; mechanism marks such files (or file masks) to be invisible for SVN (not reported as unknown files &#8220;?&#8221;). Typically CVS used .cvsignore file, Bazaar reads .bzrignore, SVN reads svn:ignore property AND local user preferences stored in ~/.subversion/config.</p>
<p>Do not depend on local developer ignore settings in ~/.subversion/config. Attach <strong>svn:ignore tag to proper directories</strong> to be present on every working copy. It will make to add new filters easier (by commiting new properties once to Subversion).</p>
<div id="_mcePaste" style="overflow: hidden; position: absolute; left: -10000px; top: 305px; width: 1px; height: 1px;">
<h2>merge</h2>
</div>
]]></content:encoded>
			<wfw:commentRss>http://blog.aplikacja.info/2009/12/subversion-best-practices/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>svn: Malformed URL for repository</title>
		<link>http://blog.aplikacja.info/2009/12/svn-malformed-url-for-repository/</link>
		<comments>http://blog.aplikacja.info/2009/12/svn-malformed-url-for-repository/#comments</comments>
		<pubDate>Thu, 10 Dec 2009 10:01:48 +0000</pubDate>
		<dc:creator>dariusz.cieslak</dc:creator>
				<category><![CDATA[en]]></category>
		<category><![CDATA[svn]]></category>
		<category><![CDATA[vcs]]></category>

		<guid isPermaLink="false">http://blog.aplikacja.info/?p=536</guid>
		<description><![CDATA[During a merge from branch on the same repository as current copy:
svn merge -r17007:17249 http://hostname/svn/path
I got the error: svn: Malformed URL for repository. The fix is to add user name in SVN URL:
svn merge -r17007:17249 http://dcieslak@hostname/svn/path
Is this a Subversion bug? Probably the problem is that my username placed in SVN config file has form: domainname\username. [...]]]></description>
			<content:encoded><![CDATA[<p>During a <strong>merge from branch</strong> on the same repository as current copy:</p>
<pre style="padding-left: 30px;">svn merge -r17007:17249 http://hostname/svn/path</pre>
<p>I got the error: <strong>svn: Malformed URL for repository</strong>. The <a href="http://groups.google.com/group/visualsvn/browse_thread/thread/81d604209e1b3ea5">fix</a> is to add user name in SVN URL:</p>
<pre style="padding-left: 30px;">svn merge -r17007:17249 http://dcieslak@hostname/svn/path</pre>
<p>Is this a <strong>Subversion bug</strong>? Probably the problem is that my username placed in SVN config file has form: domainname\username. Maybe SVN merge cannot handle that format?</p>
<p><img style=' display: block; margin-right: auto; margin-left: auto;'  class="aligncenter" src="http://subversion.tigris.org/images/subversion_logo_hor-468x64.png" alt="" width="468" height="64" /></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.aplikacja.info/2009/12/svn-malformed-url-for-repository/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>GIT rationale by Linus Torvalds</title>
		<link>http://blog.aplikacja.info/2009/10/git-rationale-by-linus-torvalds/</link>
		<comments>http://blog.aplikacja.info/2009/10/git-rationale-by-linus-torvalds/#comments</comments>
		<pubDate>Wed, 07 Oct 2009 19:42:14 +0000</pubDate>
		<dc:creator>dariusz.cieslak</dc:creator>
				<category><![CDATA[en]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[vcs]]></category>

		<guid isPermaLink="false">http://blog.aplikacja.info/?p=409</guid>
		<description><![CDATA[GIT is a very poverful Source Control Management System we are using for managing most our projects. Let&#8217;s give a voice GIT&#8217;s creator, Linux Torvalds:



]]></description>
			<content:encoded><![CDATA[<p><strong>GIT</strong> is a very poverful Source Control Management System we are using for managing most our projects. Let&#8217;s give a voice GIT&#8217;s creator, Linux Torvalds:<br />
<center><br />
<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="425" height="349" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowFullScreen" value="true" /><param name="src" value="http://www.youtube.com/v/4XpnKHJAok8&amp;hl=pl&amp;fs=1&amp;rel=0&amp;color1=0x2b405b&amp;color2=0x6b8ab6&amp;border=1" /><param name="allowfullscreen" value="true" /><embed type="application/x-shockwave-flash" width="425" height="349" src="http://www.youtube.com/v/4XpnKHJAok8&amp;hl=pl&amp;fs=1&amp;rel=0&amp;color1=0x2b405b&amp;color2=0x6b8ab6&amp;border=1" allowfullscreen="true"></embed></object><br />
</center></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.aplikacja.info/2009/10/git-rationale-by-linus-torvalds/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Git Version Control System usage techniques</title>
		<link>http://blog.aplikacja.info/2008/10/git-version-control-system-usage-techniques/</link>
		<comments>http://blog.aplikacja.info/2008/10/git-version-control-system-usage-techniques/#comments</comments>
		<pubDate>Sat, 04 Oct 2008 07:15:49 +0000</pubDate>
		<dc:creator>dariusz.cieslak</dc:creator>
				<category><![CDATA[en]]></category>
		<category><![CDATA[vcs]]></category>

		<guid isPermaLink="false">http://cieslakd.wordpress.com/?p=5</guid>
		<description><![CDATA[
We (Aplikacja.info) are a small Polish software company that write mostly in Python language and use Linux for development. GIT is an advanced version control system that was created by Linux Torvalds for maintain Linux kernel source tree. I&#8217;ll show how git can be connected in Unix shell environment with make tool.
Why GIT have been [...]]]></description>
			<content:encoded><![CDATA[<div>
<p>We (<a href="http://aplikacja.info/" target="_self">Aplikacja.info</a>) are a small Polish software company that write mostly in Python language and use Linux for development.<strong> GIT</strong> is an advanced version control system that was created by Linux Torvalds for maintain Linux kernel source tree. I&#8217;ll show how git can be connected in Unix shell environment with <strong>make</strong> tool.</p>
<p><strong>Why</strong> GIT have been chosen to support our version control needs?</p>
<ul>
<li>Failure in development server will not block our work</li>
<li>Access to history is very fast (it&#8217;s stored on every working copy)</li>
<li>I used to work during flight, GIT supports all VCS operations off-line (commit, diff, etc.)</li>
</ul>
<p>The hard thing about GIT is that it may <a href="http://blogs.gnome.org/newren/2007/12/08/limbo-why-users-are-more-error-prone-with-git-than-other-vcses/">confuse beginners</a>. If you are one, remember:</p>
<ul>
<li>Always use <strong>git diff HEAD</strong> instead of <em>git diff</em></li>
<li>Always using <strong>git commit -a</strong> instead of <em>git commit</em></li>
</ul>
<p>Some of this gotchas have been addressed by some GIT <a href="http://git.or.cz/cogito/">interfaces</a>, but they are deprecated now.</p>
<p>In order to ease GIT (and earlier, CVS) usage we introduced additional <strong>Makefile</strong> targets that handle typical source control tasks.</p>
<p><span id="more-97"></span></p>
<h2><strong>Examining working copy.</strong></h2>
<p><strong>make st</strong> shows current working copy state with all local branches and current selected branch:</p>
<pre>    st:
        git branch
        git status -a | cat</pre>
<p>(cat simply remove pager call). <strong>make di</strong> shows differences between last committed version and working copy:</p>
<pre>    di:
        git diff HEAD</pre>
<p>Locally stored history (few last commits) can be inspected by <strong>make ch</strong>:</p>
<pre>    ch:
        git log --pretty=oneline -15 | cat</pre>
<p>We are using topic branches strategy to develop software, so switching branch (<strong>make sb</strong>) is a very common operation:</p>
<pre>    sb:
        @read -p "name of existing branch to switch to [a-z_0-9]+: "\
            branch_name;\
        git checkout $$branch_name;</pre>
<h2>Local commits</h2>
<p>If we have some changes uncommitted in working copy we can commit them now:</p>
<pre>    commit: di st
        git commit -a</pre>
<p>Above command shows current changes to be committed (di) and state of a repository (st) then allows to enter comment.</p>
<h2>Going remote</h2>
<p>Lets synchronise our working copy with central repo (without locally unmodified changes): <strong>make sync</strong>:</p>
<pre>    sync:
        -git pull $(REPO) +`git branch | awk '/^\*/ {print $$2}'`
        git push $(REPO) `git branch | awk '/^\*/ {print $$2}'`</pre>
<p>It downloads current branch from central server (this operation can fail when no branch exists yet, so we ignore errors here by &#8220;-&#8221; character) and pushes un-synced commits made.</p></div>
]]></content:encoded>
			<wfw:commentRss>http://blog.aplikacja.info/2008/10/git-version-control-system-usage-techniques/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

