Débuter avec Git partie 3 : un commit plus complexe

Après avoir réalisé notre premier commit, nous continuons cette série d’articles pour débuter avec Git en nous intéressant aux différentes opérations possibles pour réaliser un commit plus complexe que le simple ajout d’un fichier.

Objectif

Pour bien débuter avec Git, nous avons vu dans le précédent article comment réaliser un commit très simple, consistant à enregistrer un seul fichier. Nous irons aujourd’hui plus loin pour coller davantage à la complexité du monde réel en constituant un nouveau commit avec plusieurs modifications différentes issues de plusieurs fichiers.

État initial du dépôt

Nous allons commencer avec un dépôt Git contenant un seul fichier texte nommé README qui est assez long.

$ cd commit-complexe
$ ls
README
$ wc -l README 
19 README

Premiers changements

Nous allons ajouter sur la première ligne la phrase “do not forget to read the file foo!” et sur la dernière ligne la phrase “do not forget to read the file bar”.

Voyons maintenant les modifications par rapport au commit précédent :

$ cd commit-complexe
$ git diff
diff --git a/README b/README
index d012f47..737bc05 100644
--- a/README
+++ b/README
@@ -1,5 +1,7 @@
this is a README

+do not forget to read the file foo!
+
Lots of interesting stuff here

Let's work
@@ -17,3 +19,5 @@ These criteria eliminated every then-extant version-control system, so immediate
The development of Git began on 3 April 2005.[16] Torvalds announced the project on 6 April;[17] it became self-hosting as of 7 April.[16] The first merge of multiple branches took place on 18 April.[18] Torvalds achieved his performance goals; on 29 April, the nascent Git was benchmarked recording patches to the Linux kernel tree at the rate of 6.7 patches per second.[19] On 16 June Git managed the kernel 2.6.12 release.[20]

Torvalds turned over maintenance on 26 July 2005 to Junio Hamano, a major contributor to the project.[21] Hamano was responsible for the 1.0 release on 21 December 2005 and remains the project's maintainer.[22] 
+
+To finish, do not forget to read file bar!

Git nous indique les changements intervenus avec des + devant les ajouts. Nous avons donc rajouté deux lignes et deux sauts de lignes.

Choix de ce qu’on souhaite mettre dans son commit : l’index

Bien, il nous reste maintenant à écrire les nouveaux fichiers foo et bar. Mais il est 19h, je suis fatigué et je ne vais avoir le temps que d’écrire le premier fichier foo. Nous procédons comme suit pour écrire et ajouter le fichier foo :

$ echo "very interesting stuff" > foo
$ cat foo 
very interesting stuff

Une fois créé, nous indiquons à Git que nous souhaitons que ce nouveau fichier soit pris en compte au prochain commit. On appelle cette opération indexer un fichier :

$ git add foo

Une furieuse envie d’enregistrer le travail en cours en faisant un git commit -a est notre premier réflexe, mais le fichier README va donc évoquer un fichier bar qui n’existe pas encore dans le dépôt. Ce n’est pas propre, surtout si un collègue relit immédiatement mon travail.

Dans notre situation, la solution est de choisir ce que l’on veut ajouter au commit, c’est à dire le fichier foo (ce que nous venons de faire) et seulement une partie des modifications du fichier README. C’est possible avec l’option –patch ou -p de git add qui va nous permettre d’indexer seulement les modifications qui nous intéressent pour préparer le prochain commit.

$ git add -p README

La commande va identifier vos différentes modifications du fichier en question et vous demander lesquelles vous souhaitez indexer pour le prochain commit.

@@ -1,5 +1,7 @@
this is a README

+do not forget to read the file foo!
+
Lots of interesting stuff here

Let's work
Stage this hunk [y,n,q,a,d,j,J,g,/,e,?]? y

Cette commande nous présente notre première modification dans le fichier README. Un hunk est ici donc une modification unitaire identifiée par Git. Le contenu ajouté apparaît avec un symbole + en tout début de ligne. Nous acceptons d’indexer la première modification en appuyant sur y (yes).

+
+To finish, do not forget to read file bar!
Stage this hunk [y,n,q,a,d,K,g,/,e,?]? n

Git nous affiche ensuite la seconde modification identifiée dans le fichier. Nous refusons la seconde en appuyant sur n (no), que nous ajouterons demain quand nous aurons écrit le fameux fichier bar dans un futur commit, parce qu’il est 19h et qu’à chaque jour suffit sa peine.

L’index avant le commit

Bien, après cette sélection, où en sommes-nous ? Un git status va nous aider.

$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)

modified: README
new file: foo

Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)

