Git-tfs : Utilisation de Git avec un serveur TFS
Publié le 3/11/2012, par Philippe Miossec dans Valtech | 1 Commentaire
Le contrôleur de code source TFS est bien souvent utilisé en entreprise.
Le contrôleur de code source Git apporte pourtant une plus grande souplesse d’utilisation et de nombreux avantages par rapport à le gestion de code source de TFS.
Nous allons donc voir comment nous pouvons utiliser Git en local tout en utilisant TFS côté serveur et ainsi en tirer de nombreux avantages.
1.Installation des outils nécessaires
- Installation de GitExtension(et Git)→ Utilisation d’OpenSsh (facultatif)→ Décocher l’option GitGUI (facultatif)→ Options par défaut de Git sauf : “Checkout as-is, commit as-is”
- Installation de p4merge , Telechargement(besoin d’un outil de 3way-merge!)→ Lors de la sélection des composants à installer, TOUT décocher sauf “Visual Merge Tool (P4Merge)”.
- Installation de notepad++ (besoin d’un éditeur de texte multi-instances!!)
- Copie des fichiers de Git-tfs dans le répertoire de Git.
Pour le moment, la gestion des branches par git-tfs que j’ai développé n’étant pas encore dans la version officielle 0.15 de git-tfs (pull request en attente de validation sur GitHub), on utilisera plutôt une version personnelle de git-tfsLa version officielle stable 0.16 gère maintenant les branches TFS!
- Verifier que le répertoire ‘bin’ de Git est dans le path ainsi que celui des outils p4merge et notepad++.
Avant-propos : Pour consulter l’aide d’une commande git :
git commit -h //aide de la ligne de commandegit help commit //aide html complete de la commande (page man)
2.Configuration de Git & GitExtension
3 moyens…
- Edition directement du fichier .gitconfig (situé dans le répertoire utilisateur)
Bootstrap : Télécharger l’archive et copiez le contenu dans votre répertoire utilisateur puis…→ Edition du fichier .gitconfig (mettre vos informations personnelles!)→ Utilisation d’un .gitignore global (si vous ne voulez pas archiver un fichier .gitignore dans TFS) => Copie du .gitignore_global( ou celui de GitHub )
- Par ligne de commande
Les configurations nécessaires pour faire fonctionner Git:
git config --global user.name "Ton Nom"git config --global user.email ton_mail@valtech.fr
Les configurations nécessaires pour faire fonctionner Git sous Windows!:
git config --global core.ignorecase truegit config --global core.autocrlf false
Consultation de la liste des configurations :
git config -lgit config --global -lgit config --local -l
- Depuis GitExtension
Au lancement de GitExtension, vérifier que le checkup est bon!Ou configurer en conséquence…Menu “Settings”→“Settings…”→Onglet “Global Settings”Editor :
notepad++ -multiInst -notabbar
MergeTool : p4merge
MergeTool Path :
C:/Program Files (x86)/p4merge/p4merge.exe
MergeTool command :
"C:/Program Files (x86)/p4merge/p4merge.exe" "$BASE" "$LOCAL" "$REMOTE" "$MERGED"
Difftool : p4merge
Difftool Path :
C:/Program Files (x86)/p4merge/p4merge.exe
Difftool command :
"C:/Program Files (x86)/p4merge/p4merge.exe" "$LOCAL" "$REMOTE"
3.Rappels sur Git!
Git est :
- un gestionnaire de contenu (et non de différence!)
- stocké sous la forme d’un graphe acyclique d’objets ou DAG
- accessible avec des références
![]() |
| Exemple de graphe acyclique représentant l’historique du dépot |
Toute manipulation de Git ne fait que manipuler ce graphe… (Ne jamais l’oublier et essayer de visualiser cela!!)
…en ne faisant qu’ajouter des commits!
4.Présentation de GitExtension
![]() |
| Interface de GitExtension montrant le DAG d’historique du dépot |
GitExtension est une interface très performante à Git qui permet :
- Consultation du graphe de commits (diff)
- Zone de staging , ajout de fichiers, de lignes
- Message de commits, templates, workitems, commit local, amend
- Stash, Merge, Rebase
- Fetch, Fetch et Rebase, Commit
- Historique (blame)
5.Utilisation de Git-TFS:
_Note :
- On pourra tester toutes les commandes git-tfs indiquées en utilisant le projet “valtechgittfs” disponible sur Codeplex Pour cela, on pourra utiliser le compte utilisateur ‘vtccds’ (mot de passe:vtccds)_
- Attention : Lors de l’interaction avec le serveur TFSde Codeplex, le login à fournir est de la forme (sans les crochets!): [LoginCodePlex]_cp@sndLe mot de passe reste celui du compte Codeplex.
5.1. Clonage du dépôt TFS
Commande de clone (dans le répertoire courant) du dépot TFS avec historique (conseillé! mais –très– long…):
git tfs clone http://monServeurTfs:8080/tfs/DepotTfs $/MonProjet/NomDuTronc .
exemple:
git tfs clone https://tfs.codeplex.com:443/tfs/TFS16 $/valtechgittfs/trunk . --username=vtccds_cp@snd --password=vtccds
Note : Attention à ne cloner que le répertoire correspondant à la branche principale du projet (le tronc) et non pas tout le dépot entier!
Commande de clone (dans le répertoire courant) du dépot TFS sans historique (dernier changeset):
git tfs quick-clone http://monServeurTfs:8080/tfs/DepotTfs $/MonProjet/NomDuTronc .
exemple:
git tfs quick-clone https://tfs.codeplex.com:443/tfs/TFS16 $/valtechgittfs/trunk . --username=vtccds_cp@snd --password=vtccds
Convient pour un développement ponctuel ou lorsqu’on n’a pas besoin de l’historique…
Note :
- le clone ne doit pas être fait dans un répertoire mappé avec TFS (workspace).
- on peut partager le dépot cloné juste par copie (ou par clonage git!) à un autre développeur.
5.2. Récupération des commits de TFS (sans merge ni rebase dans branche master)
git tfs fetch
5.3. Création des commits locaux
Lors des commits locaux dans Git, l’association de Workitems se fait par l’ajout des meta-données suivantes dans la description du commit
git-tfs-work-item: 2198 associate //Pour associer un workitemgit-tfs-work-item: 2198 resolve //Pour clore le workitem
5.4. Report des commits locaux sur le serveur TFS
Méthode facile mais déconseillée :
git tfs ct
Cette commande ouvre la fenêtre de commit de TFS (message + association de workitems) mais crée un commit de merge (moche et peut y avoir des conflits de merge au moment du commit
)
Méthode conseillée :
git tfs rcheckin
Cette commande ré-applique les commits sur le serveur TFS. Cependant, nécessite d’être à jour par rapport aux commits sur TFS et d’avoir “rebasé” ses commits locaux.
Nécessite également de ne pas avoir de modifications dans l’espace de travail
git stash save //pour mettre les modifications de côté//Commit...git stash pop //pour récupérer les modifications mises de côté
Worklow utilisé en découlant :
git tfs fetch ==>récupération de derniers commits du serveurgit stash save ==>mise de côté des modifications non commitéesgit rebase tfs/default =>réapplication des commits locaux sur la dernière version de TFS (merges possibles!)git tfs rcheckin => réapplication des commits sur TFSgit stash pop => réapplication des modifications non commitées
Ajout d’alias pour automatiser ce workflow:
Pour synchroniser ses modifications avec la dernière version de TFS:
git config --global alias.tfsrebase '!sh -c "git tfs fetch && git stash save && git rebase tfs/default && git stash pop"'
→Utilisation: git tfsrebase
Pour commiter sur TFS:
git config --global alias.tfscommit '!sh -c "git tfs fetch && git stash save && git rebase tfs/default && git tfs rcheckin && git stash pop"'
→Utilisation: git tfscommit
5.5.Scripts GitExtension:
Il peut être pratique de créer dans GitExtension les scripts décrit ci-dessous; ensuite disponibles par un clic droit dans le Browser de GitExtension.
Pour cela, allez dans le menu “Settings”→“Settings…”→Onglet “Scripts” et ajoutez un ligne où on remplira les 3 champs requis par les valeurs de chaque ligne :
| Name | Cmd. | Arguments |
|---|---|---|
| Tfs(Tronc)> Fetch | git |
tfs fetch |
| Tfs(Tronc)> Fetch and Rebase | git |
tfsrebase |
| Tfs(Tronc)> Commit | git |
tfscommit |
5.6.Gestion d’une branche de TFS:
Notes préalable :
- La création d’une branche doit toujours être effectuée avec TFS. Dès sa création, on peut ensuite la récupérer avec git-tfs et travailler avec.
- Rien n’empêche le développeur de créer des branches locales avec Git mais si une branche doit être partagée par tous les développeurs, alors la branche doit être créé préalablement sur TFS.
Récupération d’une branche TFS…
Solution déconseillée :
- Créer un nouveau dépot Git avec la seconde branche (cf clone vu précédemment)
- Inconvénients : on ne peut pas backporter des corrections et voir les différences entre les branches!
Solution Plus convenable:
Utiliser la customisée de git-tfs contenant la commande “init-branch” :
git tfs init-branch $/MyProject/MyTFSBranch //Pour récupérer une branche spécifiquegit tfs init-branch --all //Pour récupérer toutes les branches existantes
ex : git tfs init-branch $/valtechgittfs/branche1
Récupération des commits d’une branche:
git tfs fetch -i branche1
Commiter sur une branche TFS:
git tfs rcheckin -i branche1
Ajout d’alias pour automatiser le workflow précédent avec des branches:
Pour synchroniser ses modifications avec la dernière version de la branche sur TFS:
Création de l’alias git :
git config --global alias.tfsrebasebranch '!sh -c "git tfs fetch -i $1 && git stash save && git rebase tfs/$1 && git stash pop"'
Utilisation: git tfsrebasebranch branche1
Pour commiter sur la brance sur TFS:
Création de l’alias git :
git config --global alias.tfscommitbranch '!sh -c "git tfs fetch -i $1 && git stash save && git rebase tfs/$1 && git tfs -i $1 rcheckin && git stash pop"'
Utilisation: git tfscommitbranch branche1
5.7.Scripts GitExtension (suite):
Menu “Settings”→“Settings…”→Onglet “Scripts” et ajoutez un ligne où on remplira les 3 champs requis :
| Name | Cmd. | Arguments |
|---|---|---|
| Tfs(Branche)> Fetch | sh |
-c "git tfs fetch -i $(echo {sRemoteBranch} | sed 's/tfs\///')" |
| Tfs(Branche)> Fetch and rebase | sh |
-c "git tfsrebasebranch $(echo {sRemoteBranch} | sed 's/tfs\///')" |
| Tfs(Branche)> Commit | sh |
-c "git tfscommitbranch $(echo {sRemoteBranch} | sed 's/tfs\///')" |
Note: Pour les utiliser, bien faire attention à cliquer sur la ligne du commit où se trouve la branche distante ‘tfs/maBranche’ (en vert, dans GitExtension)
5.8.Travailler avec les shelvesets
Liste de ses commits réservés
git tfs shelve-list
Ceux d’un autre utilisateur:
git tfs shelve-list -u LOGIN_UTILISATEUR
Créer une branche à partir d’un shelveset:
git tfs unshelve MonShelveset MaBranche
Créer un commit réservé de la branche courante:
git tfs shelve MonShelveset
Avantage de la branche Git sur le shelveset TFS :
- on peut faire plusieurs commits
- on connait le commit parent et voit exactement les modifications faites (là ou TFS présente seulement un état de fichier et on ne sait pas comment il serait mergé!)
- mergeable plus facilement (moins sensible au modifications)
6.Utilisation de Git
- Règle de Base : Ne JAMAIS modifier des commits déjà partagés!!!!!!
- Mise de coté des fichiers modifiés de l’espace de travail (fonctionne comme une pile)
git stash save //pour mettre de côtégit stash pop //pour récupérer le dernier stash mis de côté
- Reset d’une branche à un certain commit (Mixed/Hard)
- Merge / Rebase
Le merge :
- crée un commit supplémentaire pour réunir les 2 branches.
- Il permet de matérialiser l’introduction d’une fonctionnalité dans une branche.
- Cette opération peut être réalisée avec des fichiers modifiés dans l’espace de travail.
![]() |
| le DAG après un merge : le commit C6 est un commit de merge |
Le rebase :
- réapplique les commit d’une branche sur un commit.
- Il permet d’avoir un historique linéaire.
- Cette opération ne peut être réalisée avec des fichiers modifiés dans l’espace de travail (nécessité de faire un stash auparavant).
![]() |
| le DAG après un rebase : le commit C3 est réappliqué sur la branche master… |
- J’ai commité dans le tronc alors que je voulais faire une branche
- un bug à résoudre rapidement alors que je suis en plein développement
- Modification des commits existants (pour par ex. rajouter l’association de workitems!)
git rebase -i HEAD~n (avec 'n' à remplacer par le nombre de commit qu'on veut réécrire)
Attention : Ne pas enfreindre la règle de base!!!
- Historique des opérations (et réparation des erreurs!) :
git reflog => voire l'historique des modificationgit branch MaBranche d995afd => creation d'une branche sur un commit (en indiquant son sha1)
- Astuce: Git ne fait qu’ajouter des commits et n’en détruie AUCUN! (sauf lors du passage du Garbage Collector tous les 30 jours pour effacer ceux non utilisés).Donc avant de faire une opération dont vous n’avez pas l’habitude, vous avez juste à créer une branche là où vous êtes qui vous servira de sauvegarde!Et à l’effacer quand vous avez réussi…
- Trouver un commit fautif : Bisect !
7. Aperçu de Git-TF
- Par défaut, création d’un seul commit de merge (utiliser l’option ––deep pour réappliquer les commits locaux sur le serveur TFS) et perte des messages de commit (sauf le dernier)
- Association des workitems dans la ligne de commande (donc pas de possibilité d’utiliser depuis une GUI
)et même association de workitems pour TOUS les commits (si utilisation de l’option ––deep. Et apparement il y aurait un bug
) - Pas de gestion des branches (un clone, donc un dépot par branche)
- C’est du Java
8. Retour d’expérience
Avantages:
- Connaissance à tout instant de quelle version on utilise localement
- Branches et commits locaux (expérimentation, retour en arrières, meilleur développement, baby steps,…)
- Meilleur connaissance des modifications des autres utilisateurs (visualisation de l’historique + diffs)
- BEAUCOUP plus grande souplesse de développement et de commit (commit de parties de fichiers!)
- Remplacement du shelving par les branches ( et on peut faire plusieurs commits)
- Commit de Revert
- Bisect : trouver une régression facilement en testant les commits successivement par dichotomie
- Cherry Picking (prendre un commit intérressant d’une branche et l’appliquer sur la branche actuelle)
- Meilleur Historique
- Plus de mode connecté/déconnecté de TFS
- Backport de commit entre branches plus facile
- Visual Studio est plus rapide car il n’a pas à contacter le serveur TFS pour extraire les fichiers en modifications (ainsi que beaucoup d’autres actions qui sont faites maintenant localement : blame, diff, …)
Inconvénient:
- Ticket d’entrée légèrement plus important (il faut comprendre/visualiser les manipulations du DAG)
- Rechargement des fichiers et projets plus souvent que sous TFS (à cause de la glue Git-tfs qui créé les commits sur TFS, les récupère et fait un rebase dessus. Non présent sur un dépot distant Git qui ne fait qu’envoyer les commits sur le dépot distant…)
- (?) Visual Studio exclue régulièrement des fichiers App.config & Dev.config de la Solution….
9. Conclusion
Beaucoup d’avantages, quelques petits désagréments
TFS est une solution d’archivage, Git est un outil servant à faciliter un développement
PS :
- Vous avez toutes les infos pour utiliser Git-tfs mais il vous reste à apprivoiser Git…
- Documentation
- Un petit tutoriel assez marrant pour apprendre les commandes de base de git (et voir comment elles sont mieux pensées que celles de TFS
)
(c) Image de GitExtension par le site de GitExtension : http://code.google.com/p/gitextensions/
(c) Images de DAG Git par http://git-scm.com/




Bonjour,
Merci pour ce rappel sur Git, son installation et toutes ces astuces qui seront contentés les internautes intéressés par Git.
Nous confirmons que la plupart des points sur Git sont des avantages même si certains points à améliorer subsistent (comme toute technologie).
—
L’équipe GitStack