clement13.net
Photo d’origine : Aiguillage ferroviaire vu de près, où la voie se sépare en deux.
Description
Aiguillage ferroviaire vu de près, où la voie se sépare en deux.
Source
Xunil · page d’origine
Licence
PD Domaine public
Photo d’origine, non retouchée. L’arrière-plan en est une version stylisée par le site.

Git contre TFVC : comparer, migrer, faire coexister

Comparer Git et TFVC de façon notée et contextualisée, sans dogme.

Guide≈ 13 min de lectureVérifié en partieContrôle partielLes faits principaux ont été contrôlés par recherche dans des sources citées. Les éléments ci-dessous restent à recontrôler avant de s’y fier.À recontrôler
  • Notes /5, durées de migration et scénarios : appréciations d'expert, sans source possible (déjà présentées comme telles).
  • TFVC insensible à la casse des chemins : comportement connu mais non retrouvé dans une source primaire.
Rédaction assistée par IA ; sources citées en bas de page. Une erreur ? Signalez-la via le site clement13.net.
Lecture
En bref
  • Comparer Git et TFVC de façon notée et contextualisée, sans dogme.
  • Choisir selon des scénarios (équipe, dépôt, contraintes de droits, binaires, audit, CI).
  • Connaître les voies de migration TFVC → Git avec ou sans historique, les outils (git-tfs, git-tf, import Azure DevOps) et leurs limites.
  • Décrire la coexistence d'un dépôt Git local au-dessus d'un TFVC officiel, et ses risques.
  • Disposer d'un plan de migration par étapes et d'une liste de pièges.

Prérequis : Git en profondeur, TFVC en profondeur.

Sur cette page

Niveau : 🟡→🔴

Deux philosophies#

🟡 Niveau pratique

