<?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>Cocoa Is My Girlfriend &#187; Development Environment</title>
	<atom:link href="http://www.cimgf.com/category/development-environment/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.cimgf.com</link>
	<description>Taglines are for Windows programmers</description>
	<lastBuildDate>Thu, 15 Jul 2010 21:20:40 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>My current Prefix.pch file</title>
		<link>http://www.cimgf.com/2010/05/02/my-current-prefix-pch-file/</link>
		<comments>http://www.cimgf.com/2010/05/02/my-current-prefix-pch-file/#comments</comments>
		<pubDate>Mon, 03 May 2010 00:58:32 +0000</pubDate>
		<dc:creator>Marcus Zarra</dc:creator>
				<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Cocoa Touch]]></category>
		<category><![CDATA[Coding Practice]]></category>
		<category><![CDATA[Development Environment]]></category>
		<category><![CDATA[Objective-C]]></category>
		<category><![CDATA[``]]></category>

		<guid isPermaLink="false">http://www.cimgf.com/?p=977</guid>
		<description><![CDATA[I have posted and discussed this file a few times but as with all things it has been touched, tweaked, and generally improved upon. In this article we will discuss the latest iteration of my Prefix.pch file. As with anything I post, it is available for you to use as you see fit. The File [...]]]></description>
			<content:encoded><![CDATA[<p>I have posted and discussed this file a few times but as with all things it has been touched, tweaked, and generally improved upon.</p>

<p>In this article we will discuss the latest iteration of my <code>Prefix.pch</code> file.  As with anything I post, it is available for you to use as you see fit.</p>

<h2>The File</h2>

<p>For those who don&#8217;t want to read the entire post, here is the file:</p>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
</pre></td><td class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #6e371a;">#ifdef DEBUG</span>
  <span style="color: #6e371a;">#define DLog(...) NSLog(@&quot;%s %@&quot;, __PRETTY_FUNCTION__, [NSString stringWithFormat:__VA_ARGS__])</span>
  <span style="color: #6e371a;">#define ALog(...) [[NSAssertionHandler currentHandler] handleFailureInFunction:[NSString stringWithCString:__PRETTY_FUNCTION__ encoding:NSUTF8StringEncoding] file:[NSString stringWithCString:__FILE__ encoding:NSUTF8StringEncoding] lineNumber:__LINE__ description:__VA_ARGS__]</span>
<span style="color: #6e371a;">#else</span>
  <span style="color: #6e371a;">#define DLog(...) do { } while (0)</span>
  <span style="color: #6e371a;">#ifndef NS_BLOCK_ASSERTIONS</span>
    <span style="color: #6e371a;">#define NS_BLOCK_ASSERTIONS</span>
  <span style="color: #6e371a;">#endif</span>
  <span style="color: #6e371a;">#define ALog(...) NSLog(@&quot;%s %@&quot;, __PRETTY_FUNCTION__, [NSString stringWithFormat:__VA_ARGS__])</span>
<span style="color: #6e371a;">#endif</span>
&nbsp;
<span style="color: #6e371a;">#define ZAssert(condition, ...) do { if (!(condition)) { ALog(__VA_ARGS__); }} while(0)</span></pre></td></tr></table></div>


<p>This does not <em>replace</em> the Prefix.pch that comes with your project but it does go at the top of every project that I work on.  The rest of this post we will review what this does.
<span id="more-977"></span></p>

<h2><code>#ifdef DEBUG</code></h2>

<p>I normally run my code in one of two modes.  Either I am writing and testing the code or I am compiling it to hand over to QA, a user or Apple (btw I consider all three of those to be synonymous when it comes to builds).  Therefore the first line is a switch to see if we are in debug mode.  I set this value in the build settings of my project.  If you look under the &#8220;Preprocessor Macros&#8221; section you can set the <code>DEBUG</code> definition there.</p>

<h2><code>#define DLog(...)</code></h2>

<p>This is the most used macro I have in my <code>Prefix.pch</code> file.  This is simply <code>NSLog</code> as we know it and love it.  However I automatically prepend the included macro <code>__PRETTY_FUNCTION__</code> so that any log statement that comes out will declare where it is being called from.  Personally I hate having to track down which &#8220;Fix Me&#8221; just spit out to the Console.</p>

<p>The nice thing about <code>DLog</code> over <code>NSLog</code> is that in the other branch this is a no-op that will be removed by the compiler.  Therefore when I do a client build they won&#8217;t see the debug statements nor will their build be slowed down by any potential conditional logic around the debug statements.</p>

<h2><code>#define ALog(...)</code></h2>

<p>While I do not use this one very often I do like this one an awful lot.  When I am in <code>DEBUG</code> mode it will throw an <code>NSAssertion</code> when it gets hit. This is similar to a common line of code that I see:</p>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="objc" style="font-family:monospace;">NSAssert<span style="color: #002200;">&#40;</span><span style="color: #a61390;">NO</span>, <span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;It failed&quot;</span><span style="color: #002200;">&#41;</span>;</pre></td></tr></table></div>


<p>or if you want to see the variables:</p>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="objc" style="font-family:monospace;">NSAssert2<span style="color: #002200;">&#40;</span><span style="color: #a61390;">NO</span>, <span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;It failed. Value1: %i Value2: %i&quot;</span>, value1, value2<span style="color: #002200;">&#41;</span>;</pre></td></tr></table></div>


<p>My version does not have the condition before hand and can take any number of parameters.</p>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="objc" style="font-family:monospace;">ALog<span style="color: #002200;">&#40;</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;It failed. Value1: %i Value2: %i&quot;</span>, value1, value2<span style="color: #002200;">&#41;</span>;</pre></td></tr></table></div>


<p>In addition, when the <code>DEBUG</code> flag is not set, this assertion turns into a <code>NSLog</code> which remains visible.  This allows me to have &#8220;This will never happen&#8221; calls in my code that will explode when I hit them but will be more polite if a user hits them but not so polite that I am left wondering what happened.  They won&#8217;t intentionally crash the application but they will leave a fingerprint in the output from the application so that I can discover what happened.</p>

<h2><code>NS_BLOCK_ASSERTIONS</code></h2>

<p>I am of the school of thought that believes you should never throw an assertion in production code.  If your code cannot handle that part of your app being hit and survive in some form or another then it is not production ready.  Simple as that.  Therefore I turn them off in production builds.</p>

<p>However, some other people who write libraries that I depend upon also feel this way.  Therefore I need to check to see if it is already defined so that I can avoid a warning about resetting it.  Since I have warnings set as errors in my code this is needed.</p>

<h2><code>#define ZAssert(condition, ...)</code></h2>

<p>The final gem in this collection is <code>ZAssert</code>.  This is my personal favorite and it lets me clean up my code very nicely.  First, <code>ZAssert</code> is a condition check.  If you pass the check nothing happens.  If you fail the check, bad things happen.  This is just like <code>NSAssert</code> except for one big difference.  When you turn off assertions, <code>NSAssert</code> goes away completely.  This is not what I want to happen in my code.  Instead, when assertions are turned off, I want a failure of this check to turn into an <code>NSLog</code>.  That is what <code>ZAssert</code> does for us.  In this way, we can clean up our code very nicely.  Picture this very common block of code:</p>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
</pre></td><td class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #400080;">NSError</span> <span style="color: #002200;">*</span>error <span style="color: #002200;">=</span> <span style="color: #a61390;">nil</span>;
&nbsp;
<span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span><span style="color: #002200;">!</span><span style="color: #002200;">&#91;</span>managedObjectContext save<span style="color: #002200;">:&amp;</span>error<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
  NSLog<span style="color: #002200;">&#40;</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;My save failed: %@<span style="color: #2400d9;">\n</span>%@&quot;</span>, <span style="color: #002200;">&#91;</span>error localizedDescription<span style="color: #002200;">&#93;</span>, <span style="color: #002200;">&#91;</span>error userInfo<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#41;</span>;
  <span style="color: #a61390;">abort</span><span style="color: #002200;">&#40;</span><span style="color: #002200;">&#41;</span>;
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>


<p>That is a LOT of code just to perform a save!  Blocks of code like this are very common in Objective-C.  Unfortunately we can&#8217;t roll this up into a <code>NSAssert</code> because the entire line of code will disappear when we turn them off.</p>

<p>With <code>ZAssert</code> it gets a lot cleaner:</p>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
</pre></td><td class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #400080;">NSError</span> <span style="color: #002200;">*</span>error <span style="color: #002200;">=</span> <span style="color: #a61390;">nil</span>;
ZAssert<span style="color: #002200;">&#40;</span><span style="color: #002200;">!</span><span style="color: #002200;">&#91;</span>managedObjectContext save<span style="color: #002200;">:&amp;</span>error<span style="color: #002200;">&#93;</span>, <span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;My save failed: %@<span style="color: #2400d9;">\n</span>%@&quot;</span>, <span style="color: #002200;">&#91;</span>error localizedDescription<span style="color: #002200;">&#93;</span>, <span style="color: #002200;">&#91;</span>error userInfo<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#41;</span>;</pre></td></tr></table></div>


<p>Because ZAssert survives when <code>NS_BLOCK_ASSERTIONS</code> is set and simply mutates, we can inline the save directly and make the code a lot easier to read.</p>

<h1>Wrap Up</h1>

<p>I am sure this code will evolve.  When it has changed significantly I will do an updated post.  If anyone else has some nice tips for the <code>Prefix.pch</code> then please share them as we all benefit.</p>

<h1>Acknowledgements</h1>

<p>First I would like to recognize Fraser Hess who did the original post and showed me what we can do with macros.</p>

<p>Second I would like to point out that the NSAssert line of code above is borrowed heavily from BareBones software. They figured out how to generate an assertion without actually using the <code>NSAssert</code> macros.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cimgf.com/2010/05/02/my-current-prefix-pch-file/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Automatically save the dSYM files.</title>
		<link>http://www.cimgf.com/2009/12/23/automatically-save-the-dsym-files/</link>
		<comments>http://www.cimgf.com/2009/12/23/automatically-save-the-dsym-files/#comments</comments>
		<pubDate>Thu, 24 Dec 2009 02:28:50 +0000</pubDate>
		<dc:creator>Marcus Zarra</dc:creator>
				<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Cocoa Touch]]></category>
		<category><![CDATA[Development Environment]]></category>
		<category><![CDATA[Git]]></category>
		<category><![CDATA[Objective-C]]></category>
		<category><![CDATA[Version Control]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[iPod Touch]]></category>

		<guid isPermaLink="false">http://www.cimgf.com/?p=843</guid>
		<description><![CDATA[For those not aware, when you compile an Objective-C application, whether it be for the desktop or for Cocoa Touch devices, the debugging symbols are stripped out of the binaries. Therefore, unlike other languages such as Java, when a crash occurs, there is virtually no way to determine where the crash occurred. However, when the [...]]]></description>
			<content:encoded><![CDATA[<p>For those not aware, when you compile an Objective-C application, whether it be for the desktop or for Cocoa Touch devices, the debugging symbols are stripped out of the binaries.  Therefore, unlike other languages such as Java, when a crash occurs, there is virtually no way to determine where the crash occurred.  However, when the applications are compiled, a dSYM bundle is generated.  This bundle allows us to match up the debugging symbols with the application&#8217;s crash log to help determine the cause of the crash.</p>

<p><span id="more-843"></span></p>

<p>The issue, however, is that the dSYM file must match the binary exactly<sup>[<a name="id394062" href="#ftn.id394062">1</a>]</sup>.  <del>I have not even had luck with pulling the code out of version control and compiling a second time to get the files to match up.</del>  Therefore, we need to store these dSYM files for every build that gets handed off to someone else.  For Cocoa Touch development this means every ad hoc build and every release build.  This can be a pain.  </p>

<p>To solve this problem I wrote a script that is added as the last build phase of all my iPhone projects.  The script will move the dSYM bundle into the project directory in a directory cleverly called &#8220;dSYM&#8221;.  In addition the script will check the bundle into git (after confirming the project is maintained in a git repository) and commit just that bundle.  Also, since the file is always named the same thing, it renames the file using the current date and time so that no two bundles have the same file name.</p>

<h2 id="failure_checks">Failure checks</h2>

<p>The first thing the script does is determine if it should run.</p>

<p><pre><code>if [ "$BUILD_STYLE" == "Debug" ]; then
  echo "Skipping debug"
  exit 0;
fi
</code></pre></p>

<p>The first part of the script checks to see if the build style is Debug.  Since all debug builds run just on the developer&#8217;s device and still contain the debug symbols, they can be safely ignored.</p>

<p><pre><code>if [ "$EFFECTIVE_PLATFORM_NAME" == "-iphonesimulator" ]; then
  echo "Skipping simulator build"
  exit 0;
fi
</code></pre></p>

<p>The second step is to check to see if the build is against the simulator.  Again, we have no interest in storing the symbol files for these builds.</p>

<h2 id="move_the_file">Move the file</h2>

<p>Since the location of the file is determined at build time and can vary from developer to developer (as well as machine to machine) I use the environmental variables that are part of the build.</p>

<p><pre><code>SRC_PATH=${DWARF_DSYM_FOLDER_PATH}/${DWARF_DSYM_FILE_NAME}
RELATIVE_DEST_PATH=dSYM/${EXECUTABLE_NAME}.$(date +%Y%m%d%H%M%S).app.dSYM
DEST_PATH=${PROJECT_DIR}/${RELATIVE_DEST_PATH}
echo "moving ${SRC_PATH} to ${DEST_PATH}"</p>

<p>mv "${SRC_PATH}" "${DEST_PATH}"
</code></pre></p>

<p>The next step is to build up the paths of where the file is currently and where we are going to move it to.  I like to store these in variables so that I can print them out to the console in case something goes wrong.  </p>

<h2 id="commit_it_to_version_control">Commit it to version control</h2>

<p>Every project is part of version control right? (<em>RIGHT</em>?)</p>

<p><pre><code>if [ -f ".git/config" ]; then
  git add "${RELATIVE_DEST_PATH}"
  git commit -m "Added dSYM file for ${BUILD_STYLE} build" \
      "${RELATIVE_DEST_PATH}"
fi
</code></pre></p>

<p>The final part only occurs if the project is part of a git repository.  If it is then the bundle is added to git and then just that bundle is committed with a simple message.</p>

<h2 id="conclusion">Conclusion</h2>

<p>Although I have recently been having issues getting <code>symbolicatecrash</code> to work properly, eventually either I or someone else will get it working again and at that time these files will be invaluable in tracking down crashes.</p>

<p>The final script is attached.  I normally add the file to the project and then have a script phase that just calls this script file.</p>

<p><a href="http://www.cimgf.com/wp-content/uploads/2009/12/Move_dSYM_To_Storage.sh.zip" title="Move_dSYM_To_Storage.sh.zip">Move_dSYM_To_Storage.sh.zip</a></p>

<div class="footnote"><p>
<sup>[<a name="ftn.id394062" href="#id394062">1</a>]</sup>Mach-o objects have an embedded uuid which must match the uuid of the dsym files. That&#8217;s why recompiling doesn&#8217;t work. &#8211;<a href='http://twitter.com/iamleeg/status/6998511425'>Graham Lee</a></p></div>
]]></content:encoded>
			<wfw:commentRss>http://www.cimgf.com/2009/12/23/automatically-save-the-dsym-files/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Version Control Makes You A Better Programmer</title>
		<link>http://www.cimgf.com/2008/06/03/version-control-makes-you-a-better-programmer/</link>
		<comments>http://www.cimgf.com/2008/06/03/version-control-makes-you-a-better-programmer/#comments</comments>
		<pubDate>Tue, 03 Jun 2008 17:47:45 +0000</pubDate>
		<dc:creator>Matt Long</dc:creator>
				<category><![CDATA[Advanced]]></category>
		<category><![CDATA[Coding Practice]]></category>
		<category><![CDATA[Development Environment]]></category>
		<category><![CDATA[Git]]></category>
		<category><![CDATA[Version Control]]></category>

		<guid isPermaLink="false">http://www.cimgf.com/?p=130</guid>
		<description><![CDATA[I&#8217;m a believer. I&#8217;ve used version control before, but Marcus has convinced me that with a little known version control system called Git, written by Linus Torvalds (the creator of Linux), version control is not just about versioning, it&#8217;s about expressing yourself with your code and collaborating with others, seamlessly. As memory serves the only [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m a believer. I&#8217;ve used version control before, but Marcus has convinced me that with a little known version control system called <a href="http://www.kernel.org/pub/software/scm/git/docs/tutorial.html">Git</a>, written by <a href="http://en.wikipedia.org/wiki/Linus_Torvalds">Linus Torvalds</a> (the creator of Linux), version control is not just about versioning, it&#8217;s about expressing yourself with your code and collaborating with others, seamlessly.</p>

<p>As memory serves the only time I&#8217;ve used version control in a meaningful way the system I was using was Visual SourceSafe from Microsoft. I know. Blech! It&#8217;s awful! I&#8217;ve <em>pulled</em> code from many a CVS or Subversion repository, but I&#8217;ve never really used them in the way they are intended to be used. Now, thanks to Marcus, I realize that version control isn&#8217;t just about versioning any more. It&#8217;s a whole methodology/ideology that makes better programmers. Here is what I mean.
<span id="more-130"></span></p>

<h2>Branching Inspires Wild Experimentation</h2>

<p>Have you ever been so far down a path in your code that you just think, though you probably should, there is no way you would take a chance to re-factor due to looming deadlines or even just a simple fear that you might mess up so badly you couldn&#8217;t recover? Well, fear no more! Git provides such a simple way to create a branch of your code in which you can experiment, you won&#8217;t even give it a second thought. I won&#8217;t go into the whole setup and how to get going with Git as this is done very well elsewhere <a href="http://www.cimgf.com/2008/03/18/git-and-mac-a-match-made-in-purgatory/">including a previous post from Marcus</a>. I just want to point out how easy it is to branch with a single command. In Terminal.app, <em>cd</em> to the directory of a project you have under Git source control and enter the following command.
<pre>
bash$ git branch experimental
</pre>
That&#8217;s all there is to it. You now have a nice shiny clean slate to experiment with abandon. You simply type:
<pre>
bash$ git checkout experimental
</pre>
and you are now working on the <em>experimental</em> branch you just created. Now you can just run amok and have nothing to worry about. Make crazy experimental changes to your heart&#8217;s content and all you need to do to go back to your original code base is type:
<pre>
bash$ git checkout master
</pre>
and you&#8217;re back in business. If you found that your crazy coding excursion was a great success, you can merge your changes in with the following commands.
<pre>
bash$ git checkout master
bash$ git merge experimental
</pre>
The first command switches you back to the <em>master</em> branch, while the second performs the merge of the code from the <em>experimental</em> branch into the <em>master</em> branch. If there are conflicts, you will have to fix them manually, but it seems that the need to do so is pretty rare. Git does a great job at merging changes automatically.</p>

<p>If you found, conversely, that your ideas were purely delusional&#8211;a characteristic of your over-achieving sense of hubris&#8211;you can blow them away by simply typing:
<pre>
bash$ git branch -d experimental
</pre></p>

<p>Now the idea is just a bad memory and not something you ever need worry about (or mention to your programming peers) again. Your code on the master branch is still as it was when you first started the branch. Hallelujah!</p>

<blockquote><strong>Note:</strong> The word &#8216;experimental&#8217; I&#8217;ve used in these command line examples is simply a tag. You can call your branch whatever you like. Call it &#8216;hubris&#8217; if you like. Depending on your personality, this may be more appropriate.</blockquote>

<p>The chance to experiment so easily and without fear will make you a better programmer. You will venture into areas that you would have never tried before and will likely become more bold in what you&#8217;re willing to attempt. This can only be a good thing in the long run.</p>

<h2>Collaboration</h2>

<p>The <a href="http://www.kernel.org/pub/software/scm/git/docs/tutorial.html">Tutorial introduction to git</a> provides a good example of how to collaborate when multiple people are working on the same computer, but where Git&#8217;s real power comes in is in its ability to enable collaboration. If you&#8217;re familiar with extreme programming or pair programming then you are already aware of how collaboration will make you a better programmer. The learning curve for developing applications for the Macintosh for me has been significantly leveled as Marcus has shown me how to do things in the context of real code. You can learn things in many different ways, but sharing code has got to be one of the strongest means of gaining deeper understanding. This can only make you a better programmer.</p>

<p>While not a direct feature of Git itself, you can share your repository over the many file sharing web applications out there. Marcus and I use <a href="http://www.getdropbox.com/">Dropbox</a> for our projects that we collaborate on. Here are the steps you take to collaborate remotely using Git and Dropbox.</p>

<ol>
<li>Sign up and install Dropbox from <a href="http://www.getdropbox.com/">http://www.getdropbox.com</a>.<br />
<br />This will create a folder in your home directory under <em>~/Dropbox</em>.</li>

<li>Have the person you want to collaborate with do the same and then create a shared folder that both of you can access through the Dropbox web interface.<br /><br /></li>

<li>From the project directory of the project you want to share, type:
<pre>
bash$ git clone --bare . ~/Dropbox/Shared/MySharedProject.git
</pre>
<blockquote>
<strong>Note:</strong> Keep in mind that I&#8217;m assuming you already have this project under Git version control. If not you first need to run init like so in the root of your project directory.
<pre>
bash$ git init
</pre>
</blockquote>

The <strong>&#8211;bare</strong> keyword we used in the clone command means that we simply want to create a directory that contains the contents of the .git directory in your project directory and not the actual workspace. The .git directory contains all of your code and changes to everything you need is there&#8211;it&#8217;s just not the actual workspace where xcode works from. 

</li>
<li>Create a remote (alias) for the newly cloned project by typing:
<pre>
bash$ git remote add sharedproject ~/Dropbox/Shared/MySharedProject.git
</pre>
</li><br />
<li>Now you can push any code changes from your working directory to the cloned directory, which, since it is in your <em>Dropbox</em> will automatically be uploaded to the drop box and downloaded by any other computers you have that can access <em>Dropbox</em>. First you need to commit any changes in your working directory with the following command.
<pre>
bash$ git commit -a -m "Commit message"
</pre>
Then you need to push the changes to the remote with the following.
<pre>
bash$ git push sharedproject master
</pre>
This pushes your changes to the cloned repository which is in your </em>Dropbox</em> directory. As soon as you do this, you should see the <em>Dropbox</em> icon in your menu bar change to the &#8216;synchronizing&#8217; icon. If your change is small, it will only change for a split second so you&#8217;ll have to watch it closely to see that happen.
</li>
</ol>

<p>Once your files are committed and have been pushed to your cloned repository, you can now <em>pull</em> the project from another computer. I&#8217;m assuming you have <em>Git</em> and <em>Dropbox</em> set up on the second computer. Here are the steps you take to get the code into Git.</p>

<ol>
<li>In Terminal.app on your other computer, create a new directory where you want your project to be stored with a working directory. Now run the following command.
<pre>
bash$ git clone ~/Dropbox/Shared/MySharedProject.git
</pre>
Notice that we didn&#8217;t use the <strong>&#8211;bare</strong> keyword this time. This is because we want our cloned copy to also setup a working directory since we&#8217;ll be accessing it from xcode on the second computer as well.
</li>
<li>Now create a remote (alias) to reference the project like you did on the other computer using the following.
<pre>
bash$ git remote add sharedproject ~/Dropbox/Shared/MySharedProject.git
</pre>
<blockquote><strong>Note:</strong> This step is optional as your clone will do this automatically. The difference, however, is that the clone will create a remote called &#8216;origin&#8217; by default where you can name it whatever you want (sharedproject in the example) if you do run it.</blockquote>
</li>
<li>Now you can pull the code at any time with the following command.
<pre>
bash$ git pull sharedproject master
</pre>
You won&#8217;t need to do that at this point as your code is fresh from the clone, however, should you make any changes on the originating computer that have been pushed, you could now pull those changes from this secondary computer.
</ul>
</ol>

<p>If you now make changes to the code on the second computer, you can use the exact same command you used on the first computer to push the changes. First commit the changes with:
<pre>
bash$ git commit -a -m "Commit message"
</pre>
Then simply push the changes to the cloned repository with:
<pre>
bash$ git push sharedproject master
</pre></p>

<p>And now you&#8217;re up to date. The changes are ready to be downloaded from the first computer.</p>

<h2>The Urge To Merge</h2>

<p>Nothing like sexual inuendo (urge to merge, hint hint, wink wink) on a site called &#8216;Cocoa is my Girlfriend&#8217; to get a geek going, but that&#8217;s not what I mean. Settle down. Take it easy&#8230;</p>

<p>In the end, Git&#8217;s greatest feature is its ability to merge code changes.</p>

<p>There are times when you have fairly complex code merges that are necessary and systems such as CVS or SVN (Subversion) will simply choke and give up leaving the messy merging process to your weak manual merging skills. This is a shame and not necessary any more as it is rare for Git to be unable to successfully merge code. Again, this probably its biggest strength. When you don&#8217;t have to worry about merging your code, you can do whatever you like in your branch with little fear that merging in your changes are going to conflict with someone else&#8217;s. This merging power comes from Git&#8217;s unique philosophy of source code management which sees changes as individual code additions and deletions rather than complete file changes.</p>

<h2>Conclusion</h2>

<p>There will remain naysayers who have &#8220;always done it this way&#8221; and will remain in the realm of central repositories for version control. However, if you can think outside of tradition and see the power that comes from a good source control system, you will become a better programmer. I will submit that simply starting to use any version control when you haven&#8217;t before will make you a better programmer, however, using Git for your version control system, will make it infinitely easier to become so.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cimgf.com/2008/06/03/version-control-makes-you-a-better-programmer/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>Git and XCode: A git build number script</title>
		<link>http://www.cimgf.com/2008/04/13/git-and-xcode-a-git-build-number-script/</link>
		<comments>http://www.cimgf.com/2008/04/13/git-and-xcode-a-git-build-number-script/#comments</comments>
		<pubDate>Mon, 14 Apr 2008 01:36:48 +0000</pubDate>
		<dc:creator>Marcus Zarra</dc:creator>
				<category><![CDATA[Coding Practice]]></category>
		<category><![CDATA[Development Environment]]></category>
		<category><![CDATA[Git]]></category>
		<category><![CDATA[Version Control]]></category>

		<guid isPermaLink="false">http://www.cimgf.com/?p=95</guid>
		<description><![CDATA[Git has been gaining in popularity with Cocoa developers as well as open source developers. As I work it into my development workflow, one item that was missing was the automatic injection of the build number into the application bundle. There are a few scripts floating around that perform this trick for subversion, but git [...]]]></description>
			<content:encoded><![CDATA[<p>Git has been gaining in popularity with Cocoa developers as well as open source developers.  As I work it into my development workflow, one item that was missing was the automatic injection of the build number into the application bundle.</p>

<p>There are a few scripts floating around that perform this trick for subversion, but git handles build numbers a bit differently and it appears that no one has bothered to publish one.  As is known, subversion uses an incrementing integer for build numbers.  This makes it very easy to determine which build number came first and makes it very useful for a non-public version number.  Git, however, uses a hash for each build number which is not incrementing and therefore not very useful for determining version numbers.  However, it is still very useful for pulling up a specific build when a crash report is received, etc.</p>

<p>Therefore, with the help of Matt Long&#8217;s perl-fu, I have updated Daniel Jalkut&#8217;s subversion perl script to work with git.  Since the build numbers are not sequential, I would not recommend using them for Sparkle.  Therefore, in my own build process for iWeb Buddy, I hand select the version number (for example 1.0.4) and then use the short hash from git as the CFBundleVersion number.  Normally this number is displayed in parens after the primary build number but, at least in iWeb Buddy, I have removed it from the display entirely.  Since it is no longer a sequential number it would only potentially confuse users and it displays in the crash reports anyway.</p>

<p>The updated script is as follows:</p>


<div class="wp_syntax"><div class="code"><pre class="perl" style="font-family:monospace;"><span style="color: #666666; font-style: italic;"># Xcode auto-versioning script for Subversion by Axel Andersson</span>
<span style="color: #666666; font-style: italic;"># Updated for git by Marcus S. Zarra and Matt Long</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">use</span> strict<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># Get the current git commit hash and use it to set the CFBundleVersion value</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$REV</span> <span style="color: #339933;">=</span> <span style="color: #ff0000;">`/opt/local/bin/git show --abbrev-commit | grep &quot;^commit&quot;`</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$INFO</span> <span style="color: #339933;">=</span> <span style="color: #ff0000;">&quot;$ENV{BUILT_PRODUCTS_DIR}/$ENV{WRAPPER_NAME}/Contents/Info.plist&quot;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$version</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$REV</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">$version</span> <span style="color: #339933;">=~</span> <span style="color: #009966; font-style: italic;">/^commit\s+([^.]+)\.\.\.$/</span> <span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span> 
	<span style="color: #0000ff;">$version</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$1</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #b1b100;">else</span>
<span style="color: #009900;">&#123;</span>
	<span style="color: #0000ff;">$version</span> <span style="color: #339933;">=</span> <span style="color: #000066;">undef</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #000066;">die</span> <span style="color: #ff0000;">&quot;$0: No Git revision found&quot;</span> <span style="color: #b1b100;">unless</span> <span style="color: #0000ff;">$version</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000066;">open</span><span style="color: #009900;">&#40;</span>FH<span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;$INFO&quot;</span><span style="color: #009900;">&#41;</span> <span style="color: #b1b100;">or</span> <span style="color: #000066;">die</span> <span style="color: #ff0000;">&quot;$0: $INFO: $!&quot;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$info</span> <span style="color: #339933;">=</span> <span style="color: #000066;">join</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;&quot;</span><span style="color: #339933;">,</span> <span style="color: #009999;">&lt;FH&gt;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000066;">close</span><span style="color: #009900;">&#40;</span>FH<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #0000ff;">$info</span> <span style="color: #339933;">=~</span> <span style="color: #009966; font-style: italic;">s/([\t ]+&lt;key&gt;CFBundleVersion&lt;\/key&gt;\n[\t ]+&lt;string&gt;).*?(&lt;\/string&gt;)/$1$version$2/</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000066;">open</span><span style="color: #009900;">&#40;</span>FH<span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;&gt;$INFO&quot;</span><span style="color: #009900;">&#41;</span> <span style="color: #b1b100;">or</span> <span style="color: #000066;">die</span> <span style="color: #ff0000;">&quot;$0: $INFO: $!&quot;</span><span style="color: #339933;">;</span>
<span style="color: #000066;">print</span> FH <span style="color: #0000ff;">$info</span><span style="color: #339933;">;</span>
<span style="color: #000066;">close</span><span style="color: #009900;">&#40;</span>FH<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>


<p>Since git is distributed, there is no need to be online to produce a build.  The script will grab the current abbrev-commit hash and will inject it into the current build&#8217;s Info.plist file.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cimgf.com/2008/04/13/git-and-xcode-a-git-build-number-script/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Cocoa Tutorial: Fixing Memory Leaks With Instruments</title>
		<link>http://www.cimgf.com/2008/04/02/cocoa-tutorial-fixing-memory-leaks-with-instruments/</link>
		<comments>http://www.cimgf.com/2008/04/02/cocoa-tutorial-fixing-memory-leaks-with-instruments/#comments</comments>
		<pubDate>Thu, 03 Apr 2008 00:58:50 +0000</pubDate>
		<dc:creator>Matt Long</dc:creator>
				<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Coding Practice]]></category>
		<category><![CDATA[Development Environment]]></category>

		<guid isPermaLink="false">http://www.cimgf.com/2008/04/02/cocoa-tutorial-fixing-memory-leaks-with-instruments/</guid>
		<description><![CDATA[As I am getting toward what I think is the end of coding for an application I hope to release soon, the nitty gritty work of fixing leaks, optimizing code, and squashing bugs has become the majority of what I&#8217;m doing now. Gone is the fun part of the application development process where I was [...]]]></description>
			<content:encoded><![CDATA[<p><img src='http://www.cimgf.com/wp-content/uploads/2008/04/leaks_icon.png' alt='Leaks Icon' align='left'/>As I am getting toward what I think is the end of coding for an application I hope to release soon, the nitty gritty work of fixing leaks, optimizing code, and squashing bugs has become the majority of what I&#8217;m doing now. Gone is the fun part of the application development process where I was creating features and solving new problems. It is now drudgery and focusing requires diligence. I know that the rewards are worth it as these final steps are what give an application stability and make it shine, but getting through it can be nothing but toil. Fortunately with the developer tools that shipped with Leopard, Apple has made this work much easier to handle in a little application called Instruments.
<span id="more-78"></span></p>

<p>As usual, I&#8217;ve created a demo application that will allow you to see how things work. You can download it here: <a href='http://www.cimgf.com/wp-content/uploads/2008/04/leaky.zip' title='Leaky Demo Application'>Leaky Demo Application</a>. In this post I am simply going to show you how to use Instruments to detect memory leaks. It&#8217;s pretty straightforward, but there are few little nuances you may not be familiar with that once you understand will help you feel comfortable using this powerful tool.</p>

<h2>Running Instruments From XCode</h2>

<p>You can start Instruments directly and then navigate to your project build, however, it&#8217;s much quicker and simpler to start Instruments from XCdoe. To do so , open the demo project or a project of your own in XCode and select <strong>Run | Start With Performance Tool | Leaks</strong>.</p>

<p><a href='http://www.cimgf.com/wp-content/uploads/2008/04/start_leaks.png' title='Start Leaks Instrument' rel='lightbox'><img src='http://www.cimgf.com/wp-content/uploads/2008/04/start_leaks.thumbnail.png' alt='Start Leaks Instrument' /></a></p>

<p>While working on this project, Marcus and I discovered a few things that you should keep in mind while you are using Instruments.</p>

<ul>
<li><strong>Breakpoints Do Not Break</strong>. Instruments utilizes debug information from your debug build, however, it does not stop at break points you set. This is because while you are loading your application into Instruments from the menu in XCode, Instruments simply uses the path of the current executable as its start path and loads it externally from XCode. The menu in XCode is really there as a convenience mechanism. This is not a big deal as you can always run again in Debug mode after your instruments session should you want your application to break. It&#8217;s just something to make a note of.</li>
<br />
<li><strong>NSLog Statements Do Not Show In The Debugger Console</strong>. If you want to see your NSLog statements, you will need to load the system Console application (<em>/Applications/Utilities/Console</em>).</li>
</ul>

<h2>Leaking Like A Sieve&#8230; Or Not</h2>

<p>Our expectation was that when we allocated memory for a new <em>NSString*</em> object we would see it leak right away. This was, after all, our intention. Things, however, don&#8217;t always work the way you might expect. This code would not leak in our tests no matter what we tried.</p>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span><span style="color: #a61390;">string</span> <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSString</span> alloc<span style="color: #002200;">&#93;</span> initWithString<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;Leaker&quot;</span><span style="color: #002200;">&#93;</span>;</pre></td></tr></table></div>


<p>And here&#8217;s why. It turns out that since <em>NSString</em>(s) are immutable and since we are allocating the string using the <strong>@</strong> operator, the compiler is making things more efficient for us. Strings with the same contents are given the same memory address. Here is a comment from the CocoaDev site that clarifies what I mean.</p>

<blockquote>
The nice thing about using the @&#8221;" notation for initializing NSString objects is that if you create two of them and their content is the same, the runtime uses the same storage for them. (Note, this is not guaranteed and certainly may not be the case across compilation unit or library boundaries. It is a performance optimization and the fact that it happens sometimes should not lead you to believe that you can safely, for example, use &#8220;==&#8221; to compare strings if you know they&#8217;re both from string constants.) <a href="http://www.cocoadev.com/index.pl?NSString">(Ref. CocoaDev NSString)</a>
</blockquote>

<p>In the example code, the NSString objects never leak and so they weren&#8217;t very useful. This isn&#8217;t to say that they never will leak, so you should be in the habit of calling <em>release</em> on your NSString(s), however, for our example project at least, the NSString leaks were never detected. We instead switched over to using NSMutableString at which point the application began to leak as desired.</p>

<h2>Detecting Leaks</h2>

<p>When instruments loads your application, you will see the <strong>ObjectAlloc</strong> track start to fill in. To detect the leaks in your project, click on the <strong>Leaks</strong> track and then watch the <strong>Leak Status</strong> category which will detect leaks after the current timeout value. Alternatively, you can just click the <strong>Check For Leaks Now</strong> button under the <strong>Check Manually</strong> category.</p>

<p><img src='http://www.cimgf.com/wp-content/uploads/2008/04/leaks_info.png' alt='Leaks Info' style='text-align: center;'/><br /></p>

<p>Once the leak detection process has occurred you will see a list of objects that are currently leaking. To get details for any leaks in the list, click the object in the list and then click the <em>Extended Detail</em> button at the bottom of the Instruments screen.
<br />
<a href='http://www.cimgf.com/wp-content/uploads/2008/04/extended_detail_button.png' title='Extended Detail' rel='lightbox'><img src='http://www.cimgf.com/wp-content/uploads/2008/04/extended_detail_button.thumbnail.png' alt='Extended Detail' /></a></p>

<p>Once you have clicked the Extended Detail button, you will see the stack trace list on the right side of the Instruments window. Look through the stack and locate any code highlighted with the color #CCFFFF which looks like this.</p>

<p><img src='http://www.cimgf.com/wp-content/uploads/2008/04/ccffff.png' alt='#CCFFFF' /><br /><img src='http://www.cimgf.com/wp-content/uploads/2008/04/leak.png' alt='Leak' /></p>

<hr />

<blockquote><strong>Note:</strong> This is actually inaccurate. The color may be different on your machine than on mine. Instead of looking for a color, look for your applications name and path and double-click that instead.<a href='http://www.cimgf.com/wp-content/uploads/2008/04/stack_mouseover.png' title='Stack Mouse Over' rel='lightbox'><img src='http://www.cimgf.com/wp-content/uploads/2008/04/stack_mouseover.png' alt='Stack Mouse Over' /></a><br />
Thanks to Jason for pointing out the error.</blockquote>

<hr />

<p>Once you find the leak in your application, simply double click it and Instruments will return you to the exact line in XCode where the leak is happening.</p>

<p><a href='http://www.cimgf.com/wp-content/uploads/2008/04/leak_stack.png' title='Leak Stack' rel='lightbox'><img src='http://www.cimgf.com/wp-content/uploads/2008/04/leak_stack.thumbnail.png' alt='Leak Stack' /></a></p>

<p>To fix the leak, you need to make sure that you release the object. For more information and basic guidelines on memory allocation and deallocation, do a Google search. You can start with sites like this one: <a href="http://www.stepwise.com/Articles/Technical/2001-03-11.01.html">Very simple rules for memory management in Cocoa</a>.</p>

<h2>Conclusion</h2>

<p>Finding and fixing issues is not the most glamorous aspect of application development, however, when done, the results are very rewarding. Instruments provides a streamlined way to track everything you would care about in your application. Watch this site for more tutorials on how to use other components available in Instruments. If you want to get an idea of what&#8217;s available, click on the <strong>Library</strong> button in Instruments and scroll through the ensuing list. It&#8217;s impressive.</p>

<p><img src='http://www.cimgf.com/wp-content/uploads/2008/04/library.png' alt='Instruments Library' /></p>
]]></content:encoded>
			<wfw:commentRss>http://www.cimgf.com/2008/04/02/cocoa-tutorial-fixing-memory-leaks-with-instruments/feed/</wfw:commentRss>
		<slash:comments>19</slash:comments>
		</item>
		<item>
		<title>Git and .mac: A Match Made In Purgatory</title>
		<link>http://www.cimgf.com/2008/03/18/git-and-mac-a-match-made-in-purgatory/</link>
		<comments>http://www.cimgf.com/2008/03/18/git-and-mac-a-match-made-in-purgatory/#comments</comments>
		<pubDate>Tue, 18 Mar 2008 20:16:06 +0000</pubDate>
		<dc:creator>Marcus Zarra</dc:creator>
				<category><![CDATA[Development Environment]]></category>
		<category><![CDATA[Git]]></category>
		<category><![CDATA[Version Control]]></category>

		<guid isPermaLink="false">http://www.cimgf.com/2008/03/18/git-and-mac-a-match-made-in-purgatory/</guid>
		<description><![CDATA[Last year, I made the switch from subversion to Git. After 9+ months of using Git, I can comfortably say that it was a very good choice. While branching is easy in subversion, merging is just as bad as it was in cvs. Git is a significant improvement over that. In addition, since Git is [...]]]></description>
			<content:encoded><![CDATA[<p>Last year, I made the switch from subversion to <a href="http://git.or.cz/">Git</a>.  After 9+ months of using Git, I can comfortably say that it was a very good choice.  While branching is easy in subversion, merging is just as bad as it was in cvs.  Git is a significant improvement over that.  In addition, since Git is a true distributed source control system, I can easily do branches and merges on my local machine without an internet connection and just &#8220;push&#8221; my changes to my off-site server when it is convenient.</p>

<p>I am also a user of .mac.  I like the service and the iDisk is probably my favorite feature.  Therefore, I wondered, like chocolate and peanut butter, could I put these two together and come up with something better than the individual parts?
<span id="more-66"></span></p>

<p>The answer is yes.  They work amazingly well together and make it very easy for me to push my code changes off-site even when I am not actually connected to the net.  The basic configuration is fairly simple.  I created a private directory on .mac, set up a bare repository in that directory and defined that directory as a remote location for my Git workspace.  Below are the details on how to accomplish this.</p>

<h2>Install Git on OS X</h2>

<p>First, you need to have Git.  The easiest way that I have found to get it is to use the <a href='http://www.macports.org'>MacPorts</a> and do a &#8216;sudo port install git-core +svn&#8217;.  I add svn because once you get used to Git you will want to put it in front of all your svn repositories that all those stone age developers still use.</p>

<blockquote><strong>Note:</strong> After installing MacPorts, you may need to add /opt/local/bin to your PATH in order for the <em>port</em> command to be found from the command line. Edit your .bash_profile file in your home directory (assuming you use bash) in Terminal and add the following line to the bottom of the file: <strong>export PATH=/opt/local/bin:$PATH
</strong>.</blockquote>

<h2>Create your working repository</h2>

<p>Once you have Git installed, you will want to create a repository.  That is accomplished with a single call:</p>

<p><pre>
mkdir TempProject
cd TempProject
git init
</pre></p>

<p>What that does is create a single directory called .git in the TempProject directory.  All of the version information for that workspace is stored in that single .git directory (hello Subversion guys, your .svn directories suck).</p>

<h2>Set up the bare clone</h2>

<p>Now that your repository is created, you want to create a remote copy of it in case your harddrive eats itself or gets stolen (BTW Wil, <a href="http://wilshipley.com/blog/2008/02/ted2008-part-1-gossip.html">sorry to hear about your MBA</a>, that thief should burn).  To do that, you want to have iDisk local syncing turned on.  When it is, you will have a directory under /Volumes with your .mac username.  For instance, mine is at /Volumes/mzarra.  In this directory you want to create a new directory (I called mine git).  Make sure that directory can only be accessed by you.</p>

<p>Now that it is created, you want to build the bare clone of your workspace.  To accomplish this, execute the following:</p>

<p><pre>
cd TempProject
git clone --bare . /Volumes/${USERNAME}/git/TempProject.git
</pre></p>

<p>After a few moments your new bare clone is ready.</p>

<h2>Linking the remote clone</h2>

<p>The final step is to tell your local repository where that remote repository is:</p>

<p><pre>
cd TempProject
git remote add origin /Volumes/${USERNAME}/git/TempProject.git
</pre></p>

<p>Note that I used origin as this is the default repository name for push and pull.  If you want your origin to be somewhere else then change this name.</p>

<h2>Performing a push</h2>

<p>Now that everything is set up all you need to do to sync your repositories is:</p>

<p><pre>
git push
</pre></p>

<p>And Git will update the bare clone.</p>

<h2>Sync multiple working copies</h2>

<p>But wait &#8212; there is more.  If you have more than one Mac, you can use this bare clone to keep your two workspaces in sync!  On the other Mac, once Git is installed, you can grab a working copy as follows:</p>

<p><pre>
git clone /Volumes/${USERNAME}/git/TempProject.git
</pre></p>

<p>And you will now have another working copy!  If you need to update your second Mac at a later point just:</p>

<p><pre>
git pull
</pre></p>

<p>And Git will do all the work for you.</p>

<h2>Conclusion</h2>

<p>There are a couple things to note.</p>

<ul>
<li>The initial sync back to .mac can be slow if your workspace is large.  However, as long as you &#8216;push&#8217; often enough, your subsequent syncs should be very quick.  Therefore, get in the habit of pushing often.</li>
<br />
<li> Only one Mac can sync with .mac at a time.  Therefore it is possible to get a sync failure if the n Macs try to sync at the same time.  Therefore if you are going to do a pull and you <em>just</em> pushed to .mac, make sure that both syncs succeeded.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.cimgf.com/2008/03/18/git-and-mac-a-match-made-in-purgatory/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
	</channel>
</rss>
