Working with Teams
The Git-TF tool is most easily used by a single developer or multiple developers working independently with their own isolated Git repos. That is, each developer uses Git-TF to clone a local repo where they can then use Git to manage their local development that will eventually be checked in to TFS. In this "hub and spoke" configuration, all code is shared through TFS at the "hub" and each developer using Git becomes a "spoke". Developers looking to collaborate using Git's distributed sharing capabilities will want to work in a specific configuration described below.
Most often, developers collaborating with Git have cloned from a common repo. When it comes time to share divergent changes, conflict resolution is easy because each repository shares the same common base version. Many times, conflicts are automatically resolved. One of the keys to this merging of histories is that each commit is assigned a unique identifier that is generated by the contents of the commit. When working with Git-TF, two repositories cloned from the same TFS path will not have the same commit IDs unless the clones were done at the same point in TFS history, and with the same depth. In the event that two Git repos that were independently cloned using Git-TF share changes directly, the result will be a baseless merge of the repositories and a large number of conflicts. For this reason, it is not recommended that teams using Git-TF ever share changes directly through Git (i.e. using git push
and git pull
Instead, it is recommended that a team working with Git-TF and collaborating with Git do so by designating a single repo as the point of contact with TFS. This configuration may look as follows for a team of three developers:
[TFS] [Shared Git repo]
| ^ (2) | \
| / | \
| / | \
V (1) / V (3) V (4)
[Alice's Repo] [Bob's Repo] [Charlie's Repo]
In the configuration above the actions would be as follows:
- Using the git tf clone command, Alice clones a path from TFS into a local Git repo.
- Next, Alice uses git push to push the commit created in her local Git repo into the team's shared Git repo.
- Bob can then use git clone to clone down the changes that Alice pushed.
- Charlie can also use git clone to clone down the changes that Alice pushed.
Both Bob and Charlie only ever interact with the team's shared Git repo using git push
and git pull
. They can also interact directly with one another's repos (or with Alice's) , but should never use Git-TF commands to interact with TFVC.
When working with the team, Alice will typically develop locally and use git push
and git pull
to share changes with the team. When the team decides they have changes to share with TFS, Alice will use a git tf checkin
to share those changes (typically a git tf checkin --shallow
will be used). Likewise, if there are changes that the team needs from TFVC, Alice will perform a git tf pull
, using the --merge
options as appropriate, and then use git push to share the changes with the team.
Note that (until Issue 77
is addressed) all changes coming into the TFVC repository will come in as if from Alice's TFS identity. This is fine if only Alice has an identity on that TFVC project but it may well not be what you want if Bob and Charlie also had valid identities in that TFS project.
Rebase vs. Merge
Once changes have been fetched from TFS using git tf pull
(or git tf fetch
), those changes must either be merged with the HEAD
or have any changes since the last fetch rebased on top of FETCH_HEAD
. Git-TF allows developers to work in either manner, though if the repo that is sharing changes with TFS has shared any commits with other Git users, then this rebase may result in significant conflicts (see The Perils of Rebasing
). For this reason, it is recommended that any team working in the aforementioned team configuration use git tf pull
with the default --merge
option (or use git merge FETCH_HEAD
to incorporate changes made in TFS after fetching manually).
Recommended Git Settings
When using the Git-TF tools, there are a few recommended settings that should make it easier to work with other developers that are using TFS.
core.autocrlf = false
Git has a feature to allow line endings to be normalized for a repository, and it provides options for how those line endings should be set when files are checked out. TFS does not have any feature to normalize line endings - it stores exactly what is checked in by the user. When using Git-TF, choosing to normalize line endings to Unix-style line endings (LF) will likely result in TFS users (especially those using VS) changing the line endings back to Windows-style line endings (CRLF). As a result, it is recommended to set the core.autocrlf
option to false
, which will keep line endings unchanged in the Git repo.
core.ignorecase = true
TFS does not allow multiple files that differ only in case to exist in the same folder at the same time. Git users working on non-Windows machines could commit files to their repo that differ only in case, and attempting to check in those changes to TFS will result in an error. To avoid these types of errors, the core.ignorecase
option should be set to true