Dimension TFVC Git
Architecture Centralisée : serveur de vérité Distribuée : dépôt complet partout
Unité d'enregistrement Changeset serveur Commit local (puis push)
Identifiant Numéro séquentiel Hachage
Branche Dossier serveur (objet lourd, coordonné) Pointeur léger
Verrouillage Possible (checkout lock) Pas natif (verrouillage de fichiers via Git LFS)
Revue de code Revue Visual Studio, shelvesets Pull requests, politiques de branche
Droits Par chemin (jusqu'au fichier) Par dépôt ou par branche

TFVC raisonne « le serveur sait » ; Git raisonne « l'historique est un graphe que chacun possède ». Ce renversement explique la plupart des difficultés de passage : plus de checkout, un commit n'est pas un check-in, la branche devient banale, l'historique est modifiable localement.

Équivalences de vocabulaire et de gestes#

🟡 Niveau pratique

Geste TFVC (tf) Git
Récupérer tf get git pull (= fetch + merge/rebase)
Éditer tf checkout (workspace serveur) rien : on édite
Enregistrer tf checkin git add + git commit puis git push
Annuler tf undo git restore / git reset
Historique tf history git log
Mise de côté tf shelve git stash (local) ou branche poussée
Branche tf branch git switch -c
Fusionner tf merge git merge / git rebase
Étiquette tf label git tag
Ignorer .tfignore .gitignore
Qui a modifié Annoter (Visual Studio ; pas de commande tf) git blame
Lier à un ticket Boîte de dialogue d'archivage (Visual Studio), ou tf checkin -associate:123 (client Team Explorer Everywhere) #123 dans le message (Azure Repos), AB#123 (GitHub relié à Azure Boards), ou lien en PR
💡 Astuce d'expert

Le piège mental n°1 : « un commit n'est pas un check-in ». Un check-in publie ; un commit est une sauvegarde locale. Rien n'est partagé tant qu'on n'a pas fait git push. Enseignez donc deux rituels distincts.

Comparatif noté#

🟡 Niveau pratique

Notes /5 d'expert. Contexte : équipe de 5 à 30 développeurs, projet SQL + Power BI + scripts, dépôt de quelques Go, Azure DevOps (Server ou Services), livraisons par versions produit. Appréciations contextuelles (voir NOTATION).

Critère Git TFVC Justification
Courbe d'apprentissage 2/5 4/5 Git expose index, rebase, HEAD ; TFVC est linéaire
Performance sur gros dépôts 3/5 4/5 Git : partial clone/Scalar nécessaires ; TFVC : mapping partiel
Branches / fusions 5/5 3/5 Branches triviales, fusion par graphe vs branche = dossier
Traçabilité / audit 4/5 4/5 Commits signables / changesets numérotés et liés aux work items
Granularité des droits 2/5 5/5 Chemin vs dépôt
Fichiers binaires / volumineux 2/5 4/5 LFS requis vs natif
Intégration CI/CD 5/5 3/5 Pipelines YAML déclenchés par PR vs builds classiques
Revue de code 5/5 2/5 Pull requests et politiques vs revue ponctuelle
Adéquation SQL/BI 4/5 3/5 Diff et fusion de TMDL/JSON par PR vs sans revue structurée
Travail hors ligne 5/5 2/5 Dépôt complet vs dépendance serveur
Pérennité de l'écosystème 5/5 2/5 Investissement vs « feature complete »
Disponibilité de compétences 5/5 2/5 Marché de l'emploi, formation
Coût de transition n/a n/a Voir plan de migration

Lecture : Git l'emporte nettement sur les axes « écosystème » (CI, revue, IA, recrutement, pérennité) ; TFVC garde l'avantage sur droits par chemin, binaires, simplicité. Aucun des deux ne gagne partout, et une note moyenne serait trompeuse : pondérez par vos contraintes.

Scénarios#

🟡 Niveau pratique

Scénario Recommandation Pourquoi
Nouveau projet data/BI en 2026 Git Défaut Microsoft, écosystème, PBIP/TMDL texte
Équipe 8 personnes, dépôt TFVC stable, livraisons par kit, peu de CI Rester TFVC, préparer l'avenir (coexistence, policies migrées) Pas de gain immédiat suffisant
Équipe 25 personnes, besoin de revues systématiques et pipeline de validation Migrer vers Git PR et policies de branche
Sous-traitants à droits restreints par dossier TFVC, ou plusieurs dépôts Git Droits par chemin vs découpage
Énormes binaires (assets, bases d'exemple) TFVC/Perforce, ou Git + LFS discipliné Coût de stockage/clone
Historique réglementaire à conserver 10 ans TFVC conservé en lecture + Git pour la suite Garder l'archive sans migration risquée
Maintien de 4 versions produit en parallèle Git (branches de release) ou TFVC (dossiers de release) Voir 05
Formation de juniors, recrutement Git Compétence attendue
Dépendance forte à Visual Studio et au « tout Microsoft sur site » Git sur Azure DevOps Server Même plateforme, autre moteur

Faut-il migrer#

🔴 Niveau expert

Migrer a un coût : formation, outillage, risques sur l'historique et les liens work items, rupture de l'habitude. Les déclencheurs légitimes :

  1. Besoin de revue de code outillée (pull requests, politiques) pour élever la qualité.
  2. Besoin de CI/CD moderne sur chaque changement.
  3. Pérennité : sortie d'un moteur gelé (voir 03).
  4. Recrutement et montée en compétence.
  5. Usage de l'IA de développement native aux plateformes Git.
  6. Besoin de branches par tâche à faible coût.

Non-déclencheurs : « Git, c'est la mode », « les autres le font », un seul dev gêné par une commande. Mesurez : fréquence des conflits, durée de revue, lead time de livraison, onboarding. Une équipe sans pratique de revue sous TFVC n'en aura pas davantage sous Git.

⚠️ Piège

Migrer l'outil sans migrer les pratiques : on obtient TFVC en pire (commits géants, force-push, branches éternelles). Prévoyez formation, conventions de branches (05) et protections.

Options de migration#

🔴 Niveau expert

Option Description Historique Effort Risque
Tip migration (instantané) Importer la dernière version dans un nouveau dépôt Git ; l'ancien TFVC est conservé en lecture seule Aucun (ou référence au changeset d'origine) 1/5 Faible : perte d'historique accessible, mais archivé
Migration avec historique Rejouer les changesets en commits Complet (ou N derniers mois) 3-4/5 Moyen : mappage des auteurs, branches, renommages
Migration partielle Importer certaines branches/dossiers seulement Sélectif 2-3/5 Moyen
Approche hybride TFVC archive en lecture ; Git démarre à un changeset donné Les deux séparés 2/5 Faible, mais deux sources à connaître

Microsoft recommande la migration « tip », avec au plus un historique limité (l'outil d'import natif plafonne à 180 jours) : l'historique complet est difficile à rejouer fidèlement et peu consulté.

✅ Bonne pratique

Conservez le dépôt TFVC en lecture seule pendant la période réglementaire ; placez dans le premier commit Git une référence (« importé depuis TFVC $/Projet/Main, changeset 45815 »), et dans les notes de version les correspondances de numéros.

Points structurants à décider :

  • Branches : une branche TFVC = un dossier ; les branches mortes sont à ignorer. Souvent on migre Main + les branches de release vivantes.
  • Auteurs : table de correspondance DOMAINE\nom → Nom <email>.
  • Work items : les liens vers changesets deviennent obsolètes ; on peut conserver les numéros dans les messages de commit migrés pour la recherche.
  • Labels : deviennent des tags (si importés) ; vérifiez qu'ils ne mélangent pas des versions.
  • Fichiers volumineux : à trier (LFS ? sortir du dépôt ?).
  • Encodages/fins de ligne : normalisez avant l'import (06) ; sinon l'historique entier est « modifié » au premier commit de normalisation.

Outils#

🔴 Niveau expert

Outil Nature Atouts Limites
Import Git Azure DevOps (Repos > Importer) Fonction native de la plateforme, option « Migrate history » Aucun outil à installer ; instantané ou N jours d'historique ; adapté au « tip » Historique plafonné à 180 jours ; dépôt importé limité à 1 Go ; une seule branche (ou la racine) par import
git-tfs (projet communautaire) Pont bidirectionnel git tfs clone/fetch/checkin Historique complet, travail en Git local avec check-in TFVC, branches Dépend du client TFVC installé (Team Explorer ou Visual Studio) ; plus activement maintenu ; Windows
git-tf (Microsoft) Outil Java historique de Microsoft Clone TFVC → Git Aucune nouvelle version depuis 2013 (dernière version 2.0.3, prévue pour TFS 2010 à 2013) ; à éviter pour de nouveaux projets
Scripts maison (tf history → git fast-import) Conversion sur mesure Contrôle total (mappage, filtrage, normalisation) Effort, maintenance ; réservé aux cas particuliers
Outils commerciaux (ex. offres d'éditeurs de migration) Services/outils tiers Support Coût ; évaluer sur pilote

Exemple d'usage de git-tfs (poste Windows, Visual Studio/Team Explorer installé) :

# Historique complet d'une branche
git tfs clone https://tfs.exemple.local/tfs/Collection $/Projet/Main D:\Migration\Main --branches=none
# Historique partiel : à partir d'un changeset
git tfs clone https://tfs.exemple.local/tfs/Collection $/Projet/Main D:\Migration\Main --changeset=45000
# Auteurs
git tfs clone ... --authors=auteurs.txt
# Nettoyage avant publication : retirer les métadonnées git-tfs-id si non souhaitées
git filter-repo --message-callback "..."   # selon besoins
git remote add origin https://dev.azure.com/org/projet/_git/mon-produit
git push -u origin --all
⚠️ Piège

Limites de la fonction d'import native : historique limité à 180 jours, dépôt importé limité à 1 Go, une seule branche par import. Symptôme : import refusé pour dépôt trop volumineux (ou historique tronqué). Cause : limites de la fonctionnalité. Remède : nettoyer et réduire d'abord, ou utiliser git-tfs, ou migrer en « tip ».

Coexistence git local et TFVC officiel#

🔴 Niveau expert

Situation courante : l'organisation impose TFVC comme archive officielle (builds, audit), mais l'équipe veut les bénéfices de Git à son échelle : commits fréquents, branches, stash, bisect, blame, outils IA. Solution pragmatique : un dépôt git local sans remote dans le même dossier que le workspace TFVC.

Fonctionnement :

  • On travaille et on commit en Git local pendant la journée (commits atomiques, historique fin).
  • Aux jalons (fin de chantier, fin de journée), on archive en TFVC : tf add des nouveaux fichiers, tf checkin avec lien vers le work item.
  • Les deux historiques coexistent : Git est le brouillon fin, TFVC la vérité officielle.

Règles pour que ça tienne :

  1. Deux listes d'exclusion alignées : .gitignore et .tfignore ; un fichier ignoré par l'un doit l'être par l'autre (sauf cas délibéré). Voir 03.
  2. Dossier .git exclu de TFVC (ne jamais l'ajouter au contrôle de source) et fichiers TFVC internes ($tf, .tf) exclus de Git.
  3. Fins de ligne et encodage normalisés de la même manière des deux côtés (.gitattributes + convention TFVC), sinon chaque aller-retour provoque des diffs parasites.
  4. Dates et auteurs : le commit TFVC ne reprend pas l'historique Git ; conservez des commentaires de check-in porteurs de sens, car ils sont ce que verra l'audit.
  5. Droit de lecture seule en workspace TFVC : en workspace serveur, après tf get, les fichiers sont en lecture seule et il faut un tf checkout préalable avant que Git ne les modifie. En workspace local, les fichiers restent modifiables : les éditions sont détectées automatiquement, et tf reconcile /promote transforme les ajouts/suppressions faits hors de Visual Studio en modifications en attente.
  6. Un seul sens d'écriture : ne jamais « synchroniser » TFVC → Git → TFVC automatiquement sans règle ; le plus sûr est tf get puis git add -A && git commit (« ce que TFVC m'a livré »), puis le travail, puis check-in.
Critère Note /5 Justification
Gain de confort quotidien 4/5 Commits locaux, stash, bisect
Risque de divergence entre les deux 3/5 Dépend de la discipline
Valeur pour une migration future 4/5 Historique Git fin déjà disponible, mais local
Sauvegarde 2/5 L'historique Git local n'existe qu'à un endroit : sauvegarde du poste ou dépôt miroir interne
⚠️ Piège

Le dépôt Git local sans remote n'est sauvegardé nulle part : perte du disque = perte des commits fins. Remède : git bundle régulier ou miroir vers un dépôt interne privé (hors TFS) ; ou simplement archiver le dossier .git.

🧪 Exemple BI

Un correctif sur une procédure de consolidation : trois commits Git locaux (« correction jointure », « ajout contrôle », « test partiel ») puis un changeset TFVC lié à la tâche : « Correctif consolidation couverture ». L'audit voit un changeset net ; le développeur garde la granularité fine pour bisect si la régression revient.

Plan de migration par étapes#

🔴 Niveau expert

Plan type pour une équipe de 10-20 personnes, sur 6 à 12 semaines (ordre de grandeur, dépend de la taille et de la préparation) :

1 Cadrer2 Préparer3 Pilote4 Former5 Basculer6 Consolider
Survolez ou touchez un élément pour en lire le détail.

1. Cadrer (1 semaine) — Décider : migrer quoi (Main seule ? + releases ?), avec quel historique, pour quels bénéfices mesurables. Inventaire : taille de la collection, fichiers volumineux, branches vivantes, policies, builds, liens work items. Sponsor identifié.

2. Préparer (2-3 semaines) — Nettoyer le dépôt (binaires, caches, doublons). Normaliser encodages et fins de ligne. Rédiger .gitattributes, .gitignore, conventions de branches et de messages, politiques de branche (PR, build de validation). Établir la table des auteurs. Sécuriser les droits (groupes, dépôts découpés si droits par dossier).

3. Pilote (2 semaines) — Migrer un périmètre non critique (ou une copie du réel) avec l'outil retenu ; comparer le contenu au changeset de référence (liste de fichiers + sommes de contrôle) pour prouver la fidélité ; rejouer une livraison complète (kit installable) depuis le dépôt Git ; mesurer clone, status, build.

4. Former (en continu) — 1 session pratique de 3 h : modèle objet simplifié, cycle quotidien, PR, résolution de conflits ; fiche aide-mémoire TFVC→Git (équivalences) ; « champion Git » par équipe.

5. Basculer (1 week-end ou 1 journée calme) — Geler TFVC (droits en lecture seule), migration finale, vérification (fichiers, tags, quelques fichiers sensibles ouverts à la main), mise à jour des pipelines, hooks, documentation, liens. Communication claire : « à partir de lundi, on commit ici ».

6. Consolider (4 semaines) — Support rapproché, rétrospective, métriques (conflits, durée de revue, lead time), suppression des anciens workspaces, archivage TFVC (lecture seule, conservé).

Critères de réussite : toutes les versions produit en cours reconstructibles depuis Git ; pipeline de build vert ; plus personne ne commit en TFVC ; équipe autonome sur les opérations courantes.

✅ Bonne pratique

Prévoyez un retour arrière : tant que TFVC n'est pas figé, la migration est réversible ; après le gel, gardez la source TFVC intacte 3 à 6 mois.

Pièges de migration#

🔴 Niveau expert

Piège Symptôme Cause Remède
Normalisation tardive Premier commit Git « modifie tout » Encodage/fins de ligne non unifiés Normaliser avant, ou isoler dans un commit dédié
Accents corrompus « é » dans libellés Fichiers UTF-8 relus en ANSI, ou BOM perdu Contrôle automatisé des octets ; voir 06
Historique « fantôme » Ajouts/suppressions bizarres Branche par copie dans TFVC Migrer à partir d'un point propre
Casse des chemins Doublons sous Linux TFVC insensible à la casse Détecter les collisions avant
Liens work items morts Pas de changeset dans la tâche Numéros TFVC perdus Garder les numéros dans les messages
Gros binaires oubliés Clone de plusieurs Go Historique complet importé LFS, filtres, ou tip
Équipe en mode « TFVC dans Git » Force-push, commits géants Pas de formation Protections de branche + formation
Pipelines non adaptés Builds cassés Déclencheurs TFVC Réécrire en YAML, tester sur branche
Droits par dossier perdus Sous-traitant voit tout Git ne les gère pas Dépôts séparés
Oubli des scripts internes Outil d'archivage appelle tf Dépendances cachées Inventaire des scripts (PowerShell, hooks, builds)

Contribution de l'IA#

🤖 IA

Utile à plusieurs étapes d'une migration, dangereuse si on délègue le jugement.

Cas d'usage Gain Risque Maturité Prérequis Garde-fous
Générer la table de correspondance auteurs depuis tf history 3/5 2/5 4/5 Export tf history Validation RH/propriétaire
Écrire les scripts de conversion/contrôle (comparaison arborescences, sommes) 4/5 3/5 4/5 Spécification claire Pilote sur copie, comparaison systématique
Rédiger .gitattributes / .gitignore 4/5 2/5 4/5 Liste des types de fichiers Tester sur échantillon (accents, CRLF)
Générer la fiche TFVC→Git et le support de formation 4/5 1/5 4/5 Contexte d'équipe Relecture technique
Expliquer un historique converti, détecter des anomalies 3/5 3/5 3/5 Extraits ciblés Ne pas conclure sans vérification dans l'outil
Revue de code assistée après bascule 3/5 3/5 3/5 Politiques de PR L'humain reste le relecteur responsable

Prompt type : « Voici un extrait de tf history détaillé. Produis un CSV compte_tfs;nom;email sans inventer d'adresse : laisse vide si inconnue. » L'IA ne remplace ni la décision de migrer, ni la vérification de fidélité (sommes de contrôle), ni la responsabilité sur la conformité de l'archive. Voir IA et outils.

Voir aussi#

✻ Rédigé par Claude Sonnet 5.5