Git/Premiers pas
Préalable
modifierNous allons maintenant entrer dans le vif du sujet et faire une première modification dans le code source d'une application.
Cette première expérience va nous permettre de découvrir plusieurs notions importantes : l'espace de travail et l'index.
On reprend l'exemple précédent.
git clone https://gerrit.wikimedia.org/r/p/test/mediawiki/extensions/examples.git
cd examples
Faisons d'abord un
git branch
qui va nous répondre
* master
Git nous indique qu'il existe une seule branche appelée master
et que c'est sur cette branche que nous travaillons comme l'indique l'astérisque en face de master
.
Cela nous est confirmé par
git status
qui nous répond
# On branch master nothing to commit, working directory clean
Vous pouvez faire un
git log
Pour voir quel est l'auteur et la date de la dernière modification : cela nous servira de repère pour la suite.
Ajouter un fichier dans la zone de transit
modifierCommençons par une modification simple : l'ajout d'un fichier dans la staging area (la zone de transit vers la sauvegarde). Cela peut être une première étape si vous avez créer un dépôt vide.
Par exemple, créons un fichier mon_nouveau_fichier.txt
avec un petit texte dedans.
echo "Ceci est un test de git" > mon_nouveau_fichier.txt
Voyons la façon dont git perçoit ce nouveau fichier
git status
# On branch master # Untracked files: # (use "git add <file>..." to include in what will be committed) # # mon_nouveau_fichier.txt nothing added to commit but untracked files present (use "git add" to track)
Il nous indique qu'on est toujours sur la branche master
, qu'il y a un fichier mon_nouveau_fichier.txt
mais qu'il n'est pas suivi (« untracked ») par git.
Comme nous voulons intégrer ce fichier au projet, on ne peut pas encore faire le commit
, car commit
n'envoie que les fichiers qui sont *tracked*, c'est à dire dans l'index (*staging*). Ajoutons le fichier, comme git nous le suggère, avec add
git add mon_nouveau_fichier.txt
On refait un
git status
Et, cette fois, git nous répond
# On branch master # Changes to be committed: # (use "git reset HEAD <file>..." to unstage) # # new file: mon_nouveau_fichier.txt #
Le fichier mon_nouveau_fichier.txt
sera bien intégré dans notre prochain commit
. Allons-y :
git commit -m "mon premier commit"
Remarquons ici qu'avec -m
, nous avons choisi de préciser le message de commit directement sur la ligne de commande. En lançant git commit
tout court, l'éditeur de texte ($EDITOR
) s'ouvre automatiquement pour inviter à saisir un commentaire de soumission.
[master 17eaa3e] mon premier commit 1 file changed, 1 insertion(+) create mode 100644 mon_nouveau_fichier.txt
Constatons immédiatement l'effet de ce commit :
git log
Notre dernier commit apparaît, en premier de la liste (c'est le plus récent).
commit 17eaa3e060b29d708a87867dcb725b7ec64ffaeb Author: Michel Boudran <michel.boudran@fr.wikibooks.org> Date: Tue Jul 22 22:00:39 2014 +0200 mon premier commit
Avec
git log --graph
On voit clairement que notre commit est lié au commit précédent.
Modifier un fichier
modifierFaisons une autre modification. Par exemple, modifions le fichier mon_nouveau_fichier.txt
en ajoutant une ligne.
echo "Une seconde ligne pour un second test de git" >> mon_nouveau_fichier.txt
Voyons ce que git nous dit :
git status
# On branch master # Your branch is ahead of 'origin/master' by 1 commit. # (use "git push" to publish your local commits) # # 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: mon_nouveau_fichier.txt # no changes added to commit (use "git add" and/or "git commit -a")
diff
modifierGit nous indique bien que le fichier a été modifié, voyons le résumé de ces modifications telles qu'elles sont perçues par git :
git diff
diff --git a/mon_nouveau_fichier.txt b/mon_nouveau_fichier.txt index a031263..762359c 100644 --- a/mon_nouveau_fichier.txt +++ b/mon_nouveau_fichier.txt @@ -1 +1,2 @@ Ceci est un test de git +Une seconde ligne pour un second test de git
Git nous montre la ligne qui a été ajoutée (le « + » en début de ligne).
Pour comparer une branche distante avec une locale, utiliser ".." :
git diff origin/master..master
sinon :
git diff master origin/master
add
modifierOn va maintenant faire le commit. Comme précédemment, il faut ajouter le fichier au *staging* :
git add mon_nouveau_fichier.txt
Si vous voulez ajouter au staging tous les changements qui ont été effectués (fichiers ajoutés, modifiés, supprimés), il vous suffit de faire[1]
git add --all
ou
git add -A
// ou
git add .
git status
# On branch master # Your branch is ahead of 'origin/master' by 1 commit. # (use "git push" to publish your local commits) # # Changes to be committed: # (use "git reset HEAD <file>..." to unstage) # # modified: mon_nouveau_fichier.txt #
commit
modifiergit commit -m "ma première modification"
[master 5556307] ma première modification 1 file changed, 1 insertion(+)
Remarquez le code « 5556307 » : il s'agit d'une abréviation de l'identifiant unique de l'objet Git (en l'occurrence une soumission). Chaque objet est haché en SHA-1. L'identifiant complet est en fait 5556307824d8d0425b38c9da696b84430e30f09f
, mais généralement les huit premiers caractères suffisent à l'identifier à coup sûr.
git log --graph
* commit 5556307824d8d0425b38c9da696b84430e30f09f | Author: Michel Boudran <michel.boudran@fr.wikibooks.org> | Date: Tue Jul 22 22:18:08 2014 +0200 | | ma première modification | * commit 17eaa3e060b29d708a87867dcb725b7ec64ffaeb | Author: Michel Boudran <michel.boudran@fr.wikibooks.org> | Date: Tue Jul 22 22:00:39 2014 +0200 | | mon premier commit |
On voit bien que nos deux commits se succèdent.
Supprimer un fichier
modifiergit rm mon_nouveau_fichier.txt
git status
# On branch master # Your branch is ahead of 'origin/master' by 2 commits. # (use "git push" to publish your local commits) # # Changes to be committed: # (use "git reset HEAD <file>..." to unstage) # # deleted: mon_nouveau_fichier.txt #
Il n'est pas nécessaire de faire un add.
git commit -m "ma première suppression de fichier"
[master 77ea581] ma première suppression de fichier 1 file changed, 2 deletions(-) delete mode 100644 mon_nouveau_fichier.txt
Annuler une suppression
modifierCertains outils comme PyCharm sont dotés d'un historique local (en plus de celui de Git) qui permet d'annuler un "git rm". Il est accessible via un clic droit sur le dossier à restaurer.
Regrouper des modifications
modifierIl est possible de fusionner une soumission avec la dernière révision, via l'argument amend, sans avoir à réécrire leur résumé avec no-edit :
git commit --amend --no-edit
Généralement on l'utilise pour mettre à jour un commit :
git add -A && git commit --amend --no-edit && git push -f
Si la cible n'est pas la dernière révision, on peut annuler les intermédiaires (via git reset) jusqu'à ce qu'elle le devienne, puis ensuite, replacer les commits annulés avec :
git cherry-pick xxx
(où xxx est l'ID du commit)
Par ailleurs, certains logiciels clients Git permettent de rassembler plusieurs révisions sélectionnées depuis une liste, comme la fonction cherry-pick de SmartGit ou NetBeans qui permet de sélectionner des commits existant pour les intégrer à sa branche, ou git blame pour afficher les auteurs de chaque passage.
En console, annuler ou modifier un commit peut être réalisé de plusieurs manières :
git commit --amend --no-edit
git reset HEAD~1
git rebase -i
(puis squash)
En cas de réécriture d'historique, le hash du commit change, ce qui ne pose pas de problème en local mais complexifie considérablement les rebases des branches issues de celle réécrite, car Git voit des conflits entre le commit original et celui réécrit[2].
Pour modifier le résumé d'un ancien commit (xxx) : git rebase --interactive 'xxx^'
Il faut donc éviter de les multiplier : ne pas en enchainer plusieurs avec le même résultats, ou en créer des “fix” du précédent. Il faut les casser et les regrouper. Ainsi les rebase auront moins de conflit, les git blame seront parlant et les git revert de feature deviendront possibles. Dans cette optique, il faut d'ailleurs préférer les rebases aux merges pour éviter l'ajout d'un commit de merge inutile nuisant à la lisibilité et à la taille du dépôt.
Enfin, éviter d’embarquer dans un commit un fichier qui ne contient qu’une modification d’espace ou de retour chariot pour limiter les tailles d’historique et les conflits de merge.Recherche dans l'historique
modifierPour rechercher un mot dans tous les historiques de tous les fichiers (du répertoire et des sous-répertoires du script) :
git rev-list --all | (
while read revision; do
git grep -F 'mon_mot_clé' $revision
done
)
Par ailleurs, git bisect
permet de rechercher dans l'historique des révisions en définissant les mauvais et bon commits[3].
Continuer
modifierVous maîtrisez désormais le strict minimum pour travailler avec git. Vous pouvez ajouter, modifier et supprimer des fichier et enregistrer les changements dans votre dépôt local ainsi que consulter l'historique des modifications. Cela reste toutefois une vision simpliste de la gestion de projet et nous verrons dans la suite comment exploiter les branches locales et comment partager votre travail avec d'autres contributeurs en publiant vos modifications sur un dépôt distant et en récupérant les modifications des autres contributeurs.
Références
modifier- ↑ http://git-scm.com/docs/git-add
- ↑ « Rewriting Git History », Git’s now confused
- ↑ https://git-scm.com/docs/git-bisect
- https://learngitbranching.js.org/ : explications schématisées