

- Description
- Livre de comptes ancien ouvert, aux colonnes tracées à la main et aux écritures manuscrites.
- Source
- Daderot · page d’origine
- Licence
- CC0 Domaine public
TFVC en profondeur
Comprendre le modèle de Team Foundation Version Control : serveur central, workspaces, changesets numérotés.
En bref
- Comprendre le modèle de Team Foundation Version Control : serveur central, workspaces, changesets numérotés.
- Maîtriser les objets : shelvesets, labels, branches, merges, check-in policies, gated check-in.
- Utiliser
tf.exeen ligne de commande avec assurance (get,add,checkout,checkin,undo,delete,history,merge,branch,status,workfold) et connaître les pièges (TF203069et consorts). - Connaître les limites, la performance, les droits, et l'état de pérennité de TFVC (état 2026-10).
Sur cette page
- Principes
- Workspaces serveur et locaux
- Changesets
- Shelvesets
- Labels
- Branches et fusions
- Politiques de check-in et gated check-in
- tf.exe en ligne de commande
- Exclusions .tfignore
- Intégration des work items
- Droits et sécurité
- Performance et limites
- Pièges et codes d'erreur
- Pérennité et état du produit
- Contribution de l'IA
- Voir aussi
Niveau : 🟢→🔴
Principes#
🟢 Niveau novice
TFVC est une GDS centralisée : le serveur (collection de projets d'Azure DevOps Server ou organisation Azure DevOps Services) détient l'historique. Chaque enregistrement est un changeset, numéroté séquentiellement pour toute la collection (changeset 45815, par exemple). Le poste ne contient que les fichiers demandés (get) dans un workspace : un lien nom de dossier serveur ↔ dossier local.
Cycle de base :
- Get : récupérer la dernière version.
- Checkout (édition) : signaler qu'on modifie (explicite en workspace serveur, implicite en workspace local).
- Modifier les fichiers.
- Check-in : valider ; crée un changeset atomique, avec commentaire et work items associés.
Trois atouts : numéros de changeset lisibles, droits fins par dossier, et intégration native Visual Studio/work items. Trois limites : dépendance au serveur, branches lourdes en concept (une branche est un dossier), outils de revue et de CI plus pauvres que sur Git.
Workspaces serveur et locaux#
🟡 Niveau pratique
| Aspect | Workspace serveur | Workspace local (défaut moderne) |
|---|---|---|
| Où l'état est connu | Serveur : il sait quels fichiers vous avez | Poste : comparaison locale à la demande |
| Fichiers en lecture seule | Oui, jusqu'au checkout | Non : fichiers modifiables, modifications détectées par comparaison avec la copie en cache |
| Hors ligne | Limité : mode « hors connexion » de Visual Studio, à repasser en ligne ensuite | Possible : tf reconcile ensuite |
| Performance pour très gros dépôts (millions de fichiers) | Meilleure | Se dégrade vers 100 000 éléments (analyse du disque, copies multiples) |
| Verrouillage | lock:checkout possible |
Pas de checkout verrouillant à l'édition |
Choix : un workspace local convient à la plupart des équipes ; le serveur reste pertinent sur des arborescences gigantesques ou pour imposer le verrouillage. Les workspaces sont par machine et par utilisateur (nom du poste + propriétaire).
tf workspace /new MonWS /collection:https://tfs.exemple.local/tfs/Collection /login:... /noprompt
tf workfold /map $/Projet/Main D:\TFS\Main /workspace:MonWS
tf workspaces # liste
tf workspace /delete MonWS;ProprioXX
Un workspace est mappé à un chemin local ; un dossier local ne peut dépendre que d'un workspace. Symptôme : « The path is already mapped in workspace… » (TF400... / TF203...). Remède : tf workspaces, supprimer ou démapper l'ancien (tf workfold /unmap).
Changesets#
🟢 Niveau novice
Un changeset est l'ensemble atomique : fichiers ajoutés/modifiés/supprimés/renommés/fusionnés, commentaire, work items liés, résultats des policies. Il est immuable (le commentaire peut être modifié après coup, pas le contenu). Particularités :
- Numéro global croissant dans la collection : repère naturel pour dater et dire « ce correctif est dans le CS 45643 ».
- Versionnage des renommages et suppressions : TFVC enregistre explicitement les opérations ; l'historique suit un fichier déplacé.
- Spécificateurs de version :
C45643(changeset),D2026-09-16(date),L<label>(label),T(dernière),W(workspace).
Un changeset peut être rattaché à plusieurs work items ; chacun conserve alors un lien vers le même changeset.
Dans un compte rendu de livraison, citez les changesets avec un texte explicite (« CS 45643 – correctif PREBUILD ») : un lien brut est opaque, et c'est ce numéro qui relie code, work item, build et kit.
Shelvesets#
🟡 Niveau pratique
Un shelveset met de côté des modifications sur le serveur, nommées, sans les valider. Usages : sauvegarde intermédiaire, partage pour revue, changement de contexte, build d'essai (builds « shelveset »).
tf shelve MonShelveset /comment:"WIP KPI" /noprompt
tf shelvesets /owner:* # lister
tf unshelve MonShelveset;Proprio # restaurer dans le workspace
tf shelve /delete MonShelveset
Différences avec git stash : un shelveset est nommé, serveur, partageable, visible dans les outils, quand le stash est local et anonyme. Il ne porte pas de graphe de fusion : c'est un instantané de modifications.
Un shelveset n'est pas sauvegardé par le workspace : il l'est avec la base de collection. Mais il s'accumule ; sans politique de nettoyage (suppression des vieux), la base grossit. Les shelvesets contenant des secrets sont lisibles par ceux qui ont le droit de lecture.
Labels#
🟡 Niveau pratique
Un label nomme un ensemble de versions de fichiers (pas forcément cohérent : on peut mélanger des versions). Il sert à marquer une livraison, mais il est mutable : on peut déplacer, ajouter, retirer des éléments d'un label (et à moins de droits adaptés, le supprimer). Contraste avec le tag Git, qui est un pointeur vers un commit atomique.
tf label Livraison_9.1.0 $/Projet/Releases/9.1 /recursive /comment:"Kit 9.1.0"
tf labels /collection:...
tf label /delete Livraison_9.1.0@$/Projet
Pour une livraison, privilégiez le numéro de changeset (immuable) + une branche de release dédiée, plutôt que le label seul. Si vous utilisez un label, notez dans la documentation de livraison le changeset correspondant.
Branches et fusions#
🟡 Niveau pratique
En TFVC, une branche est un dossier serveur déclaré « branche » (objet versionné) : $/Projet/Main → $/Projet/Dev, $/Projet/Releases/9.1. Créer une branche copie logiquement l'arborescence (côté serveur, coûteux seulement en métadonnées). La relation parent/enfant est enregistrée : les fusions ne sont autorisées par défaut que selon cette relation (aval/amont).
tf branch $/Projet/Main $/Projet/Dev /collection:... /comment:"Branche de dev"
tf merge $/Projet/Main $/Projet/Dev /recursive # Main -> Dev (réintégration descendante)
tf merge $/Projet/Dev $/Projet/Main /recursive /version:C45000~C45600 # sélectif par plage de changesets
tf checkin /comment:"Merge Main vers Dev" /noprompt
tf resolve /auto:AutoMerge # résolution automatique
tf resolve fichier /auto:TakeTheirs # TakeTheirs / KeepYours
tf merges $/Projet/Main $/Projet/Dev /recursive # ce qui reste à fusionner
tf history $/Projet/Dev /recursive /format:brief
Le serveur calcule la fusion de deux versions avec leur base commune (en suivant la relation de branche). Les fusions TFVC suivent les changesets : on peut fusionner seulement le changeset 45643, ce qui est puissant (rétro-portage chirurgical) et dangereux (ordre incohérent des changesets partiellement fusionnés).
Fusion sans base (baseless merge) : fusionner entre deux dossiers sans relation de branche déclarée (typiquement un dossier copié plutôt que branché). Option /baseless : sans ancêtre, tout est un conflit potentiel car l'outil n'a pas de base de comparaison. À réserver aux cas d'import ou de reconstruction.
Structure classique (standard Main/Dev/Release) :
$/Projet
├─ Main (code stable, intégration)
├─ Dev
│ ├─ Feature-A (branches de fonctionnalité)
│ └─ Feature-B
└─ Releases
├─ 9.0 (branches de release / maintenance)
└─ 9.1
Règle de flux : les fusions vont de l'enfant au parent (reverse integration) et du parent à l'enfant (forward integration) ; on ne fusionne pas « latéralement » (Release 9.0 → Release 9.1) sauf par Main, sauf baseless. Voir la mise en perspective dans 05.
Une branche par copie de dossier (clic droit « copier » et non « Branch ») donne un dossier sans historique de branche : les fusions suivantes seront baseless. Symptôme : tout est conflit. Remède : convertir en branche (Convert to Branch) tant qu'il n'y a pas eu de divergence, ou recréer proprement.
Politiques de check-in et gated check-in#
🔴 Niveau expert
Check-in policies : règles évaluées côté client au moment du check-in (Visual Studio) : association obligatoire à un work item, commentaire non vide, build propre, analyse de code, notes de check-in. Elles s'activent par projet d'équipe. Limite structurelle : elles s'exécutent chez le client, donc contournables (/override avec justification journalisée).
Gated check-in : le check-in n'est accepté que si un build validant le changement passe. Le serveur crée un shelveset, lance la build, et ne committe qu'en cas de succès. Utile sur un tronc partagé : garantit que Main compile. Coût : latence, file d'attente de builds, contention.
Évolution récente : Microsoft a annoncé en avril 2025 la dépréciation des anciennes check-in policies (stockage et implémentation historiques). Le calendrier prévoit des phases de notification puis un blocage : à l'étape finale, des policies obsolètes non migrées peuvent bloquer tous les check-ins du dépôt. En février 2026, le billet de l'équipe Azure DevOps indiquait la phase II avec appel à retirer ou remplacer les policies obsolètes. À faire : auditer les policies de chaque projet TFVC, supprimer les obsolètes, recréer celles utiles au nouveau format (état 2026-10 ; détail et dates à vérifier sur le blog Azure DevOps).
Symptôme : message de non-conformité des policies à chaque check-in, invisible dans tf.exe. Cause : policies obsolètes stockées sur le serveur. Remède : les retirer via Team Explorer ou l'interface d'administration du projet avant la phase finale de blocage.
tf.exe en ligne de commande#
🟡 Niveau pratique
tf.exe est livré avec Visual Studio (Common7\IDE\CommonExtensions\Microsoft\TeamFoundation\Team Explorer\TF.exe). Il fonctionne en authentification intégrée Windows ou avec /login:. Dans un dossier mappé, la collection est déduite du workspace.
| Commande | Rôle | Exemple |
|---|---|---|
tf get |
Récupérer des versions | tf get $/Projet/Main /recursive ; /force pour re-télécharger ; /version:C45643 ; /preview simule |
tf add |
Ajouter à la source | tf add *.sql /recursive ; /noprompt ; /exclude n'existe pas : passer par .tfignore |
tf checkout (tf edit) |
Marquer pour modification | tf checkout script.sql ; /lock:none |
tf checkin |
Valider | tf checkin /comment:"Message" /associate:12345 /noprompt ; /override:"raison" |
tf undo |
Annuler des modifications en attente | tf undo /recursive * ; tf undo /workspace:MonWS;Proprio * (annule dans un autre workspace) |
tf delete |
Supprimer | tf delete fichier.sql ; /recursive ; /lock:none |
tf rename / tf move |
Renommer/déplacer | tf rename ancien.sql nouveau.sql |
tf status |
Modifications en attente | tf status /recursive /format:detailed |
tf history |
Historique | tf history $/Projet/Main/dossier /recursive /stopafter:20 /format:detailed |
tf diff |
Comparer | tf diff fichier.sql /version:C45000~T |
tf changeset |
Détails d'un changeset | tf changeset 45643 /noprompt |
tf branch / tf merge / tf merges |
Branches, fusions | voir plus haut |
tf workfold |
Mappings du workspace | tf workfold ; /map ; /unmap |
tf workspace / tf workspaces |
Gérer les workspaces | /new, /delete |
tf shelve / tf unshelve |
Shelvesets | voir plus haut |
tf label |
Labels | voir plus haut |
tf reconcile |
Rapprocher modifications hors ligne | tf reconcile /promote /recursive |
tf rollback |
Annuler un changeset | tf rollback /changeset:45643 /recursive |
tf destroy |
Détruire définitivement | tf destroy $/Projet/.../x (irréversible, droits admin) |
Recette de travail typique en ligne de commande :
Set-Location D:\TFS
tf get . /recursive # synchroniser
tf status . /recursive # contrôle avant travail
# ... modifications ...
tf add "Datamart\nouveau script.sql" # nouveaux fichiers
tf checkin . /recursive /comment:"Correctif KPI couverture" /associate:12345 /noprompt
Dans un script d'archivage, lisez le code de sortie : 0 succès, 1 succès partiel, 2 commande non reconnue, 100 aucun succès. Un tf checkin qui n'a « rien à valider » peut renvoyer un code non nul sans que ce soit une erreur : testez d'abord tf status. Protégez les chemins contenant des espaces par des guillemets.
tf add applique les règles de .tfignore quand l'argument contient un caractère générique (/noignore les outrepasse), mais tf add . /recursive sur un dossier contenant bin/, obj/ et des caches non ignorés ajoutera du bruit. Vérifiez tf status avant checkin : c'est la dernière barrière.
Retrouver qui a modifié un script de consolidation depuis la dernière livraison : tf history "$/Projet/Main/Datamart/script.sql" /version:C45000~T /format:detailed. Pour des audits en masse, tf history ... /format:detailed /noprompt redirigé dans un fichier, puis analyse PowerShell.
Exclusions .tfignore#
🟡 Niveau pratique
.tfignore est le pendant TFVC de .gitignore : un fichier texte à la racine d'un dossier mappé, pris en compte par tf add et par Visual Studio (le détecteur de changements ne propose plus les fichiers ignorés). Syntaxe voisine mais séparateur \ et chemin commençant par \ = relatif au dossier du .tfignore ; ! pour réintégrer.
# Exclusions
*.user
*.suo
\bin
\obj
\node_modules
!\bin\keep.dll # exception : forcer l'ajout
Règles à connaître :
.tfignoreest sans effet sur un élément déjà sous contrôle de source. Pour sortir un fichier du contrôle :tf delete(puis check-in), le fichier reste sur disque si on l'a supprimé de la version seulement via workspace local ; attention,tf deletesupprime aussi localement par défaut.- Si une modification est déjà en attente sur l'élément, faire d'abord
tf undo, sinon TF203069 (voir pièges). tf deleterefuse un élément jamais rapatrié dans le workspace (« introuvable dans votre espace de travail ») : faire d'abord untf getde l'élément.- Le
.tfignoredoit être lui-même versionné pour que toute l'équipe ait les mêmes exclusions ; sur un dépôt qui est aussi suivi par Git en local, conservez deux listes alignées (.gitignoreet.tfignore).
Intégration des work items#
🟡 Niveau pratique
TFVC relie nativement changesets et work items : à l'enregistrement, /associate:<id> (ou le panneau Visual Studio) crée le lien Changeset sur le work item, et la résolution éventuelle (/resolve:) peut changer son état. Bénéfices : de la tâche on retrouve le code (et inversement), les builds remontent les changesets inclus, et l'audit de livraison se fait par requête. Avec les branches, l'onglet « Développement » montre la propagation d'un changeset entre branches.
Imposez la policy « work item associé » : sans cela, la traçabilité se perd en quelques semaines. Un changeset peut porter plusieurs tâches, mais évitez le fourre-tout : un changeset par sujet (voir aussi Azure DevOps / TFS en profondeur).
Droits et sécurité#
🔴 Niveau expert
Les permissions TFVC se définissent par chemin serveur (héritage, refus explicite) : Lecture, Check-out, Check-in, Étiquetage, Fusion, Gestion des branches, Verrouillage, Gestion des permissions, gestion des étiquettes, révision des modifications d'autrui… Cette granularité est supérieure à Git (qui se règle au dépôt). Cas d'usage : un sous-traitant ne voit que $/Projet/Releases/9.1/Docs, la production peut seulement lire Releases.
Principes : droits par groupes et non par individus ; refus explicite à réserver aux exceptions (un refus l'emporte) ; auditer périodiquement avec tf permission /collection:... $/Projet /recursive.
Performance et limites#
🔴 Niveau expert
- Points forts : bonne tenue sur très gros arbres (nombreux fichiers), chargement partiel naturel (seulement les dossiers mappés), binaires volumineux gérés sans extension.
- Points faibles :
statuslent en workspace local sur des centaines de milliers de fichiers ; opérations de fusion lourdes sur de grosses arborescences ; dépendance du réseau/serveur ; une base de collection qui grossit avec les shelvesets et les binaires. - Limites : chemins locaux limités par Windows (260 caractères) ; revue de code moins riche (demandes de revue de code Visual Studio, sans équivalent des politiques de PR) ; hors-ligne limité (espace de travail local et
tf reconcile), sans historique sur le poste. - Atténuations : mapping minimal (
workfold), dossiers racine courts, nettoyage régulier des shelvesets/workspaces inactifs, supervision de la taille de la base de collection.
Notes /5 de TFVC (contexte : équipe de 5 à 30 développeurs, Azure DevOps Server sur site, projet mixte SQL/BI/scripts) :
| Critère | Note | Justification |
|---|---|---|
| Courbe d'apprentissage | 4/5 | Modèle proche de SVN, Visual Studio guide |
| Performance sur gros dépôts | 4/5 | Mapping partiel, très gros arbres corrects |
| Branches / fusions | 3/5 | Fonctionnelles, rigides, baseless pénibles |
| Traçabilité / audit | 4/5 | Changesets numérotés, work items |
| Granularité des droits | 5/5 | Par chemin, héritage/refus |
| Fichiers binaires / volumineux | 4/5 | Pas de contournement requis |
| Intégration CI/CD | 3/5 | Builds OK, mais l'écosystème moderne cible Git |
| Adéquation SQL/BI | 3/5 | Diffs textes OK ; PBIP/TMDL sans revue par PR |
| Pérennité de l'écosystème | 2/5 | Maintenu mais « feature complete » (voir ci-dessous) |
Pièges et codes d'erreur#
🔴 Niveau expert
| Code / symptôme | Cause | Remède |
|---|---|---|
| TF203069 — modification en attente sur l'élément | Tentative de delete/rename/add alors qu'une modification est déjà en attente |
tf undo de l'élément, puis refaire l'opération |
« introuvable dans votre espace de travail » (tf delete) |
Élément jamais rapatrié localement | tf get de l'élément, puis tf delete |
| TF14061 — workspace introuvable | Workspace supprimé ou propriétaire différent | tf workspaces /computer:*, recréer ou mapper |
| TF10121 — chemin invalide | Chemin serveur mal écrit ($/ manquant) |
Vérifier par tf dir $/ |
| TF400xxx — conflit de version | Fichier modifié par un autre depuis votre get |
tf get puis tf resolve |
| Conflits massifs après copie de dossier | Fusion baseless | Reconstruire la branche proprement |
| Check-in qui échoue sur policies | Policies obsolètes (2025-26) | Les migrer, voir section policies |
tf checkin « rien à valider » |
Modifications non détectées (workspace local, fichier en lecture seule) | tf reconcile, vérifier tf status |
| Fichiers « fantômes » à l'ajout | Pas de .tfignore |
Ajouter .tfignore avant le premier add |
| Mojibake sur les accents | Fichiers sans BOM lus en ANSI, ou inverse | Voir 06 |
Les messages TFxxxxxx varient selon les versions : consultez le texte complet et l'aide Microsoft correspondante plutôt que de vous fier au seul code. Je n'ai pas vérifié chaque numéro pour toutes les versions : la section est une orientation, à confirmer en cas de doute.
Pérennité et état du produit#
🔴 Niveau expert
État vérifié par recherche (sources : documentation Microsoft Learn « Choosing the right version control for your project », billets de la feuille de route Azure DevOps, blog Azure DevOps) :
- Git est le contrôle de version par défaut pour les nouveaux projets Azure DevOps ; Microsoft recommande Git et d'envisager la migration des projets TFVC existants.
- TFVC est « feature complete » : Microsoft maintient la compatibilité (il reste supporté dans Azure DevOps et dans Azure DevOps Server), mais tout investissement futur va à Git. Pas de fonctionnalité nouvelle attendue.
- La feuille de route annonçait une suppression progressive de TFVC pour les nouveaux projets et organisations sans usage existant, avec un paramètre permettant de désactiver la création de dépôts TFVC. Les dépôts TFVC existants restent utilisables.
- Les check-in policies historiques sont en cours de dépréciation (calendrier 2025-2026, voir plus haut).
- Visual Studio : l'intégration TFVC est maintenue mais l'effort porte sur Git.
- À vérifier à chaque montée de version : la version d'Azure DevOps Server installée et ses notes de version ; la politique de support (modèle « Modern Lifecycle ») ; toute annonce de fin de création de dépôts TFVC pour votre collection.
Lecture d'expert : TFVC n'est pas retiré ; il est gelé. Une organisation qui l'utilise en production n'a pas d'urgence technique, mais a un risque stratégique : dette de compétence, absence d'innovation (pas de pull requests, pas d'IA de revue native comparables à Git), et risque que les outils tiers abandonnent le support. L'échéance réaliste de migration se décide par les besoins métier (revues, CI, recrutement), pas par une date imposée. La démarche est détaillée dans 04.
Contribution de l'IA#
Avec TFVC, l'apport de l'IA est réel mais plus pauvre qu'avec Git.
| Cas d'usage | Gain | Risque | Maturité | Garde-fous |
|---|---|---|---|---|
Écrire/expliquer une commande tf.exe ou un script PowerShell d'archivage |
4/5 | 3/5 | 3/5 | Tester avec /preview, relire les chemins |
Analyser un export tf history pour un audit |
4/5 | 2/5 | 4/5 | Contrôler les chiffres par un recompte |
| Rédiger commentaires de check-in | 3/5 | 2/5 | 4/5 | Rattacher un work item réel |
| Assistants dans Visual Studio (Copilot) pour code et messages | 3/5 | 2/5 | 3/5 | Les fonctions IA de PR/revue ciblent surtout Git |
Expliquer un code d'erreur TFxxxxxx |
3/5 | 4/5 | 2/5 | L'IA hallucine volontiers les numéros : vérifier sur la doc Microsoft |
L'IA ne remplace pas la connaissance du modèle serveur (workspaces, mappings) ni la décision d'archiver. Voir IA et outils.
Voir aussi#
- Panorama des GDS · Git en profondeur · Git vs TFVC
- Stratégies de branches · GDS et données SQL / BI
- Azure DevOps / TFS en profondeur · CI/CD
- Matrice : gestion de version et branches · Glossaire
✻ Rédigé par Claude Sonnet 5.5