<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/atom.xsl" media="screen"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-US"><title type="html">Edward Thomson&amp;#39;s Blog</title><subtitle type="html">Discussions about Team Foundation Server in a cross-platform environment.</subtitle><id>http://blogs.msdn.com/b/ethomson/atom.aspx</id><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/ethomson/" /><link rel="self" type="application/atom+xml" href="http://blogs.msdn.com/b/ethomson/atom.aspx" /><generator uri="http://telligent.com" version="5.6.50428.7875">Telligent Evolution Platform Developer Build (Build: 5.6.50428.7875)</generator><updated>2011-04-04T23:37:00Z</updated><entry><title>Locking and git-tf and... danger?</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/ethomson/archive/2012/08/28/locking-and-git-tf.aspx" /><id>http://blogs.msdn.com/b/ethomson/archive/2012/08/28/locking-and-git-tf.aspx</id><published>2012-08-28T14:56:00Z</published><updated>2012-08-28T14:56:00Z</updated><content type="html">&lt;p&gt;If you haven't yet seen or heard about the new git-tf tool from Microsoft, this blog post probably won't make any sense. &amp;nbsp;So... &amp;nbsp;go check it out over at &lt;a href="http://gittf.codeplex.com/" target="_blank"&gt;gittf.codeplex.com&lt;/a&gt;. &amp;nbsp;It's okay, I'll wait.&lt;/p&gt;
&lt;p&gt;Okay, got it? &amp;nbsp;Yeah, I know, it's cool, right? &amp;nbsp;Well, it is, but like any software project, there are a few problems. &amp;nbsp;One of them is in the whole &lt;code&gt;git-tf checkin&lt;/code&gt; process and how it needs to take a lock on your tree before it can continue. &amp;nbsp;I mean, locks are annoying, right? &amp;nbsp;If git-tf requires a lock to do a checkin, then that's going to fail if somebody else has already taken a lock somewhere in that folder. &amp;nbsp;And, of course, the default in TFS is to take a lock on binaries, so if you've got some of those in your tree then git-tf is going to complain all the time when you try to checkin.&lt;/p&gt;
&lt;p&gt;It's even worse when you run into this the first time and decide that we can't have been so obnoxious as &lt;em&gt;force&lt;/em&gt; you to take a lock. &amp;nbsp;Surely those developers put in some no lock option, maybe even called &lt;code&gt;--no-lock&lt;/code&gt;, that will avoid locking. &amp;nbsp;And we did! &amp;nbsp;And with our appropriately scary warning in the checkin help:&lt;/p&gt;
&lt;pre class="codeblock"&gt;--no-lock Does not take a lock on the server path before committing (dangerous)&lt;/pre&gt;
&lt;p&gt;...you can see why this is a problem. &amp;nbsp;I mean, it's &lt;strong&gt;&lt;em&gt;dangerous?!&lt;/em&gt;&lt;/strong&gt; &amp;nbsp;Who would want to use that!?&lt;/p&gt;
&lt;p&gt;Okay, let's back up and explain why we decide to take this lock.&lt;/p&gt;
&lt;p&gt;Team Foundation Server's version control model has good concurrency. &amp;nbsp;Let's assume that you and I are both working on the latest version and we both edit some files. &amp;nbsp;If we both hit the checkin button at the same time, this is a classic race condition, but one that's harmless. &amp;nbsp;Our checkins get serialized and - assuming we haven't edited any of the same files to produce a conflict - it really doesn't matter all that much which one of us wins this race and which one loses. &amp;nbsp;Both of our changesets got checked in and the next time we do a get latest, we get the other person's changes, too. &amp;nbsp;Things get a little bit more complicated if we edit the same file, but not much. &amp;nbsp;The winner of this race gets their changes checked in - the loser has to resolve a conflict and then checkin again. &amp;nbsp;This is pretty classic version control behavior and a well-understood problem.&lt;/p&gt;
&lt;p&gt;git, of course, also has good concurrency. &amp;nbsp;Let's assume that you and I are both on HEAD and we both edit some files. &amp;nbsp;If we both were to commit to our local git repository, now we both have new commits that share a common parent. &amp;nbsp;At some point, we'll need to merge this branch in the graph, but this is no big deal. &amp;nbsp;Again, a race condition that doesn't matter.&lt;/p&gt;
&lt;p&gt;git-tf, on the other hand, can't cope well with this race condition. &amp;nbsp;(It might be a bit much to have called it &lt;em&gt;dangerous&lt;/em&gt;, but that little word scared you enough to read this blog post, so I think we'll stick with that term for a little while longer.) &amp;nbsp;Here's how git-tf checkin works, in a nutshell:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Finds the latest TFS changeset that you've fetched and merged into your graph. &amp;nbsp;This is the "high water mark".&lt;/li&gt;
&lt;li&gt;Takes a lock on the TFS path you're bridging. &amp;nbsp;Unless, of course, you're living dangerously and using that crazy &lt;code&gt;--no-lock&lt;/code&gt; flag.&lt;/li&gt;
&lt;li&gt;Ensures that this high water mark is actually the latest TFS changeset. &amp;nbsp;If not, you will be told to fetch that changeset and merge.&lt;/li&gt;
&lt;li&gt;Pends the changes to TFS that are representative of the changes in your git commit and checks them in.&lt;/li&gt;
&lt;li&gt;Updates the aforementioned "high water mark" to the changeset that I just checked in.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Let's take another look at this race condition once git-tf gets in the picture. &amp;nbsp;Imagine that I'm using git-tf and you're using some other TFS client like Visual Studio or the TFS plug-in for Eclipse. &amp;nbsp;The latest version is changeset 3, and I've made a git commit on top of that. &amp;nbsp;My git repository looks like this:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-48/4377.locking_2D00_1.png"&gt;&lt;img src="http://blogs.msdn.com/resized-image.ashx/__size/500x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-48/4377.locking_2D00_1.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I'm ready to git-tf checkin these changes, and I'll do so without a lock. &amp;nbsp;Meanwhile, you've also made some changes against TFS and you're going to check in at the same time. &amp;nbsp;If you happen to sneak your changeset in between steps 3 and 4 (above), then I've updated my high-water mark to &lt;em&gt;my&lt;/em&gt; changeset... &amp;nbsp;but I never got &lt;em&gt;your&lt;/em&gt; changeset.&lt;/p&gt;
&lt;p&gt;In a perfect world, I would pull your changeset down as a git commit such that it has a parent of 3, and my git commit &lt;code&gt;4fac65...&lt;/code&gt; has your changeset as a parent. &amp;nbsp;This keeps the linear model of TFS changesets that git-tf strives so hard for. &amp;nbsp;Except that if I do that, my commit can't be &lt;code&gt;4fac65...&lt;/code&gt; anymore, it gets a completely new ID because those are computed based on their parents. &amp;nbsp;Ouch.&lt;/p&gt;
&lt;p&gt;The way it is, I'll never even see your changes until there's a new changeset and I can fetch that, since git-tf's high water mark already includes the latest changeset on the server. &amp;nbsp;So it turns out that not locking can be dangerous after all.&lt;/p&gt;
&lt;p&gt;Of course, most people don't have &lt;em&gt;that&lt;/em&gt; much churn in their code tree that this is an issue. &amp;nbsp;So you could just check the history in TFS to make sure that nobody else snuck with a new changeset in those few seconds. &amp;nbsp;And if they did, of course, you could just stick a new dummy changeset in TFS so that you could pull the latest version that has the other changes, too. &amp;nbsp;But this isn't exactly an ideal workflow.&lt;/p&gt;
&lt;p&gt;So the question of course becomes: &amp;nbsp;can we avoid taking a lock, but stay out of danger? &amp;nbsp;We think so. &amp;nbsp;We spun up &lt;a href="http://gittf.codeplex.com/discussions/393372" target="_blank"&gt;a conversation over on our codeplex site&lt;/a&gt; about this - so if you're interested in this topic, we'd love your feedback.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10342341" width="1" height="1"&gt;</content><author><name>Edward A Thomson</name><uri>http://blogs.msdn.com/ethomson_4000_edwardthomson.com/ProfileUrlRedirect.ashx</uri></author><category term="tfs" scheme="http://blogs.msdn.com/b/ethomson/archive/tags/tfs/" /><category term="git-tf" scheme="http://blogs.msdn.com/b/ethomson/archive/tags/git_2D00_tf/" /><category term="git" scheme="http://blogs.msdn.com/b/ethomson/archive/tags/git/" /></entry><entry><title>Team Foundation Server and Xcode projects with git-tf</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/ethomson/archive/2012/08/28/team-foundation-server-and-xcode-projects-with-git-tf.aspx" /><id>http://blogs.msdn.com/b/ethomson/archive/2012/08/28/team-foundation-server-and-xcode-projects-with-git-tf.aspx</id><published>2012-08-28T14:15:00Z</published><updated>2012-08-28T14:15:00Z</updated><content type="html">&lt;p&gt;Brian Harry &lt;a href="http://blogs.msdn.com/b/bharry/archive/2012/08/13/announcing-git-integration-with-tfs.aspx" target="_blank"&gt;announced the availability of &lt;code style="white-space: nowrap;"&gt;git-tf&lt;/code&gt;&lt;/a&gt;&amp;nbsp;last Monday, a new tool from Microsoft that allows you to create a local git repository from a path in Team Foundation Server, then check the changes in your repository back in to TFS. &amp;nbsp;This tool is another piece in our cross-platform support, aimed at users of IDEs that don't have built-in TFS integration.&lt;/p&gt;
&lt;p&gt;We hope that Xcode users will find this particularly useful, as Xcode sadly lacks a plug-in model that would allow us to build TFS support natively. &amp;nbsp;Xcode does have git support, however, so once you've created your git repository with git-tf,&amp;nbsp;you can use Xcode's source code integration directly.&lt;/p&gt;
&lt;p&gt;This means that if you're writing mobile applications, you can now use Team Foundation Server as your ALM solution for the entire development team. &amp;nbsp;Imagine you have your shared business logic in C, you have a Windows Phone 8 version being developed in Visual Studio, an Android version being developed in Eclipse and an iOS version being developed in Xcode. &amp;nbsp;Now all your developers can take advantage of TFS Version Control - your Visual Studio users with Team Explorer, your Eclipse users with the TFS Plug-in for Eclipse and your Xcode users with git-tf.&lt;/p&gt;
&lt;p&gt;I'm too hopelessly old-school to be hip to the new mobile apps, so I'm going to show how I work on a cross-platform command-line application that plays blackjack. &amp;nbsp;I've got my source in TFS, with an Xcode project side-by-side with my Visual Studio solution:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-48/8640.vstudio_2D00_vc.png"&gt;&lt;img src="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-48/8640.vstudio_2D00_vc.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Once I have Xcode and git-tf installed on my Mac, I can download this project easily:&lt;/p&gt;
&lt;pre class="codeblock"&gt;ethomson@mbp:~/Demo% git tf clone --deep http://tfs2012:8080/tfs/DefaultCollection $/DefaultAgile/blackjack&lt;br /&gt;Username: ethomson&lt;br /&gt;Password: &lt;br /&gt;Connecting to TFS...&lt;br /&gt;Cloning $/DefaultAgile/blackjack into /Users/ethomson/Demo/blackjack: 100%, done.                   &lt;br /&gt;Cloned 14 changesets. Cloned last changeset 19 as fb65c36&lt;br /&gt;ethomson@mbp:~/Demo% &lt;/pre&gt;
&lt;p&gt;Now I have a git repository that represents my TFS changesets, with full history. &amp;nbsp;(That was the &lt;code style="white-space: nowrap;"&gt;--deep&lt;/code&gt; option, without that I would have a single git commit that represents my latest TFS changeset. &amp;nbsp;This is quicker to compute and useful if you don't need full history.) &amp;nbsp;You can see that my history in Visual Studio:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-48/3441.vstudio_2D00_history.png"&gt;&lt;img src="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-48/3441.vstudio_2D00_history.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;is the same as the history in my local git repository:&lt;/p&gt;
&lt;pre class="codeblock"&gt;ethomson@mbp:~/Demo/blackjack% git log&lt;br /&gt;commit f33b75c0190d76c417fd5d724236a9c3f731b185&lt;br /&gt;Author: tfsuser &amp;lt;tfs2012\tfsuser&amp;gt;&lt;br /&gt;Date:   Tue Aug 14 15:20:20 2012 -0500&lt;br /&gt;&lt;br /&gt;    This is a commit from Xcode.&lt;br /&gt;&lt;br /&gt;commit a88b3887f1998fac74beb8ee32b4d91e06d8e625&lt;br /&gt;Author: ethomson &amp;lt;tfs2012\ethomson&amp;gt;&lt;br /&gt;Date:   Tue Aug 14 15:16:16 2012 -0500&lt;br /&gt;&lt;br /&gt;    This is a change from Visual Studio.&lt;br /&gt;&lt;br /&gt;...etc...&lt;/pre&gt;
&lt;p&gt;When I open up this project in Xcode, you'll notice that when I start making changes to files, they're automatically added to my git index, as denoted by the small &lt;strong&gt;M&lt;/strong&gt;&amp;nbsp;next to the filename in Project Navigator. &amp;nbsp;Below, I've made some changes to my project's assertion logic, changing Assert.cpp and Assert.h.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-48/6622.xcode_2D00_editing.png"&gt;&lt;img src="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-48/6622.xcode_2D00_editing.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;When Xcode's source control integration, I can commit these changes to my local git repository from right within my IDE. &amp;nbsp;When committing, it will show a handy diff viewer for each file in my commit.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-48/0474.xcode_2D00_committing.png"&gt;&lt;img src="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-48/0474.xcode_2D00_committing.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;You can see the two commits I've made in my Xcode project in my git log.&lt;/p&gt;
&lt;pre class="codeblock"&gt;ethomson@mbp:~/Demo/blackjack% git log&lt;br /&gt;commit 6f9bbafa5482c77de5b97b2548320b78de6b82fe&lt;br /&gt;Author: Edward Thomson &amp;lt;ethomson@edwardthomson.com&amp;gt;&lt;br /&gt;Date:   Thu Aug 16 15:58:43 2012 -0500&lt;br /&gt;&lt;br /&gt;    Fixed some typos in the comments.&lt;br /&gt;&lt;br /&gt;commit 8dd92848b4ea0f6549d6f88d28e47c3e1201cd7c&lt;br /&gt;Author: Edward Thomson &amp;lt;ethomson@edwardthomson.com&amp;gt;&lt;br /&gt;Date:   Thu Aug 16 15:55:01 2012 -0500&lt;br /&gt;&lt;br /&gt;    A couple of minor changes in Xcode&lt;br /&gt;&lt;br /&gt;...etc...&lt;/pre&gt;
&lt;p&gt;Once I'm done making changes locally and I want to integrate with the rest of the team, I can check them in to my TFS server using git-tf checkin. &amp;nbsp;Just like when I cloned my project, I can use the &lt;code style="white-space: nowrap;"&gt;--deep&lt;/code&gt; option to preserve history.&lt;/p&gt;
&lt;pre class="codeblock"&gt;ethomson@mbp:~/Demo/blackjack% git tf checkin --deep&lt;br /&gt;Username: ethomson&lt;br /&gt;Password: &lt;br /&gt;Connecting to TFS...&lt;br /&gt;Checking in to $/DefaultAgile/blackjack: 100%, done.                            &lt;br /&gt;Checked in 2 changesets, HEAD is changeset 21&lt;/pre&gt;
&lt;p&gt;Back in Visual Studio, you can see both of these changesets in my TFS history.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-48/6283.vstudio_2D00_aftercheckin.png"&gt;&lt;img src="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-48/6283.vstudio_2D00_aftercheckin.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;And, of course, since I'm doing Continuous Integration builds for this project, as soon as I checkin from git-tf, TFS queues up a build for me. &amp;nbsp;In this case, I get two - one for each changeset, since I did a deep checkin from my two git commits.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-48/7245.vstudio_2D00_builds.png"&gt;&lt;img src="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-48/7245.vstudio_2D00_builds.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-48/7245.vstudio_2D00_builds.png"&gt;&lt;/a&gt;So you can see that now I can easily use Xcode to take advantage of the ALM functionality of Team Foundation Server, providing every developer on a team with intuitive access to TFS Version Control.&lt;/p&gt;
&lt;p&gt;git-tf is &lt;a href="http://gittf.codeplex.com/" target="_blank"&gt;available now on CodePlex&lt;/a&gt;, Microsoft's Project Hosting for Open Source Software and we're making git-tf available open source under the MIT license. &amp;nbsp;We think this is a very useful tool right now, and we're looking forward to making it even better.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10341166" width="1" height="1"&gt;</content><author><name>Edward A Thomson</name><uri>http://blogs.msdn.com/ethomson_4000_edwardthomson.com/ProfileUrlRedirect.ashx</uri></author><category term="cross-platform" scheme="http://blogs.msdn.com/b/ethomson/archive/tags/cross_2D00_platform/" /><category term="tfs" scheme="http://blogs.msdn.com/b/ethomson/archive/tags/tfs/" /><category term="git-tf" scheme="http://blogs.msdn.com/b/ethomson/archive/tags/git_2D00_tf/" /><category term="git" scheme="http://blogs.msdn.com/b/ethomson/archive/tags/git/" /></entry><entry><title>TFS Austin User Group</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/ethomson/archive/2011/04/04/tfs-austin-user-group.aspx" /><id>http://blogs.msdn.com/b/ethomson/archive/2011/04/04/tfs-austin-user-group.aspx</id><published>2011-04-05T04:37:00Z</published><updated>2011-04-05T04:37:00Z</updated><content type="html">&lt;p&gt;A very special thanks to the &lt;a target="_blank" href="https://sites.google.com/site/tfsaustinusergroup/" title="TFS Austin User Group"&gt;TFS Austin User Group&lt;/a&gt;&amp;nbsp;for providing me time today to present on TFS for Heterogeneous Environments.&amp;nbsp; My slide deck from the presentation is available here:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/b/ethomson/archive/2011/04/04/tfs-austin-user-group.aspx"&gt;(Please visit the site to view this file)&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10149830" width="1" height="1"&gt;</content><author><name>Edward A Thomson</name><uri>http://blogs.msdn.com/ethomson_4000_edwardthomson.com/ProfileUrlRedirect.ashx</uri></author><category term="austin" scheme="http://blogs.msdn.com/b/ethomson/archive/tags/austin/" /><category term="cross-platform" scheme="http://blogs.msdn.com/b/ethomson/archive/tags/cross_2D00_platform/" /><category term="tfs" scheme="http://blogs.msdn.com/b/ethomson/archive/tags/tfs/" /><category term="eclipse" scheme="http://blogs.msdn.com/b/ethomson/archive/tags/eclipse/" /><category term="user-group" scheme="http://blogs.msdn.com/b/ethomson/archive/tags/user_2D00_group/" /></entry></feed>