Cet article présente les commandes GIT que j'utilise au quotidien dans mon métier de développeur JavaScript et TypeScript.
Un peu comme une liste de sorts du monde des sorciers, elles sont peu nombreuses mais extrenement utiles.
Pour expliquer ces commandes, je vais partir du principe que vous avez une branche ‘develop’ qui correspond à votre environnement de pré-recette et que vous travaillez à partir de branches dérivées de ‘develop’.
L’objectif de cet article est de vulgariser l’utilisation des commandes git. S'il est incomplet, contient une information erronée ou une explication trop complexe, nous vous invitons à prendre contact avec nous. Nous ajouterons la modification en vous notifiant.
Les commandes du travail quotidien
git checkout
Cette commande permet de naviguer entre les branches ou d'en créer une avec l’option -b. Elle permet aussi de naviguer entre les commits avec la syntaxe : git checkout <hash_du_commit>, utilisée à la suite de git log.
git add
La commande qui permet d’ajouter un fichier, en spécifiant le chemin du fichier en question. Lorsque le fichier .gitignore est bien paramétré avec les éléments que l’on souhaite ignorer, il est courant d’utiliser simplement git add . pour ajouter tous les nouveaux fichiers créés. L’option --interactive est intéressante ; elle permet de sélectionner les fichiers à ajouter un à un. L’utilisation de l'option interactive peut être assez complexe.
Chacune des commandes vous permet de choisir sur quels fichiers vous souhaitez travailler. Vous pouvez sélectionner plusieurs fichiers en entrant leurs numéros (ou les caractères entre crochets) et en appuyant sur Entrée. Vous pouvez entrer plusieurs numéros/caractères à la fois, séparés par des espaces, ou les ajouter individuellement. Les fichiers sélectionnés sont marqués d'un * devant leur ligne. Laissez la ligne vide et appuyez sur Entrée pour indiquer à Git que vous avez terminé, et il continuera à l'étape suivante, s'il y en a une.
git rm
Cette commande est l’inverse de git add. Elle permet de supprimer un fichier du suivi, ce qui est particulièrement utile en cas d’ajout involontaire (par exemple, les node_modules).
Attention : Pour supprimer de l’index de git sans supprimer du dossier de travail, utilisez l’option --cached.
git commit
Cette commande est probablement la plus utilisée car elle ajoute votre travail à l’index de la branche courante. Il est nécessaire de l’utiliser correctement ; par exemple, on utilise très souvent (toujours dans mon cas) l’option --all pour spécifier que l’on souhaite que tous les changements soient pris en compte. Je ne vais pas entrer dans le détail des bonnes pratiques de commit sur les messages et les changements, mais juste présenter ce que cette commande peut faire.
Elle dispose de nombreuses options, qui ne sont pas toutes utiles en général. Il est possible que chaque ingénieur puisse avoir une préférence, seul le temps vous familiarisera avec les différentes options.
git commit --amend
L’option --amend est particulièrement pratique pour fusionner les changements courants avec le commit précédent. Par exemple, lorsqu’on travaille sur la même granularité de fonctionnalité, on peut réutiliser le dernier commit.
Astuce : la norme est : un commit = un changement, --amend doit être l’exception sauf s'il influence le même changement.
Nous proposons une formation Node.js, où les commandes git sont abordées
git pull
Cette instruction permet de récupérer les mises à jour du repo distant. La syntaxe est git pull origin develop.
git pull --no-rebase
Avec l’option --no-rebase, vous créez un merge commit dans votre branche.
git pull --rebase (--interactive)
Avec --rebase, vous appliquez l’ensemble des commits présents sur ‘develop’ à votre branche, ce qui permet de maintenir l’historique. --rebase doit toujours être privilégié pour conserver la fluidité du travail d’équipe.
L’option --interactive donne la possibilité de réaliser l’opération manuellement, en choisissant les commits à reprendre, ceux à fusionner, etc.
Astuce : lorsqu'on merge une PR, normalement, soit on fusionne les commits (squash) soit on crée un merge commit. Si on revient dessus, pour différentes raisons, la PR en local n’a plus les mêmes commits que sur ‘develop’, l’historique a été perdu. Il faut donc utiliser la commande git pull origin develop --no-rebase pour pouvoir récupérer l’historique sans conflit.
git push
Elle permet d’envoyer ses changements locaux vers le repo distant. Il y a deux options intéressantes : --force et --force-with-lease. Les deux vont forcer la mise à jour du repo distant, particulièrement si l’historique des commits n’est pas le même. On les utilise lorsqu'on rebase et qu'on amende. En effet, on modifie la structure de l’historique des commits, on est donc obligé de forcer. La seconde option est toujours à privilégier car elle ajoute un contrôle supplémentaire : si des pertes de travail sont détectées, elle refusera de s’exécuter.
git log
Cette commande liste les commits sur la branche. Son intérêt réside dans la navigation entre les commits, ce qui est très utile pour identifier un commit responsable d’un bug.
Astuce : La navigation entre les commits est un argument supplémentaire pour utiliser --rebase dans la gestion des branches.
git bisect
Cette commande, combinée à git log, permet d’identifier un commit source d’un bug dans votre projet.
Concrètement, si l’état de votre code est mauvais, avec git checkout, remontez assez loin pour que le bug n’apparaisse pas, copiez et collez le hash de ce commit sans bug. Puis commencez par git bisect start et git bisect bad <hash_du_dernier_commit> et git bisect good <hash_du_commit_bon>.
À partir de maintenant, vous pouvez lancer vos tests et, tant que ceux-ci échouent (le bug est présent), inscrivez git bisect bad. Dès que ceux-ci réussissent (le bug a été introduit), écrivez git bisect good. Git va alors afficher les détails du mauvais commit pour vous aider à le corriger.
Pour stopper git bisect, écrivez git bisect reset.
git blame
Cette commande affiche la révision et l'auteur qui a modifié chaque ligne d'un fichier. Cela permet de comprendre rapidement qui a apporté des modifications spécifiques et pourquoi.
Elle est intégrée par défaut à l’extension git de vscode.
git status et git diff
Ces deux commandes permettent de détailler l’état de ce qui n’est pas dans l’index de git. status donne une indication sur les fichiers et diff liste les différences entre le travail courant et l’index ligne par ligne.
Astuce : Utilisez ces commandes avant de faire add et commit pour bien vérifier que vous n’ajoutez pas de code étrange et parfois non sécurisé à votre branche distante.
git stash
Elle stocke dans un cache le travail non commité et retourne à l’état ‘propre’, sans différence.
On peut accéder au ‘stash’ plus tard via git stash list et les supprimer via git stash clear ou git stash drop.
Astuce : je l’utilise uniquement pour tester des modifications en local. Elle permet surtout de ne pas avoir à effacer manuellement du code que l’on ne veut pas.
git cherry-pick
Elle permet de récupérer un commit spécifique via son hash et de l’appliquer à sa branche.
Astuce : Un argument supplémentaire pour le --rebase et l’atomicité des commits. Elle présente aussi un grand intérêt pour pouvoir créer des branches de recettage qui excluent certaines fonctionnalités.
Notre formation TypeScript, finançable à 100%. Les commande git sont abordées dans cette formation.
git reset
Elle efface votre historique local et replace l’index de git sur la branche racine (HEAD) ou le commit que vous avez spécifié.
Astuce : À manier avec précaution, la suppression est définitive et peut écraser du travail existant. Elle a un intérêt si vous entrez dans un rebase conflictuel, vous pouvez recommencer l’opération.
Les commandes de maintenance
Au-delà des commandes git de travail quotidien, il y a les commandes de maintenance. Celles qui vont augmenter votre productivité et vous faciliter la vie.
git rebase
Bien que potentiellement complexe, git rebase est puissante pour maintenir un historique de projet propre. Elle permet de modifier l'ordre des commits, de les squasher ensemble ou de les modifier, contribuant à une meilleure compréhension et à une révision du code plus aisée.
git branch
Elle affiche les branches de votre repo.
Une option intéressante ici est --delete, très utile lorsqu’on a créé une branche avec un nom inapproprié, ou pour supprimer une branche de test.
git fetch
Cette commande synchronise le repo local avec le repo distant. Si une branche existe en distant mais pas en local, elle sera ajoutée en local.
Fetch a aussi la possibilité de récupérer des éléments d’autres repos distants. Néanmoins, je n’ai pas connaissance de cas qui utilisent cette fonctionnalité.
git config
Cette commande gère la configuration de votre git, par exemple, elle ajoute les paramètres d’authentification de votre repo pour pouvoir travailler avec les repos distants.
Elle peut aussi forcer le passage au pull --rebase par défaut avec la syntaxe suivante : git config --global pull.rebase true
Utilisez-la pour personnaliser au maximum votre usage de git au quotidien.
git prune et git remote prune origin
Ces deux commandes sont des commandes de nettoyage. git prune va supprimer les objets référencés qui ne sont pas présents sur le repo distant et git remote prune origin va supprimer les branches locales qui ont été supprimées à distance.
Dans certains gros projets, avec beaucoup de développeurs, le nombre de branches croissant rapidement, les dossiers .git locaux ont tendance à s’embompoint. Utiliser ces commandes de temps en temps a donc son intérêt.
git clear
Il s'agit d'une commande personnalisée pour supprimer toutes les branches locales qui on été supprimées sur le repo distant.
git fetch --prune && git branch --format '%(refname:short)' | grep -v 'remotes/' | while read branch; do git show-ref --verify --quiet refs/remotes/origin/$branch || git branch -D $branch; done
Explications :
'git fetch --prune' : Elle met à jour les références des branches distantes, en supprimant celles qui n'existent plus.
'git branch --format '%(refname:short)''' : Cette commande liste uniquement les noms courts des branches locales sans les informations de tracking.
'grep -v 'remotes/''' : Cela exclut toutes les entrées des branches distantes (qui contiennent 'remotes/') de la liste, ne laissant que les branches locales.
'Boucle while' : Pour chaque branche locale restante, la commande vérifie si une référence distante correspondante existe. Si non, la branche est affichée.
Vous avez un besoin de développement ou de formation ?