Git for the TFVC User – Workflow Investigations Part 4: Converting a TFVC repository


image_thumb2_thumb_thumb … co-authored with Richard Albrecht, complementing the Version Control (ex Branching and Merging) Guide.

Continued from Part 1 – Making Changes, we would like to share our notes, NOT guidance, and invite you to give us candid feedback on our proposed walkthroughs that are related to the high-level workflow steps mentioned above:



migration thoughts

Loaned from the silent BETA preview and based on findings as outlined in Understanding TFS migrations from on-premises to Visual Studio Online.

We recommend simple ‘tip’ migrations to avoid the cost and complexity of understanding and migrating history, as well as exceptions caused by missing or corrupt history. Avoid potential pitfalls by:

  •  Keeping your old TFVC repository to look at the past.
  •  Keeping your large binary files, for example videos, in your old or another TFVC repo.
  •  Re-evaluating your branching strategy and do not migrate your TFVC branches to Git.

Why not?

  •  Migrations are complex, expensive and hard to plan and implement effectively.
  •  Migrations are plagued with edge cases.
  •  Our experience shows that no solution will move your data with full fidelity.



walkthrough 4 – converting a TFVC repository

This walkthrough is based on from-the-field findings and conflicts, in places, with the recommendations. For example migration of history or TFVC branches to Git is not recommended, but covered as the migration needed to be done in the associated evaluation environment. Remember, we are looking for candid feedback, not sharing guidance!

TFVC history

When migrating the full history, which is not a recommended scenario, consider the following steps:

Step

Instructions

1
Create new Team Project

꙱ - Done

  • Create a new TFS Team Project, selecting Git as the source control type.
  • Preferably use the same process template for the new Team Project, if you plan to migrate the work items to avoid complex field mappings.

2
Clone the TFVC repo

꙱ - Done

  • Get the latest version of your source code from the team project using the Git-TFS --all option, which copies all of the TFVC change sets for a given Team Project.
  • Example:
    git tfs clone https://account.visualstudio.com/defaultcollection
    “$/Test Project” d:\MyRepo --all
    Initialized empty Git repository in D:/Projects/GitProjects/Test Project Git/All/.git/
    info: no TFS root found !
    PS:perhaps you should convert your trunk folder into a branch in TFS.
    Fetching from TFS remote 'default'...
    C6 = 22e24eb05f464ae0ba337502124728e205a0d75c
    C7 = ed50ac6ead447bc40832f2155e8e38ad19572498
    C8 = 7ae15b1f036f7ba4aa08812d295b750dd6ce8fa0

    NOTE

    · To migrate only X number of revisions use the Git-TF tool with the –depth <num> option.  This option allows the user to specify how many revisions back to clone in the new Git repository.

    · If one is looking to clone changesets based on date range that option does not exist in these tools.

3
Deal with cloning errors

꙱ - Done

  • With large TFVC repositories the Git-TFS tool can fail to complete the cloning. Resolve such errors with a fetch command should get the rest of the source code.
    git tfs fetch –all
  • If the TFVC repo contains branches the Git-TFS tool will not create corresponding Git branches and you may get an error message about broken references during the cloning process. See TFVC Branches, as below, when you need to migrate branches.

4
Cleanup code

꙱ - Done

  • Review, modify and cleanup the code and directory structure.

5
Associate and Push changes to Git repo

꙱ - Done

  • Associate the local repo with the Team Project.
    Example:
  • git remote add baseline
    http://tfs2013sa:8080/tfs/defaultcollection/_git/Test Branches Git
  • Push the local repository to a centralized TFS Git repository.
    Example:
    git push –u baseline –all

6
Review migration

꙱ - Done

  • Verify that the latest code has been migrated to the centralized TFS Git repository.

TFVC tip only

When migrating the tip (latest history), consider the following steps:

Step

Instructions

1
Create new Team Project

꙱ - Done

  • Create a new TFS Team Project, selecting Git as the source control type.
  • Preferably use the same process template for the new Team Project, if you plan to migrate the work items to avoid complex field mappings.

2
Clone the TFVC repo

꙱ - Done

  • Get the latest version of your source code from TFVC using the Git-TFS quick-clone command.
  • The Git-TFS quick-clone command will only clone the last change set done, i.e. the tip of your current code.
    Example:
    git tfs quick-clone https://account.visualstudio.com/defaultcollection
    “$/Test Project” d:\MyRepo

3
Cleanup code

꙱ - Done

  • Review, modify and cleanup the code and directory structure.

4
Associate and Push changes to Git repo

꙱ - Done

  • · Associate the local repo with the Team Project.
    Example:
    git remote add baseline
    http://tfs2013sa:8080/tfs/defaultcollection/_git/Test Branches Git
  • Push the local repository to a centralized TFS Git repository.
    Example:
    git push –u baseline –all

5
Review migration

꙱ - Done

  • Verify that the latest code has been migrated to the centralized TFS Git repository.

TFVC branches

When migrating TFVC branches, consider the following steps:

Step

Instructions

1
Review the Branch topology

꙱ - Done

  • Remember that implementation and concepts of branches in TFVC and Git are different.
  • Do not simply replicate your TFVC branch topology in Git.
  • Use the Git-TFS tool and the list-remote-branches option to get a list of branches to consider.
  • Cleanup or select the essential branches.

