Tortoise Git 4
Tortoise Git 4
21
4 Les adeptes de Subversion pourront remarquer qu’il ne s’agit pas d’un checkout !
5 Le «checkout» de Git permet de choisir la version (ou la branche) qui sera votre copie de travail. Il est possible de changer
de version de travail à chaque fois qu’on le souhaite. Cette fonctionnalité ne sera pas traité plus en détails dans ce guide.
TortoiseGit
4.2.1. Transférer les modifications des fichiers dans le repository local : (add +) commit6
Le commit est la commande la plus effectuée lors de l’utilisation d’un projet contrôlé et versionné par Git.
Les fichiers concernés et déjà versionnés doivent d’abord être placés dans la «staging area» dans le
repository local, puis ils sont (ainsi que leurs modifications) ensuite transférés (committed) vers le
repository local.
6 Il semble qu’il n’y a pas de différences avec l’étape suivante dans l’appel des commandes, mais j’ai préféré faire la diffé-
rence entre fichiers modifiés et nouveaux fichiers.
‣ajout d’un fichier modifié et de ses modifications du répertoire de travail vers la staging area :
$ git add file
e.g. $ git add [Link]
‣transfert des modifications des fichiers de la staging area vers le repository local :
$ git commit -m ”message explaining modifications”
Important : tous les fichiers de la staging area sont transférés vers le repository local au moment du
commit.
Git
Note : le message accompagnant le commit -m “message explaining modifications” n’est
pas obligatoire mais très fortement conseillé
Lorsque vous avez modifié un fichier, et qu’il n’est donc
[Link]
depuis le dossier où le fichier est contenu :
$ git add [file]
e.g. $git add [Link]
([Link] est maintenant dans la staging area)
e.g. $git add *.cs
Git (Tous les fichiers *.cs de ce dossier sont maintenant dans la staging area)
2. commit
la commande suivante ajoute [Link] au repository local (ainsi que tous les autres fichiers de la
staging area).
$ git commit -m “added [Link]”
1. add
La commande add se fait via le menu contextuel : clic
droit sur le(s) fichier(s) à ajouter -> Tortoise Git -> Add...
Une fenêtre de dialogue apparaît alors vous permettant
d’ajuster votre ajout en (dé)sélectionnant les fichiers à
ajouter.
!
Après avoir valider votre ajout, votre fichier est marqué
d’un gros + bleu, indiquant qu’il se trouve comme mo-
difié (staged) et sera ajouté au prochain commit.
TortoiseGit !
2. commit
La fenêtre de dialogue suivante vous permet d’ailleurs
de faire directement le commit. Même s’il est conseillé
de le faire une fois pour tous les fichiers ajoutés et mo-
difiés, voici tout de même la liste des commandes à
effectuer.
!
[Link]
depuis le dossier où le fichier est contenu :
$ git rm [file]
e.g. $git rm [Link]
([Link] n’est maintenant plus dans la staging area)
e.g. $git rm *.pdb
(Tous les fichiers *.pdb de ce dossier vont être supprimés du repository local)
Git Pour supprimer le fichier du repository mais le garder sur son disque dur, on peut aussi utiliser la
commande :
$ git rm --cached [file]
2. commit
la commande suivante opère la suppression : les fichiers supprimés ne seront plus cette nouvelle version
du repository.
e.g. $ git commit -m “deleted [Link] and all *.pdb files”
1. rm
La commande rm se fait via le menu contextuel : clic
droit sur le(s) fichier(s) à supprimer -> Tortoise Git ->
Delete ou Delete (keep local).
Les deux préparent la suppression du fichier au pro-
chain commit, mais le premier envoie en plus le fi-
chier à la corbeille (rm), alors que le second le laisse
en place sur le disque dur (rm --cached, il n’a plus
TortoiseGit aucune pastille). Le dossier contenant prend une
méchante pastille en forme de X rouge annonçant
qu’il y aura des suppressions au prochain commit.
! !
TortoiseGit
2. commit
2. commit
la commande suivante réalise l’opération dans la prochaine version dans le repository local.
e.g. $ git commit -m “renamed old_named and moved file”
La boîte de dialogue ci-contre s’ouvre alors et permet de renommer le fichier. Celui-ci est maintenant
marqué par un gros + bleu, car git opère en interne, une copie, un add et un remove. Le fichier renommé
est donc ajouté. Il faut ensuite effectuer le commit comme pour un add.
‣ Git Move versioned item(s) here : déplace les fichiers versionnés dans le nouveau dossier (ils sont ajou-
tés et ceux d’origine sont détruits) ;
‣ Git Move and rename versioned item here : fait la même chose mais vous autorise à renommer les
fichiers avant ;
‣ Git Copy versioned item(s) here : fait la même chose que le premier mais sans détruire les fichiers dans
le dossier d’origine ;
‣ Git Copy and rename versioned item here : fait la même chose que le précédente mais vous autorise à
renommer les fichiers avant.
L’historique des versions des fichiers est à chaque fois conservé.
$ git log
permet de visualiser l’historique du repository de manière assez moche. On retrouve les opérations
effectuées, l’auteur des modifications ainsi que le message qu’il a laissé.
exemple de résultat :
commit cf273ccca4acebdf67bdb43043409600f85cf800
Author: Marc Chevaldonné <[Link]@[Link]>
Date: Sun Aug 8 [Link] 2010 +0200
Git
deleting [Link]
commit 5a6471bcd67289e7d04541130902411691f1f0b6
Author: Marc Chevaldonné <[Link]@[Link]>
Date: Sun Aug 8 [Link] 2010 +0200
added [Link]
TortoiseGit
!
TortoiseGit
4.3.1. Principe
Le concept de branches de Git est indissociable de celui des
copies de travail. Pour bien comprendre ces principes, il faut se
représenter deux types d’entités : les commits et un système de
pointeurs sur commit. Par commit, nous entendons ici une
version du repository, i.e. un état (une photographie) du projet à
un instant donné. Ces commits seront représentés dans les
schémas suivants par une case avec Ci ou i est un indice qui
croît avec le temps. La branche principale s’appelle «master»7.
«HEAD» est un pointeur sur la branche courante (celle que vous
êtes en train d’utiliser), soit «master» tant que vous ne faites pas
de branches.
8 On pourrait également supprimer la branche ou faire un rebase. Mais ceci ne fait pas l’objet de ce document.
‣ Branches de debug : ces branches sont généralement créées dans un but précis qui est celui de
corriger un bug en particulier et ont donc normalement une durée de vie limitée. Elles sont supposées
être réintégrées assez rapidement dans la branche qui les a vu naître.
‣ Branches de test : elles ont pour objectif de tester de nouvelles idées, pas forcément prévues au
démarrage du projet. Leur durée de vie est moyenne et leur réintégration dans la branche qui les a vu
naître dépend de l’idée elle-même.
‣ Branches de module : l’objectif de telles branches est de préparer une amélioration, un module,
complètement à part, et de ne l’intégrer qu’une fois terminer. Ces branches doivent donc être
réintégrées dans la branche «master». Leur durée de vie dépend de la taille du module à ajouter. Notons
toutefois que plus celle-ci est longue, plus le risque de problèmes lors de la fusion sera importante.
‣ Branches de développement : elles représentent tout un pan de votre projet, une version de
l’application. Ces branches vivent tout au long du projet et ne sont jamais réintégrées dans la branche
«master». On peut par exemple imaginer dans le cadre de notre jeu, la branche «Web» et la branche
«XBox».
1. Créer la branche :
Note : $ git branch
$ git branch branch_name
renvoie la liste des branches du
e.g. $ git branch debug#1
repository. La branche avec un * est la
Enfin, lorsque vous voulez faire un commit, vous remarquerez que le click droit n’offre plus l’option «Git
Commit -> master...» mais «Git Commit -> debug#2...» indiquant par là que la branche active sur la-
Enfin, vous pouvez vérifier sur quelle branche vous vous trouvez lorsque vous voulez faire un commit :
clic droit offre l’option «Git Commit -> branch_name...» ou branch_name est le nom de la branche active.
1. Faites un clic droit sur le dossier parent, puis choisissez TortoiseGit -> Switch/Checkout...
Placez-vous dans la branche qui va recevoir la branche fusionnée (e.g. «master»).
TortoiseGit
i. dans la branche «master», le fichier Tap_tappe.txt est créé et au commit C1, contient le texte
suivant :
<Onstage>
New York M C:
You want it right, direct from hell, Spinal Tap!
C1
--- Spinal Tap performs Tonight I'm Gonna Rock You Tonight ---
David: We are Spinal Tap from the UK you must be the USA!
#
ii. la branche «song_branch» est créée ; le fichier Tap_tappe.txt est modifié et au commit C2,
contient le texte suivant (en rouge le texte modifié) :
<Onstage>
New York M C:
You want it right, direct from hell, Spinal Tap!
--- Spinal Tap performs Tonight I'm Gonna Rock You Tonight ---
David: We are Spinal Tap from the UK you must be the USA!
Little girl, it's a great big world but there's only one of me
You can't touch 'cause I cost too much but
Tonight I'm gonna rock you (Tonight I'm gunna rock you)
Yeah tonight I'm gonna rock you (Tonight I'm gunna rock you)
Tonight!
Whoa yeah
Chorus:
Little girl, it's a great big world, but there's
only one of - meeeee
iii. on retourne sur la branche «master» ; le fichier Tap_tappe.txt est modifié à nouveau et au commit
C3, contient donc le texte suivant (en rouge le texte modifié) 9 :
<Onstage>
New York M C:
You want it right, direct from hell, Spinal Tap!
--- Spinal Tap performs Tonight I'm Gonna Rock You Tonight ---
David: We are Spinal Tap from the UK you must be the USA!
9 notez que le texte modifié en C2 n’est pas contenu ici puisqu’il est modifié dans une autre branche
1. on tente un merge
$ git checkout main_branch e.g. «master» : $ git checkout master
$ git merge merged_branch e.g. «song_branch» : $ git merge song_branch
Git ne sait pas dans quel ordre il doit fusionner les modifications des deux branches (doit-il mettre
d’abord les paroles de Tonight ou la Garden Interview ?)
Si on ouvre le fichier, il contient des insertions lors du merge qu’il faut éditer. Par exemple, le fichier
Tap_tappe.txt ressemble désormais à :
<Onstage>
New York M C:
You want it right, direct from hell, Spinal Tap!
--- Spinal Tap performs Tonight I'm Gonna Rock You Tonight ---
David: We are Spinal Tap from the UK you must be the USA!
<<<<<<< HEAD
Git
<Garden Interview I>
Marty: Let's...uh talk a little bit about the history of the
group. I understand Nigel you and David originally started
the band wuh...back in...when was it... 1964?
David: Well before that we were in different groups, I was in a
group called The Creatures and w-which was a skiffle group.
Nigel: I was in Lovely Lads.
David: Yeah.
Nigel: And then we looked at each other and says well we might as
well join up you know and uh....
David: So we became The Originals.
Nigel: Right.
David: And we had to change our name actually....
Nigel: Well there was, there was another group in the East End
called The Originals and we had to rename ourselves.
David: The New Originals.
Nigel: The New Originals and then, uh, they became....
David: The Regulars, they changed their name back to The Regulars
and we thought well, we could go back to The Originals but
what's the point?
Nigel: We became The Thamesmen at that point.
=======
--- Tonight I'm Gonna Rock You Tonight (lyrics) ---
Little girl, it's a great big world but there's only one of me
You can't touch 'cause I cost too much but
Tonight I'm gonna rock you (Tonight I'm gunna rock you)
Yeah tonight I'm gonna rock you (Tonight I'm gunna rock you)
Tonight!
Whoa yeah
Chorus:
Little girl, it's a great big world, but there's
only one of - meeeee
À cause du conflit, l’auto-commit n’a pas été fait. Il nous faut éditer le conflit et faire le commit à la main.
Nous voulons par exemple mettre les paroles de la chanson avant la Garden Interview (avec des coupes
pour des raisons de place) et bien sûr enlever les lignes insérées par Git :
<Onstage>
New York M C:
You want it right, direct from hell, Spinal Tap!
--- Spinal Tap performs Tonight I'm Gonna Rock You Tonight ---
David: We are Spinal Tap from the UK you must be the USA!
Little girl, it's a great big world but there's only one of me
You can't touch 'cause I cost too much but
Tonight I'm gonna rock you (Tonight I'm gunna rock you)
Yeah tonight I'm gonna rock you (Tonight I'm gunna rock you)
Tonight!
[...]
Chorus:
Little girl, it's a great big world, but there's
only one of - meeeee
Git
--- end of the song ---
[...]
David: The Regulars, they changed their name back to The Regulars
and we thought well, we could go back to The Originals but
what's the point?
Nigel: We became The Thamesmen at that point.
Git ne sait pas dans quel ordre il doit fusionner les modifications des deux branches (doit-il mettre
d’abord les paroles de Tonight ou la Garden Interview ?).
Les fichiers en conflit sont marquées d’une pastille qui fait peur : !
TortoiseGit
Le fichier est alors considéré comme résolu et modifié. Il a perdu sa méchante pastille pour la pastille
rouge avec un point d’exclamation. Il peut être maintenant «commité».
TortoiseGit
Il était donc nécessaire d’avoir compris la gestion de Git en local et la gestion des branches avant de parler de la
synchronisation avec le repository distant.
Cette partie présente comment soumettre son travail dans le cas où personne n’a rien soumis depuis votre
dernière mise à jour ; comment récupérer le travail des collaborateurs dans le cas où vous n’avez rien soumis
depuis votre dernière mise à jour ; comment soumettre et récupérer le travail des autres collaborateurs en cas de
conflits (vous avez fait des mises à jour et/ou quelqu’un a fait des mises à jour) grâce aux branches distantes et à la
fusion de branches10.
Pour l’ensemble de ces parties, nous utiliserons le cas suivant. Il existe un repository distant déjà créé contenant un
fichier sur la branche master. Ce fichier est modifié par deux utilisateurs : Derek Smalls et Nigel Tufnel.
10 Nous ne travaillerons ici qu’avec un seul repository distant, mais sachez qu’il est possible d’avoir plusieurs repositories
distants pour un même projet.
La synchronisation avec le repository distant se fait à l’aide de branches (remote branches). Par exemple, la
branche master du repository distant (origin) est représentée en local par origin/master. Attention, ce pointeur
origin/master, correspond à l’état de la branche du repository distant au moment de la dernière mise à jour. Dans
la suite de cet exemple, nous représenterons donc l’évolution des repository de Derk, de Nigel et distant. Au
démarrage, puisque les 2 utilisateurs sont à jour, les repositories ressemblent à ça.
! !
! !
Il souhaite partager son travail sur le repository distant. Pour cela, il fait un push. Le repository est mis à
jour, ainsi que la branche distante origin/master de Derek, mais pas celle de Nigel qui n’a rien fait.
! !
Cette opération se passe bien s’il n’y a pas eu d’autres apports des autres collaborateurs (ici Nigel) sur le
repository. Dans le cas contraire, il faut d’abord mettre à jour votre repository, résoudre les éventuels
conflits, puis pousser à nouveau.
! !
Pour que sa branche master soit mise à jour, il doit fusionner les deux branches master et origin/master.
Cette fusion ne pose aucun problème puisque master pointe toujours sur un ancêtre de origin/master. En
d’autres termes, ça ne pose aucun problème parce que Nigel n’a pas fait de commits entre sa dernière
mise à jour et le fetch. Après la fusion, les repositories ressemblent donc à ça.
! !
Git 2. Il faut ensuite fusionner les deux branches : pour cela, on se place d’abord dans la branche qui doit
recevoir (e.g. master) et on fusionne (puis commit) :
$ git merge [remote-branch]
e.g. $ git merge origin/master
Cette opération se passe bien s’il n’y a pas de conflits, c’est-à-dire si le collaborateur qui fait le fetch n’a
pas fait de modifications générant de conflits.
! !
Nigel «pousse» son travail sur le serveur via un push. Le repository distant est modifié. Celui de Nigel
aussi et est à jour. En revanche, la branche origin/master de Derek n’est plus à jour mais il ne le sait pas
encore.
! !
Derek a terminé son travail et souhaite le pousser à son tour. Il fait un push mais se le voit refuser par le
serveur, qui lui demande de faire d’abord un fetch, de fusionner ses données, puis de faire un commit et
de repousser à nouveau.
Il obtient des conflits sur le fichier modifié par Nigel au commit C4 et ses propres modifications du commit
C3. Après avoir géré les conflits, fusionné les branches et fait le commit C5, son repository ressemble à :
Il peut cette fois-ci faire son push, puisqu’il est à jour avec le repository distant (C5 est bien un ancêtre de
C4).
! !
4.5.1. Tag
À suivre...
4.5.2. Rebase
À suivre...
4.5.3. Pull
À suivre...