git-tf - simple two-way bridge between TFS and Git
- Synchronizes Git commits with TFS changesets and vice versa.
- One-to-one changeset-commit correspondence.
- Works transparently. Other TFS users may not even know that you use Git.
- TFS Workitem support:
git tf wi.
- Displays TFS-styled history with changeset numbers instead of commit hashes:
git tf log.
New features are implemented in the
Here is the typical git-tf usage workflow:
You work in the master branch offline as you normally do with a local git repository. You can stash, rebase, make local branches, bisect, etc. No need to checkout a file before editing.
If a commit is associated with a TFS workitem, you use
wicommand to mark the commit:
$ git tf wi 1234
This marks the HEAD commit with the workitem 1234.
When you are ready to sync with the server, you first
$ git tf pull
This retrieves each TFS changeset individually and commits them into the tfs branch. Each commit is marked with a changeset number.
If you used
git rebaseyour changes instead of merging. It is important, see below.
pushyour local changes to TFS
$ git tf push
This sends each of your pending commits to TFS individually. If a commit was associated with workitems, then the created changeset is associated with them automatically.
To see the list of pending commits use
$ git tf statuswhile you are on master branch.
How it works
The tfs branch points to the git commit in the master branch that is last synchronized with TFS. In some sense tfs branch is analogous to origin.
Each git commit synchronized with TFS has a git note in the tf namespace. Each note has a TFS changeset number. To see the notes run
$ git log --notes=tf
Associated workitems IDs are stored in the tf.wi note namespace.
The commit pointed by tfs branch must always have a note. Without it git-tf won't be able to sync.
push commands move the tfs branch.
Download the files and make sure that git-tf is in the PATH variable. I usually have only a symbolic link to git-tf in the PATH variable and I recommend doing it this way. Also make sure that git-tf files have the execution permission.
Normally you don't execute none of git-tf files directly. You access git-tf by calling
$ git tf <command>
Team Explorer Anywhere installation
Team Explorer Anywhere is a cross-platform client for TFS.
Once it is installed, you have to accept their EULA:
$ tf eula -accept
It is a paid product, but you can use it for 180 days:
$ tf productkey -trial
The product key is stored at ~/.microsoft/Team Explorer/10.0/
Skip this section if you have already mapped a TFS server folder to a local folder.
Configure a profile.
$ tf profile -new myProfile \ -string:serverUrl=http://tfs01.xyz.example.com \ -string:userName=john \ -string:userDomain=company \ -string:password=password \ -boolean:acceptUntrustedCertificates=true
Make sure that acceptUntrustedCertificates is set to true if you have a secure connection (https).
Create a workspace.
$ tf workspace -new -profile:myProfile -collection:http://tfs01.xyz.example.com MyWorkspace
Map a server folder to a local folder:
$ tf workfold -map -workspace:MyWorkspace $/MyProject/Main ~/projects/myProject
Cloning a TFS repository
Once you have a local folder mapped to a server folder, you can use
$ git tf clone -e yourName@tfsServer.com --all
This will import the entire change history from TFS to Git. Be patient. TFS works way slower than Git.
###Changesets to fetch
There are four ways to specify what changesets to fetch:
- By default only the latest changeset is fetched
--alloption: fetch the entire TFS history
--numberoption: fetch a specified number of changesets
--versionoption: fetch changesets since the specified version
Since the majority of TFS users are on Windows, the
core.autocrlf is set to true by default.
To change that set
tf.clone.autocrlf config value to false globally before cloning:
$ git config --global tf.clone.autocrlf false
DO NOT MERGE
git merge tfs on master if you have used
pull. You should always
# on branch master $ git rebase tfs
rebase is like
merge, but instead of applying their changes on
your changes, it applies your changes on their changes.
If you use
merge, you will screw your TFS history up when you
your team won't be happy.