2
Clone repository

꙱ - Done

  • Clone the TFVC repo using the Git-TFS tool and the --with-branches option.
  • The option will create all of the branches during the cloning process.
  • Example to clone $/TestBranches/main and related branches:
    git tfs clone --with-branches http://tfs2013sa:8080/tfs/defaultcollection "$/TestBranches/main" "D:\Projects\GitProjects\Test Branches Git\All Branches"
    Initialized empty Git repository in D:/Projects/GitProjects/Test Branches Git/All Branches/.git/
    Fetching from TFS remote 'default'...
    C10 = f196b079bb789cfc307f8faf31005f19bdd6c353
    C11 = d30182afbfadd4fabb385175f4ea392d75241c7f
    Tfs branches found:
    - $/TestBranches/Dev
    - $/TestBranches/Release1
    The name of the local branch will be : Dev
    C12 = df09b9c5d4e9c49e3ebd74ffa191895f6d1ca6b2
    C13 = c8864732582df703f87466dfb6046bca8c46309e
    The name of the local branch will be : Release1
    C14 = 6fe85f13de18a1edcb20f3ed9f84c1afa74fd294

3
Associate and Push changes

꙱ - Done

  • Associate the local repo with the Team Project.
    Example:
    git remote add baseline2
    http://tfs2013sa:8080/tfs/defaultcollection/_git/Test Branches Git
  • Push the local repository to a centralized TFS Git repository.
  • Git will automatically create the associated Git branches.
    Example:
    git push -u baseline2 --all
    Username for 'http://tfs2013sa:8080':
    Password for 'http://tfs2013sa\*********@tfs2013sa:8080':
    Counting objects: 30, done.
    Delta compression using up to 8 threads.
    Compressing objects: 100% (18/18), done.
    Writing objects: 100% (30/30), 9.08 KiB | 0 bytes/s, done.
    Total 30 (delta 9), reused 30 (delta 9)
    remote: Analyzing objects (30/30) (243 ms)
    remote: Storing pack file and index... done (211 ms)
    To http://192.168.0.130:8080/tfs/defaultcollection/_git/Test Branches Git
    * [new branch] Dev -> Dev
    * [new branch] Release1 -> Release1
    * [new branch] master -> master
    Branch Dev set up to track remote branch Dev from baseline2.
    Branch Release1 set up to track remote branch Release1 from baseline2.
    Branch master set up to track remote branch master from baseline2.

NOTE

There may be a need to trim or collapse branches or history before. See the rebase command Trimming Git Commits/Squashing Git History for more information.

4
Review migration

꙱ - Done

  • Verify that all TFVC branches have been migrated to the centralized TFS Git repository.

Thoughts?

Comments (1)

  1. Philippe says:

    Disclaimer: I am one of the 2 maintainer of git-tfs

    >Get the latest version of your source code from the team project using the Git-TFS –all option, which copies all of the TFVC change sets for a given Team Project.

    The `–all` option is not needed here (just when using `git tfs fetch` when the repository contains more than one tfs remote) and could be removed for a simpler the command line 😉

    > To migrate only X number of revisions use the Git-TF tool with the –depth <num> option.  This option allows the user to specify how many revisions back to clone in the new Git repository.

    You could do that with git-tfs too but in a way more clever (but I admit, hidden 🙁 )

    You must use the command `git tfs quick-clone` but using the option `-c` to specify the changeset you want to clone ( `git tfs quick-clone -c=126`) and once finished, you just have to `fetch` (`git tfs fetch`).

    I find it clever because you choose your commit and not use an arbitrary number –depth=100 (why 100?)

    >migration thoughts : We recommend simple ‘tip’ migrations to avoid the cost and complexity of understanding and migrating history, as well as exceptions caused by missing or corrupt history.

    I partly agree but 2 things in a such way of doing is worrying me…

    1. History is quite important in your daily development job. A thing that generally tfs users didn't understand and do not value enough! But using git, you finish to learn it!! And migrating only the tip cause the problem that you should spend months, not even years before reconstituting a useful history that you could blame, checkout,…. 🙁

    2. When you have a big team of developers using more than one long development branches, how do you do to migrate to git at a given moment without migrating some history and all these branches and just a 'tip', like you suggest? That's seems not very doable…

    >Keeping your large binary files, for example videos, in your old or another TFVC repo.

    I admit that a history coming from TFVC could not be perfect, but a tool like rtyley.github.io/bfg-repo-cleaner could help you to clean it quite easily…

    > Migrations are plagued with edge cases.  Our experience shows that no solution will move your data with full fidelity.

    With git-tfs, I try to… but I agree with you that digging in tfs history and the way tfs store it are such a mess compared to the way git is doing that it's a really difficult task!

    >With large TFVC repositories the Git-TFS tool can fail to complete the cloning. Resolve such errors with a fetch command should get the rest of the source code.

    We indeed have a bug in git-tfs and some objects are kept in memory that cause a crash in really big history. Any contribution by a user that have big repositories on the subject is welcome!

    You could at least mitigate the problem (and perhaps even speed a little your migration) by using the `–batch-size=50` option to tell git-tfs to handle a maximum of 50 changesets (value that you could change) at the same time…

Skip to main content