Introduction à Git pour les gens normaux
Vous êtes convaincus : Git c’est génial. Tous vos collègues vous en parlent, github est en lien partout, Google et Linus l’utilisent et il n’y a pas un blog qui n’en disent pas du bien (à part ceux des fans de Baazar bien sûr). Bref, vous vous sentez dans la peau des utilisateurs de CVS quand SVN est arrivé, vous voulez goûter au progrès et ne plus être has been.
Mais voilà, après avoir découvert qu’il n’y a presque pas de ressources en français sur l’outil, vous avez lu Pro Git, vous avez posé des questions sur StackOverflow et vous n’arrivez toujours pas comprendre ce que veulent dire les incantations runiques du genre :
git reset --mixed HEAD~1
Tout le monde sur les fora vous disent que c’est pourtant évident, et vous vous sentez très bête. Non ? Bon, c’est juste moi alors.
Don’t panic ! Avec l’espoir de prévenir une nouvelle dépendance à l’aspirine chez les développeurs agiles, on va se faire quelques tutos e-vidents.
Pas de présentation de l’outil
Je pars du principe que vous savez utiliser un système de gestion des sources. Ce n’est pas un cours de gestion de projet, mais une aide de prise en main d’un outil. Et je ne vous ferai pas la pub de Git non plus, si vous êtes là, c’est que vous êtes a priori intéressés (et en plus je trouve Mercurial plus simple, mais bon, c’est moins classe sur le CV).
Pour suivre ce tuto vous avez donc besoin :
- D’avoir utilisé précédemment un outil de gestion de sources quelconque (SourceSafe ne compte pas). J’inclurai des références à SVN, donc bonus pour ses utilisateurs.
- D’être capable d’oublier tout ce que vous avez appris avec cet outil de gestion de sources. Parce qu’il va y avoir pas mal de remise en cause.
- Savoir vous servir de la ligne de commande. Dépendants de Tortoise, allez voir chez Hg si j’y suis. Je sais ça craint, mais si vous cherchez sur Wikipedia qui a codé Git, ça ne vous étonnera pas.
- Avoir installé Git et être capable d’afficher sans erreur « git help ». L’installation n’a rien à voir avec notre sujet qui est de démystifier cet outil chamanique, pas de savoir comment le placer sur l’autel.
Dans ce premier tuto vous allez apprendre à :
- Créer un dépôt local.
- Enregistrer des modifications.
- Voir l’effet de ces modifications.
- Comprendre ce que fait exactement Git quand vous faites tout ça.
Temps de lecture : 1H30 minimum.
Créer un dépôt Git
Pour commencer, le plus simple est que nous travaillons tous avec les mêmes fichiers. Voici un petit Zip qui contient des fichiers texte, un dossier et une image pour nous permettre de faire nos tests :
Téléchargez l’archive, faite une extraction et, depuis un shell, mettez vous dans le dossier ainsi obtenu. Si vous faites « ls » ou « dir », vous devriez maintenant voir :
tuto_git_e-vidence $ ls
divers README.txt README.txt~ TODO.txt TODO.txt~ tuto.txt tuto.txt~
Pour créer un dépôt local, ou « repository », nous allons utiliser « git init » :
$ git init Initialized empty Git repository in ../tuto_git_e-vidence/.git/
Pour le moment, rien de compliqué. Techniquement, il semble qu’il ne s’est rien passé à part une petite phrase pour vous dire que Git a fait son boulot. Pourtant, si vous affichez les fichiers cachés, vous verrez qu’un nouveau dossier « .git » est apparu :
$ ls -a . divers README.txt TODO.txt tuto.txt .. .git README.txt~ TODO.txt~ tuto.txt~
« .git » est le dossier qui contient tout l’historique de votre dépôt ainsi que tous ses fichiers de configuration. En gros, sauvegarder votre dépôt est aussi simple que de sauver ce dossier. Supprimer votre dépôt, c’est juste mettre ce dossier à la poubelle.
Inutile de passer du temps sur « .git ». Cachez le pour ne plus y penser.
Ah si, une dernière chose pour les anciens de SVN. « .git » n’existe que dans le dossier racine, à l’inverse des dossiers « .svn » qui se trouvaient dans chaque sous dossier. Cela rend la dissociation entre vos fichiers normaux et ceux stockés dans Git beaucoup plus simple.
A ce stade là, Git n’a absolument aucune trace d’aucun fichier. « git init » ne fait que créer le dépôt, il n’ajoute rien dedans. D’une manière générale, et c’est très important car constant avec Git, Git ne fera rien sans que vous lui demandiez explicitement. Cela semble souvent rébarbatif au début, mais cela vous donne un contrôle très fin sur ce que vous faites et paie sur le long terme.
Ajouter des fichiers au dépôt
Git possède un fonctionnement très particulier : il sauvegarde des listes de changements. Il ne se souvient pas de comment était les fichiers à un instant T, mais il se souvient de l’ensemble des modifications faites depuis le début.
C’est très déroutant au départ, surtout si l’on vient de SVN, car on raisonne en termes de versions de fichiers. Avec Git, il n’y a pas de versions de fichier. Il y a juste des groupes de changements à vos fichiers de départ. On appelle cela des « changesets ».
Au départ, dans votre historique, il n’y a rien. Pour Git, le premier « snapshot » (l’image du système de fichier qu’il garde en interne) est une feuille blanche. On dit alors à Git de prendre en compte des fichiers, et Git ne rajoute pas les fichiers mais « l’action d’avoir créé un fichier et son contenu ».
En pratique, voilà comment on ajoute nos fichiers :
$ git add README.txt #1 $ git add TODO.txt $ git add tuto.txt $ git add divers #2 $ git commit -m "Ceci est un commentaire" #3 [master (root-commit) bbfc3cf] Ceci est un commentaire 4 files changed, 5 insertions(+), 0 deletions(-) create mode 100755 README.txt create mode 100755 TODO.txt create mode 100644 divers/django.png create mode 100644 divers/truc_que_je_ne_classerai_jamais.txt create mode 100755 tuto.txt
Il y a beaucoup de choses à expliquer ici.
#1 : D’abord, on utilise « git add » pour signaler à Git que l’on veut ajouter cette modification au dépôt. J’ai bien dit « cette modification », pas « ce fichier », bien qu’on utilise le nom du fichier pour s’y référer. Ici on dit « ajoute la modification qui consiste à la création du fichier README.txt ».
#2 : On fait la même chose avec « TODO.txt » et « tuto.txt ». « git add » fonctionne de manière récursive, ce qui signifie que si vous lui donnez un dossier, Git va chercher toutes les modifications qu’il pourra trouver dans ce dossier, et ses sous-dossiers, ainsi que les sous-dossiers des sous-dossiers et ainsi de suite. Là, il s’aperçoit qu’il y a création de deux fichiers dans le sous dossier et il les ajoute.
#3 : Ensuite, on utilise « git commit » pour dire « sauvegarder ces modifications dans l’historique de Git ». Il est obligatoire d’écrire un commentaire à chaque commit, et on peut le faire entre autres en utilisant l’option « -m » suivie du commentaire entre guillemets.
Vous noterez d’une part que « git commit » est différent de celui utilisé par SVN. Commit sauvegarde les modifications dans le dépôt localement, pas du tout sur un serveur distant. Nous verrons comment sauvegarder les modifications sur un serveur distant plus tard.
Ensuite, du fait de l’aspect récursif de « git add », nous aurions pu faire « git add . » (”git add point”) à la racine pour ajouter toutes les modifications du dossier courant et donc de tout le projet, plutôt que de faire « git add nom_du_fichier » pour chaque fichier.
Certes, mais cela aurait eu un effet indésirable : celui d’ajouter également les fichiers temporaires « TODO.txt~ » et « README.txt~ ». C’est une des raisons pour laquelle la finesse de Git est agréable, vous pouvez contrôler exactement ce qui rentre et ce qui sort.
Tout de même, dans la plupart des cas, il est pratique de faire rapidement un « git add . ». Heureusement, Git fournit un moyen de déclarer une liste de fichiers que l’on ne souhaite jamais ajouter au dépôt : le fichier « .gitignore » (attention au point au début du nom).
« .gitignore » se place à la racine du dépôt, à côté du dossier « .git » (et non dedans). Il s’agit d’un fichier texte ordinaire mais caché, et sur chaque ligne vous pouvez mettre un nom de fichier que vous ne voulez jamais sauvegarder dans le dépôt. On peut utiliser l’étoile (*) comme joker.
Créez ce fichier (il n’existe pas par défaut), et ajoutez « *~ » sur la première ligne pour éviter la sauvegarde de tous ces fichiers temporaires.
Maintenant vous pouvez faire un « git add . » sans arrières pensées.
Comme « .gitignore » est un fichier ordinaire, il peut être ajouté au dépôt. Ce n’est pas obligatoire mais chaudement recommandé si vous souhaitez partager cette liste avec les autres développeur.
Donc :
$ git add . $ git commit -m "Ajout du .gitignore" [master e3bfc5d] Ajout du .gitignore 1 files changed, 1 insertions(+), 0 deletions(-) create mode 100644 .gitignore
Jouons un peut avec les modifications
Modifions maintenant les fichiers. Supprimons le fichier « README.txt » (qui lit encore la doc de nos jours de toute façon ?), et ajoutons une ligne dans le « TODO.txt » qui devient :
- Maîtriser Git.
- Devenir un expert en Python.
- Créer mon premier site avec Django.
- Penser "ergonomie" dès le départ pour mon prochain dév.
On peut voir les modifications faites depuis le dernier commit grâce à la commande « git status » :
$ git status # On branch master # Changed but not updated: # (use "git add/rm <file>..." to update what will be committed) # (use "git checkout -- <file>..." to discard changes in working directory) # # deleted: README.txt # modified: TODO.txt # no changes added to commit (use "git add" and/or "git commit -a")
Les utilisateur de SVN noterons que même si on utilise pas « git rm », Git comprend tout de même que le fichier a été supprimé.
Ajoutons un fichier « test.txt » (créez le normalement) :
$ git status # On branch master # Changed but not updated: # (use "git add/rm <file>..." to update what will be committed) # (use "git checkout -- <file>..." to discard changes in working directory) # # deleted: README.txt # modified: TODO.txt # # Untracked files: # (use "git add <file>..." to include in what will be committed) # # test.txt no changes added to commit (use "git add" and/or "git commit -a")
Deux grandes colonnes sont apparues. « Changed but not updated » correspond aux modifications effectuées sur des fichiers qui sont déjà pris en compte par Git. « Untracked files » liste les fichiers dont Git n’a encore jamais sauvegardé aucune modification.
Comme « git add » n’ajoute pas des fichiers, mais des modifications, on peut utiliser cette commande à la fois pour dire à Git de prendre en compte la création de « test.txt », mais aussi nos derniers changements :
$ git add . $ git status # On branch master # Changes to be committed: # (use "git reset HEAD <file>..." to unstage) # # modified: TODO.txt # new file: test.txt # # Changed but not updated: # (use "git add/rm <file>..." to update what will be committed) # (use "git checkout -- <file>..." to discard changes in working directory) # # deleted: README.txt #
« Changes to be committed » contient maintenant la liste des changements qui seront sauvegardés si vous faites un commit. Si vous ne faites pas de commit, vous pouvez dire à Git de ne pas sauvegarder ces changement toute de suite.
Par exemple, vous ne voulez pas sauvegarde les changements faits sur « TODO.txt » immédiatement, dans ce cas vous pouvez faire « git reset » (nous verrons « reset » en détails dans un autre tuto) :
$ git reset HEAD TODO.txt Unstaged changes after reset: M README.txt M TODO.txt
« TODO.txt » passent de la colonne « Changes to be committed » à « Changed but not updated » :
$ git status # On branch master # Changes to be committed: # (use "git reset HEAD <file>..." to unstage) # # new file: test.txt # # Changed but not updated: # (use "git add/rm <file>..." to update what will be committed) # (use "git checkout -- <file>..." to discard changes in working directory) # # deleted: README.txt # modified: TODO.txt #
Cette colonne contient tout ce que vous avez modifié mais que vous ne voulez pas encore sauvegarder. C’est exacte, vous pouvez très bien faire un commit qui ne sauvegarde que certaines modifications.
Vous noterez de plus que notre suppression de « README.txt » est bien détectée, mais pas ajoutée automatiquement pas le « git add » à la liste des choses à sauvegarder. C’est une protection pour vous éviter de bourrinement valider une suppression. Il faut la confirmer avec « git rm ». Contrairement à SVN, Git vous laisse utiliser « git rm » a posteriori sans tiquer :
$ git rm README.txt rm 'README.txt' $ git status # On branch master # Changes to be committed: # (use "git reset HEAD <file>..." to unstage) # # deleted: README.txt # new file: test.txt # # Changed but not updated: # (use "git add <file>..." to update what will be committed) # (use "git checkout -- <file>..." to discard changes in working directory) # # modified: TODO.txt #
Nous pouvons maintenant joyeusement sauvegarder nos modifications :
$ git commit -m "Ajout d'un fichier et suppression d'un autre" [master 9f2f748] Ajout d'un fichier et suppression d'un autre 1 files changed, 0 insertions(+), 1 deletions(-) delete mode 100755 README.txt create mode 100644 test.txt
Le modification de « TODO.txt » n’a pas été sauvegardée par Git :
$ git status # On branch master # Changed but not updated: # (use "git add <file>..." to update what will be committed) # (use "git checkout -- <file>..." to discard changes in working directory) # # modified: TODO.txt #
Vous pouvez voir l’historique des commits en utilisant la commande « git log » :
$ git log commit 9f2f748ecb853a1cb616b6d387f7169dac32f243 Author: ksamuel <mail@e-vidence.net> Date: Sat Mar 27 19:12:18 2010 +0000 Ajout d'un fichier et suppression d'un autre commit e3bfc5d3457756d695bbed735ea018559d8b00cd Author: ksamuel < mail@e-vidence.net> Date: Sat Mar 27 18:52:12 2010 +0000 Ajout du .gitignore commit bbfc3cf5ef3f93c4aab17b39193907a047b5617b Author: ksamuel < mail@e-vidence.net> Date: Sat Mar 27 18:34:49 2010 +0000 Ceci est un commentaire
Le log permet de voir rapidement le nombre de commit, la date, et l’auteur des modifications. C’est un aperçu de l’historique de Git. On voit ici toute la valeur des commentaires qui permettent de comprendre rapidement de quoi il est question.
Il est possible de change son nom, son email, et aussi la manière dont s’affiche le log, mais ce sera pour plus tard.
Pour les utilisateur de GNU/Linux, sachez que vous avez la commande « tig » qui vous permet de naviguer très facilement dans le log. Sous Ubuntu, installer « tig » est un simple « apt-get ».
Finalement, ajoutons les modifications faites à « TODO.txt » :
$ git add TODO.txt $ git status # On branch master # Changes to be committed: # (use "git reset HEAD <file>..." to unstage) # # modified: TODO.txt # $ git commit -m "Finalement le TODO est bien comme ça" [master edfb9d2] Finalement le TODO est bien comme ça 1 files changed, 1 insertions(+), 0 deletions(-) $ git log commit edfb9d255b7a77b7babeaeda3ea6630b38ca1231 Author: ksamuel <mail@e-vidence.net> Date: Sat Mar 27 19:19:33 2010 +0000 Finalement le TODO est bien comme ça commit 9f2f748ecb853a1cb616b6d387f7169dac32f243 Author: ksamuel <mail@e-vidence.net> Date: Sat Mar 27 19:12:18 2010 +0000 Ajout d'un fichier et suppression d'un autre commit e3bfc5d3457756d695bbed735ea018559d8b00cd Author: ksamuel <mail@e-vidence.net> Date: Sat Mar 27 18:52:12 2010 +0000 Ajout du .gitignore commit bbfc3cf5ef3f93c4aab17b39193907a047b5617b Author: ksamuel <mail@e-vidence.net> Date: Sat Mar 27 18:34:49 2010 +0000 Ceci est un commentaire
Dense n’est-ce pas ? C’est sans doute le plus gros défaut de Git : la masse d’informations qu’il vous demande de gérer en plus au début. Une fois qu’on maîtrise le concept, ce n’est plus un problème car ces informations font partie de votre work flow, mais au début c’est un poids en plus, et il faudra patienter un peu avec que cela devienne naturel.
Encore une fois par rapport à SVN vous noterez les différences suivantes :
- Git vous oblige à une étape intermédiaire entre vos modifications et la sauvegarde : vous devez sélectionner explicitement ce que vous voulez sauvegarder. Le bon côté, c’est que vous pouvez facilement sauvegarder des modifications et pas d’autres. Le côté ennuyeux, c’est que c’est une étape qu’on ne peut pas sauter.
- Git vous permet de supprimer les fichiers sans paniquer.
- Le commit de Git sauvegarde les modifications en local, pas sur un serveur distant. Vous pouvez le faire au milieu du désert si vous le souhaitez.
Comprendre ce qui vient de se passer
Vous avez fait 4 commit, et il y a donc maintenant 4 « changesets » dans l’historique de votre dépôt.
Vous pouvez voir ces changesets avec « git log », le plus récent étant le premier affiché. :
$ git log commit edfb9d255b7a77b7babeaeda3ea6630b38ca1231 Author: ksamuel <mail@e-vidence.net> Date: Sat Mar 27 19:19:33 2010 +0000 Finalement le TODO est bien comme ça commit 9f2f748ecb853a1cb616b6d387f7169dac32f243 Author: ksamuel <mail@e-vidence.net> Date: Sat Mar 27 19:12:18 2010 +0000 Ajout d'un fichier et suppression d'un autre commit e3bfc5d3457756d695bbed735ea018559d8b00cd Author: ksamuel <mail@e-vidence.net> Date: Sat Mar 27 18:52:12 2010 +0000 Ajout du .gitignore commit bbfc3cf5ef3f93c4aab17b39193907a047b5617b Author: ksamuel <mail@e-vidence.net> Date: Sat Mar 27 18:34:49 2010 +0000 Ceci est un commentaire
Vous noterez la ligne « commit edfb9d255b7a77b7babeaeda3ea6630b38ca1231 ». Le code étrange à côté du mot « commit » est “le nom” du changeset, son identifiant unique, aussi appelé « hash ». Si vous voulez vous référer à un changeset en particulier, notez ce hasg (il est différent pour vous et moi car nous n’avons pas le même dépôt).
Vous pouvez voir quelle est la différence entre un changeset et un autre avec « git diff », et cette commande attend le hash d’un autre changeset. Par exemple, pour voir quel sont les différences entre ce qu’il y a maintenant dans notre projet et ce qu’il y avait dans le commit « Ajout d’un fichier et suppression d’un autre » :
$ git diff 9f2f748ecb853a1cb616b6d387f7169dac32f243 diff --git a/TODO.txt b/TODO.txt index 664dc6b..a85daaf 100755 --- a/TODO.txt +++ b/TODO.txt @@ -1,3 +1,4 @@ +- Maîtriser Git. - Devenir un expert en Python. - Créer mon premier site avec Django. - Penser "ergonomie" dès le départ pour mon prochain dév.
Pour déchiffrer ce message, il faut le couper en deux :
diff --git a/TODO.txt b/TODO.txt
index 664dc6b..a85daaf 100755
--- a/TODO.txt
+++ b/TODO.txt
@@ -1,3 +1,4 @@
Indique de quoi on va parler. Ici, il que l’on va voir les modification apportées à « TODO.txt ». Ensuite :
+- Maîtriser Git.
- Devenir un expert en Python.
- Créer mon premier site avec Django.
- Penser "ergonomie" dès le départ pour mon prochain dév.
Est le contenu du fichier lui-même, annoté pour montrer où se situent les ajouts (+) et les retraits (-). Ici c’est un peut confus car mes lignes commences déjà par « - »
Il existe par ailleurs des moyens plus confortables de voir les différences et les status, mais ce n’est pas l’objet du jour.
Ok, on voit ce qui s’est passé dans notre projet, mais comment Git voit-il tout cela ? Réponse en schémas :
Comme vous le voyez, chaque changeset n’est pas indépendant, mais pointe vers un autre et le sens de la flèche est contre intuitif.
On pourrait penser que la flèche pointe vers le changeset suivant, en fait, pas du tout : chaque changeset pointe vers son « parent », c’est à dire le changeset précédent. En effet, il applique des modifications sur son parent.
On peut donc lire le diagramme ci-dessus comme :
« Finalement le TODO est bien comme ça » est une série de modification sur « Ajout d’un fichier et suppression d’un autre » qui est une série de modifications sur « Ajout du .gitignore » qui est une série de modifications sur « Ceci est un commentaire ».
Git conserve un historique de modifications, et l’unité est un groupe de modifications. Utiliser Git, ce n’est rien d’autre dire où l’on se trouve dans l’historique. En clair, contrairement à SVN, on ne dit pas «j’ai tels fichiers à ma disposition maintenant » mais, « je me trouve à tel changeset dans l’historique ».
Cela signifie qu’il y a dans Git, en permanence, un pointeur pour dire où vous êtes. L’historique ne bouge pas, c’est vous qui bougez !
Ce pointeur, Git l’appelle « HEAD », et ce n’est ni plus ni moins qu’un qu’un gros panneau qui vous dit « vous êtes ici » :
« HEAD » ne contient rien. « HEAD » est juste un marqueur pour vous indiquez votre position dans l’historique. Quand plus tard vous apprendrez à revenir en arrière, l’historique ne bougera pas, c’est vous qui bougerez :
Ne pas confondre Index, HEAD et la copie de travail
Les schémas que vous venez de voir sont incomplets, car Git possède une grande subtilité qu’il faut absolument comprendre pour pouvoir l’utiliser : vous ne travaillez jamais sur « HEAD ».
« HEAD » est le marqueur qui vous indique où vous vous trouvez dans l’historique, il serait donc normal de penser que c’est là où l’on travail. Pas du tout.
« HEAD » pointe sur le dernier changeset, qui est une copie immuable et on ne peut pas la modifier.
Mais alors, dans quoi travaille-t-on ?
Et bien Git ajoute deux notions supplémentaires :
- la copie de travail;
- l’index.
La copie de travail, c’est votre projet tel que vous pouvez le voir. Ce sont les fichiers que vous modifiez, supprimez, ajoutez. Ces fichiers ne sont pas sauvegardés dans Git. Ce sont des fichiers normaux, et si vous faites une modifications sur un fichier puis que vous le supprimez avant de faire un commit, les modifications seront perdues.
En clair, vous travaillez toujours en dehors de Git.
Git ne vous permet pas de travailler dans son historique, il vous permet juste :
- d’ajouter des modifications;
- de récupérer des modifications;
- de vous déplacer dans les modifications.
Un changeset ne se modifie pas (en tout cas, pas comme vous le pensez), et on à jamais accès directement à « HEAD ». « HEAD » pointe sur un changeset, qui est une boîte, un coffre fort qui contient et protège les dernières modifications enregistrées.
Mais alors pourquoi mettre un panneau « vous êtes ici » si vous n’êtes pas vraiment ici ? Et bien vous êtes ici au sens Git du terme, c’est à dire que c’est ici, sur ce changeset, que se rajoutera votre prochain commit.
Nous avons donc deux choses importantes :
- L’historique : une liste de changesets dans laquelle on peut se promener mais qu’on ne peut pas modifier. On peut juste lui rajouter un nouveau changeset.
- La copie de travail : votre projet, des fichiers normaux, modifiables, et complètement en dehors de Git.
Mais alors, à quoi sert l’index ?
Il s’agit tout simplement de l’étape qui vous permet de faire passer vos modifications hors de Git, dans Git.
L’index, ce changeset mal connu
Concentrez vous bien sur cette partie parce que c’est la notion qu’il manque à la plupart des utilisateurs de Git en péril. Si vous comprenez ça, la suite sera facile.
L’index est un changeset, au même titre que tous les autres, mais il a deux particularités :
- Il est modifiable par les commandes « add », « rm » et « reset »;
- Il n’est pas inclus dans l’historique Git.
L’index est juste une étape intermédiaire qui vous permet de dire, « voilà à quoi doit ressembler mon prochain changeset dans l’historique si je fais un commit ». C’est un outil qu’on peut modifier à loisir, remettre à zéro, casser, reconstruire, démolir, etc.
Voici donc un schéma plus complet du fonctionnement de Git :
A chaque commit, l’index est sauvegardé par dessus le changeset sur lequel pointe « HEAD », puis « HEAD » est déplacé sur le nouveau changeset :
Un peu de pratique
Modifiez TODO.TXT pour qu’il ressemble à ceci :
- Maîtriser Git.
- Mettre un commentaire sur ce tuto parce qu'il est pas mal quand même.
- Devenir un expert en Python.
- Créer mon premier site avec Django.
- Penser "ergonomie" dès le départ pour mon prochain dév.
Supprimez aussi le fichier « tuto.txt ».
Vous allez voir « git status » d’un nouvel oeil :
$ git status # On branch master # Changed but not updated: # (use "git add <file>..." to update what will be committed) # (use "git checkout -- <file>..." to discard changes in working directory) # # modified: TODO.txt # deleted: tuto.txt #
« Changed but not updated » veut dire « changé dans la copie de travail mais pas dans l’index ». En gros, vous avez modifié des fichiers, mais vous n’avez pas ajouté ces modifications dans l’index. Ce que l’on fait avec « git add/rm » :
$ git add TODO.txt $ git rm tuto.txt rm 'tuto.txt' $ git status # On branch master # Changes to be committed: # (use "git reset HEAD <file>..." to unstage) # # modified: TODO.txt # deleted: tuto.txt #
« Changes to be committed » veut dire, « ces modification sont dans l’index, elles seront sauvegardées au prochain commit ». On peut choisir qu’une de ces modifications ne soit pas appliquée :
$ git reset HEAD TODO.txt Unstaged changes after reset: M TODO.txt
« git reset » remplace la modification de « TODO.txt » de l’index par l’état de « TODO.txt » qui se trouvait dans « HEAD ».
$ git status # On branch master # Changes to be committed: # (use "git reset HEAD <file>..." to unstage) # # deleted: tuto.txt # # Changed but not updated: # (use "git add <file>..." to update what will be committed) # (use "git checkout -- <file>..." to discard changes in working directory) # # modified: TODO.txt #
Pour l’instant, rien n’est sauvegardé :
$ git log commit edfb9d255b7a77b7babeaeda3ea6630b38ca1231 Author: ksamuel <mail@e-vidence.net> Date: Sat Mar 27 19:19:33 2010 +0000 Finalement le TODO est bien comme ça […]
On commit :
$ git commit -m "On sauvegarde l'index dans l'historique" [master 1a0633c] On sauvegarde l'index dans l'historique 1 files changed, 0 insertions(+), 1 deletions(-) delete mode 100755 tuto.txt
Les modifications de l’index sont maintenant dans l’historique et « HEAD » pointe dessus :
$ git log commit 1a0633ce778044aadea23eb39cdc21fc6c949989 Author: ksamuel <mail@e-vidence.net> Date: Sat Mar 27 21:08:04 2010 +0000 On sauvegarde l'index dans l'historique commit edfb9d255b7a77b7babeaeda3ea6630b38ca1231 Author: ksamuel <mail@e-vidence.net> Date: Sat Mar 27 19:19:33 2010 +0000 Finalement le TODO est bien comme ça […]
Git est complexe mais pas compliqué
Si vous avez bien suivi le tuto, vous devriez maintenant comprendre, non seulement le principe de modifier / sauvegarder, mais aussi ce que fait Git derrière quand vous lui demandez de telles actions.
Ce n’est pas difficile à comprendre, mais c’est beaucoup d’informations à retenir comme en témoigne ce long tuto. Malgré cela, les explications que l’on trouve sur le net sont généralement très incomplètes ou nébuleuses, et j’espère donc que cet article vous aura réconcilié avec ce merveilleux outil qu’est Git.
Dans le prochain tuto, nous verrons comment revenir en arrière avec Git quand on a fait des modifications qui ne nous plaisent pas à l’aide des commande « checkout » et « reset ».





30/03/2010 à 12:50
[...] E-vidence « Introduction à Git pour les gens normaux [...]
31/03/2010 à 12:49
Ce super. ce tuto me débarrasse de beaucoup de zone d’ombre dans GIT.
12/04/2010 à 19:07
[...] web commence a recevoir de nombreux tutos sur cet outil (par ex, ce site.) Il est possible de configurer à sa sauce git avec un fichier .gitconfig (un bon moteur de [...]
14/04/2010 à 16:48
Merci pour ce tuto