I just released git-tfs v0.11.0.

There are two new commands in this release: bootstrap and verify. bootstrap will find TFS commits and configure git-tfs remotes for you. verify checks that the latest TFS-related commit has the same content as the corresponding version in TFS.

There are a number of bug fixes:

  • Correctly handle the “no newer checkins on the server” case for VS2010. (commit)
  • Work on x86 and x64 more often (commit)
  • Allow checkin policy overrides (commit)
  • Generate a default checkin comment (commit, commit)
  • Ensure consistent casing in the new repository (commit)

You can see the full diff on github.


Today I pushed two new git-tfs goodies: bootstrap, and checkin policy override.

checkin policy override

The checkin policy override support is pretty straightforward. If you try to check in to TFS…

git tfs checkin

…and it fails with some messages about checkin policies (e.g. no associated work items, or the code analysis policy can’t run), you can now override the policy failures. Of course, the best fix is to comply with the policy. For example, if you need to specify an associated work item and provide a checkin comment:

git tfs checkin -w 12345 -m "My awesome code has an awesome checkin comment."

But, if you really need to override the policy failures, you can now do it:

git tfs checkin -f "Policy override because of X" -m "Normal checkin comment."

Of course, you can use checkintool to do all this in a GUI.


The other change was the addition of a bootstrap command. This is useful if you create a TFS clone and share it with a colleague who then needs to interact with TFS. While two identical invocations of git tfs clone will produce identical repositories, git clone is always going to be faster than git tfs clone. So, I would guess that most people who want to collaborate on a TFS project using git will benefit from this command.

The old workflow for this was:

[user1] git tfs clone http://blah/blah/blah $/blah
[user1] cd blah
[user1] git remote add shared git@someplace:shared/repo.git
[user1] git push shared master
[user2] git clone git@somplace:shared/repo.git
[user2] cd repo
[user2] git tfs init http://blah/blah/blah $/blah

At this point, the users can collaborate with each other using git, and they can both do TFS checkin or fetch. For the best workflow, both users need to type in the exact same path. An extra ‘/’ or a capitalization change will keep git-tfs from matching up the TFS remotes, and it will refetch things it doesn’t need to.

So, the bootstrap command replaces the last ‘git tfs init’:

[user2] git tfs bootstrap

This will scan HEAD’s history for checkins with TFS metadata, and configure one or more TFS remotes to match. If you already have the remotes configured, it will just tell you what it found.

The other day, I added experimental support for checkin directly from git-tfs to tfs. (Nate added an interactive version of checkin, too.) It doesn’t feel quite complete yet, and I haven’t decided which way to take it.

The main thing that’s missing is a way to tie the TFS checkin to the git branch. There are a few options that I’ve come up with for how to do this: dcommit, merge in TFS, or merge back to the git branch.

Dcommit would be similar to dcommit in git-svn, where the git commits are checked in to TFS one at a time, effectively rebasing the git branch onto the end of the TFS branch.

Merging in TFS doesn’t mean letting TFS do merges, but rather it means that git tfs checkin would fetch up to the new TFS commit, and give it two parents.

T1 --- T2 --- T3 --- X
   \                /
     G1 --- G2 -- G3

T1 is the base TFS changeset. G* are commits in git. T2 and T3 are commits made in TFS before the git branch is checked in to TFS. X is the TFS changeset created by git-tfs, with parents T3 and G3.

Merging back to the git branch is similar to merging in TFS, but with the merge commit in a different place:

T1 --- T2 --- T3 --- T4
   \                    \
     G1 --- G2 --- G3 -- X

Here, T4 is the new changeset created by git-tfs, and a merge commit is created with G3’s tree and parents G3 and T4.

The thing I like about dcommit is that it captures everything, if you want. It seems like it would be potentially problematic, in that it would be pretty slow and more error prone. Like rebase, it removes commits from history, which I’m a little wary of. Merging on the TFS branch is conceptually very nice, but it breaks the ability to refetch the exact same TFS history (given the same clone configuration). It also might not be as convenient for managing a git master that parallels the TFS mainline, because the merge won’t be available on the git branch. I’m not very well-versed in the mechanics of git’s merging awesomeness, so this might be a moot point, but it seems like the “merge in git” option would provide a better workflow.

If you have any thoughts, please leave a comment. I’m open to suggestions.

I built version 0.9.1 of git-tfs today. The notable changes are

  1. It should work seamlessly with the TFS client libs that come with VS2008 and VS2010.
  2. It has a new “quick-clone” command.

The quick-clone command is used exactly like clone. The difference is that, while clone will chug for hours trying to get an exact replica of all of the changesets in the TFS repository, quick-clone will just grab a snapshot from TFS.

Look for it on the downloads page at github.