modified: README

La commande est très claire si on la lit rigoureusement : sur la branche master, les modifications suivantes sont prêtes à être committées : le fichier README a été modifié et un nouveau fichier foo a été créé.

Git nous indique également qu’un changement est survenu mais qu’il n’a pas été indexé (sous la phrase Changes not staged for commit) : c’est le fameux changement que nous souhaitons faire demain.

Le commit lui-même

Il est grand temps de valider nos modifications et de créer un commit. Il ne faut ici surtout pas utiliser l’option -a de git commit sous peine de valider indistinctement toutes les modifications présentes dans le dépôt, ce que nous ne voulons absolument pas faire.

On va vérifier puis valider notre commit grâce à la commande suivante :

$ git commit -v

Un éditeur de texte s’ouvre et nous affiche la sortie suivante :

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# On branch master
# Changes to be committed:
# modified: README
# new file: foo
#
# Changes not staged for commit:
# modified: README
#
# ------------------------ >8 ------------------------
# Do not modify or remove the line above.
# Everything below it will be ignored.
diff --git a/README b/README
index d012f47..6c50e6b 100644
--- a/README
+++ b/README
@@ -1,5 +1,7 @@
this is a README

+do not forget to read the file foo!
+
Lots of interesting stuff here

Let's work
diff --git a/foo b/foo
new file mode 100644
index 0000000..7c50c6a
--- /dev/null
+++ b/foo
@@ -0,0 +1 @@
+very interesting stuff

Nous retrouvons ici le résultat du précédent git status et le détail des modifications qui vont être validées. Nous remarquons que seule la mention du fichier foo dans le README et la création de ce fichier foo y figurent. Nous avons donc réussi notre commit.

Si ça n’était pas le cas, vous pouvez quitter votre éditeur de texte sans enregistrer, cela annulera le commit. Si tout est bon, entrez simplement un message de commit pertinent comme “mention foo in README and add the foo file” et sauvegardez.

Le résultat de la commande est le suivant :

$ git commit -v
[master 077f1f6] mention foo in README and add the foo file
2 files changed, 3 insertions(+)
create mode 100644 foo

Nous voyons notre message de validation et également que deux fichiers ont été modifiés.

État de notre dépôt après ce commit

Dans quel état est notre dépôt après ce commit ? Encore une fois l’analyse de la commande git status va nous aider.

$ git status
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)

modified: README

no changes added to commit (use "git add" and/or "git commit -a")

En effet nous avons la seconde modification du fichier README que nous avions faite qui n’a pas encore été enregistrée dans aucun commit. Nous n’avons pas indexé cette modification. Elle demeure donc dans notre dépôt en attente d’un prochain traitement.

Un git diff nous montre cette modification :

$ git diff
diff --git a/README b/README
index 6c50e6b..737bc05 100644
+
+To finish, do not forget to read file bar!

Il s’agit bien de la modification que nous ne souhaitions pas encore enregistrer (j’ai simplifié l’affichage de la commande précédente pour aller à l’essentiel).

Sauvegarde du travail

Nous avons un beau commit, mais il n’existe pour l’instant que sur notre ordinateur personnel. Un malheureux accident ou un vol est si vite arrivé, il est indispensable de sauver notre travail sur notre dépôt Git distant (voir la création du dépôt distant dans la partie 1). Nous procédons avec un simple git push vers notre dépôt distant:

$ git push

Conclusion

Bien débuter avec Git nécessite de comprendre ce que l’on fait et pour cela nous abordons les notions fondamentales une par une.

La notion essentielle abordée aujourd’hui est l’ajout de modifications à l’index. L’index constitue l’ensemble des modifications à prendre en compte dans le prochain commit. Nos modifications ont donc pour l’instant 3 statuts possible dans Git : non-indexées, indexées ou enregistrées dans un commit. À chaque statut correspond une palette d’opérations possibles et Git vous tient en permanence au courant du statut de vos différentes modifications en cours, en vous proposant souvent des actions possibles.

Nous aborderons bientôt dans un prochain article une autre notion fondamentale de Git : les branches.

Me suivre sur les réseaux sociaux

N’hésitez pas à me suivre directement sur les différents sociaux pour suivre au jour le jour mes différentes projets dans le Logiciel Libre :

Suivre l’actualité du Logiciel Libre et Open Source francophone

Abonnez-vous au Courrier du hacker, une newsletter hebdomadaire résumant le meilleur de l’actualité francophone du Logiciel Libre et Open Source. Déjà plus de 80 numéros et 2000 abonnés.

One thought on “Débuter avec Git partie 3 : un commit plus complexe

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *