Git-Tfs - Exclude certain branches from migration
Dec 31, 2016 · 4 minute read · Commentsgittfssource controlgit-tfs
The time to migrate from your TFVC repository to GIT has come. Great! The process is quite straightforward. You can get all your source control history recreated in GIT using Git-Tfs. The tool can even include the changesets from the branches that has already been merged. But, what if the process fails on the specific merge changeset or you want to skip some of the branches?
Prerequisites
Get the Git-Tfs tool and make sure that it is in your PATH
.
Process
Let’s assume that we need to migrate from a TFS repository to GIT. The repository contains the Main branch with the following history.
Changeset Description
----------------------------------
39 Merge Branch6 to Main
34 Merge Branch5 to Main
29 Merge Branch4 to Main
24 Merge Branch3 to Main
20 Merge Branch2 to Main
10 Merge Branch1 to Main
5 Create Main folder
As you can see there are several branches that have been merged to Main. The resulting GIT repository needs to contain all the intermediate changesets from these branches. There should be a merge commit for every branch that was integrated.
Migrate from TFS to GIT with branches history
To perform the migration we need to invoke Git-Tfs clone command.
It initializes a new Git repository from a TFS repository.
The command allows to pass the branches
parameter, which specifies the strategy to manage branches.
--branches=VALUE Strategy to manage branches:
* none: Ignore branches and merge changesets,
fetching only the clone tfs path
* auto:(default) Manage merged changesets and
initialize the merged branches
* all: Manage merged changesets and initialize
all the branches during the clone
To get the full history we’d need to set the strategy to auto
. The following command creates the GIT repository with all the merged branches.
git tfs clone <TFS_URL> <REPOSITORY_PATH> . --branches=auto --resumable
Skip the selected merged branches
What if we need to exclude some of the branches - ignore the intermediate changes made in the branch.
There is no parameter in Git-Tfs that would allow to specify which branches to skip. It’s either everything that was merged or nothing. But, it is possible to achieve the desired outcome by following the steps below.
Steps
Let’s assume that we want to exclude the branch history of the Branch4
. By looking at the source control history we can see that the branch was merged as part of the changeset 29
.
First we need to clone the repository up to the changeset before the merge. The
clone
command allows to pass thechangeset id
, which causes the clone operation to skip all the further changesets after the one specified:-t, --up-to=VALUE up-to changeset # (optional, -1 for up to maximum, must be a number, not prefixed with C)
So, we need to invoke the clone command with the
changeset id
prior to thechangeset 29
.git tfs clone <TFS_URL> <REPOSITORY_PATH> . --branches=auto ^ --resumable --up-to=28
Next, we can fetch the merge changeset using different branching strategy -
none
, so that the branch history is not retrieved. Thefetch
command also has the--up-to
parameter, so it’s possible to retrieve just this one changeset.git tfs fetch --branches=none --up-to=29
Then, we can get the rest of the changes. But first, we need to override the Git-Tfs configuration so that the full branch history is retrieved.
When the
fetch
command is executed with the branches strategy set tonone
, Git-Tfs sets thegit-tfs.ignore-branches
flag toTrue
on the repository. So, we need to reset this flag, otherwise the Git-Tfs will ignore other branches.git config git-tfs.ignore-branches False
Once the flag is reset, we can fetch the remaining changesets.
git tfs fetch --branches=auto
The last step is to apply the retrieved changes on the
master
branch.git merge remotes/tfs/default
Result
As you can see below, the Git repository contains the intermediate changes made in the branches, except for the Branch4
.
You can exclude any number of branches using the method described above. But, if you need to skip more than a few, it might be good idea to write a script that would automate the process.