- 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 dev
branch.
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
wi
command 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
fetch
orpull
changes.$ 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
fetch
, thengit rebase
your changes instead of merging. It is important, see below. -
Then you
push
your 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 status
while you are on master branch.
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.
fetch
, pull
and 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 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
Once you have a local folder mapped to a server folder, you can use clone
:
$ git tf clone -e [email protected] --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
--all
option: fetch the entire TFS history--number
option: fetch a specified number of changesets--version
option: fetch changesets since the specified version
###Line endings
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
Never use git merge tfs
on master if you have used fetch
instead
of pull
. You should always rebase
:
# 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 push
and
your team won't be happy.
...is here