Je ne suis pas une experte Git, je ne connais pas toutes les commandes, mais depuis quelques années, j'ai une routine et quelques commandes que j'utilise au quotidien. Ces commandes me permettent de gérer 95% de mes besoins.
Avec seulement 7 commandes, je peux gérer mon projet au quotidien. Voici la liste des commandes que je vais présenter à travers mon workflow de développement :
git fetch
git checkout
git branch
git add
git commit
git push
git rebase
Démarrer mon développement
Je présente deux façons de démarrer mon développement. Je vais commencer par GitLab, un outil ultra répandu, que j'ai toujours connu via mes différentes expériences, chez les petits comme chez les gros clients. Il m'est arrivé de démarrer mon développement sans passer par GitLab, donc je présenterai également cette deuxième option.
La branche principale de développement de votre projet peut s'appeler master
, dev
, main
... Cela dépend de votre projet, et peut importe son nom, c'est la branche sur laquelle toute l'équipe fait partir ses branches pour faire son développement. Dans mon exemple, la branche principale de développement s'appelle main
.
Cas 1 : je démarre mon développement via GitLab
Quand je démarre un développement, je créé ma branche à partir de l'issue GitLab, il y a un bouton pour créer une branche, et ça la rattachera à votre issue. Ici mon issue s'appelle : "Add new feature", et la branche va s'appeler automatiquement add-new-feature
.
Une fois la branche créée via GitLab, je veux tout simplement la récupérer et me placer sur cette branche.
Récupération de ma branche
Je récupère ma branche en local en faisant :
git fetch
Je peux voir dans ma console, le nom de ma branche apparaître.
Se déplacer sur ma branche
Pour commencer mon développement, je vais me déplacer sur ma branche. Je fais cette commande :
git checkout add-new-feature
Cas 2 : je démarre mon développement à la mano
Récupération des modifications du projet
Je fais la commande suivante :
git fetch
Se déplacer sur la branche principale
Je me place sur la branche principale de développement de mon projet. Pour me déplacer, j'utilise git checkout
. Ici, la branche principale de développement de mon projet s'appelle main
, donc je fais :
git checkout main
Écraser la branche principale pour la mettre à jour
J'écrase la branche main
locale par la branche distante main
:
git reset --hard origin/main
A partir de ce moment là, je sais que la branche main
locale est la même que la branche distante. Je m'assure ainsi de créer ma branche à partir de la branche principale à jour.
Création de ma branche et se déplacer sur celle-ci
Je veux créer ma branche à partir de main
pour faire mon développement et me déplacer sur la branche créée. Je veux appeler ma branche add-new-feature
, je vais donc faire la commande suivante :
git checkout -b add-new-feature
En cours de développement
Je développe sur ma branche, et une fois tout ou partie de mon développement terminé je fais les commandes suivantes :
J'ajoute mes modifications
J'ajoute toutes mes modifications, je fais :
git add .
ou
git add -A
Cas 1 : je commit pour la première fois
Je créé mon commit avec ce message feat(example): add new feature
. Je fais la commande suivante :
git commit -m "feat(example): add new feature"
ou
git commit
(va m'ouvrir l'éditeur de mon choix, vim par défaut)
Si le Conventional-Changelog ne vous dit rien, voici un article pour vous.
Cas 2 : j'ajoute des modifications à mon commit précédent
Si je veux ajouter un développement supplémentaire sur ma branche, je travaille en général avec un seul commit pour mon développement, donc j'utilise git commit --amend
:
git commit --amend
ou
git commit --amend --no-edit
Je ne travaille pas avec des commits intermédiaire du genre :
feat(example): add something
feat(example): delete something
feat(example): update something else
Pour ensuite "squash" ces commits pour avoir 1 seul commit :
feat(example): add new feature
Je fais un seul commit, mon commit final, et j'amend
ce commit pour n'avoir qu'un seul commit qui sera mergé sur la branche de développement. C'est une question d'habitude et de préférence.
A la fin de mon développement
Prérequis si vous créez vos branches en local : configurez votre git avec cette commande pour ne pas avoir à préciser à chaque fois l'upstream :
git config --global push.default current
Je pousse mes modifications
Je fais cette commande pour pousser mon développement :
git push
ou
git push --force-with-lease
Si vous n'êtes pas familier avec l'option --force-with-lease
, je vous recommande cet article.
Mise à jour de ma branche par rapport à la branche principale
Dans le cas où la branche principale de développement à évoluée par rapport à ma branche de développement, je dois faire un git rebase
.
Je récupère toutes les modifications faites par les autres personnes de mon projet :
git fetch
Je mets à jour ma branche par rapport à main
(la branche principale).
git rebase origin/main
Je gère les conflits éventuels via mon IDE pour plus de simplicité. Vous avez également des outils Git qui permettent de gérer les conflits plus facilement.
Et ensuite je push quand j'ai terminé mon rebase :
git push --force-with-lease
J'utilise également le rebase interactive -i | --interactive
pour certaines situations. C'est une option que je conseille de regarder même si je ne l'utilise qu'occasionnellement (la doc du rebase).
Les commandes supplémentaires
Utilisées occasionnellement
Quand je veux voir l'historique des commits sur une branche :
git log
Quand je veux voir mes modifications en cours non commités :
git status
Quand je veux sauvegarder un "brouillon" de mon développement en cours sur une branche :
git stash
Quelques exemples de stash
sont listés ici.
Utilisées rarement
Quand je démarre sur un nouveau projet :
git clone
Quand je définis mon nom d'auteur et l'email associé :
git config --global user.name "Clara Belair"
git config --global user.email clara.belair@example.com
Pourquoi je préfère git fetch
à git pull
pour récupérer les modifications distantes ?
On me pose souvent la question pourquoi je fais un git fetch
au lieu d'un git pull
. Attention, ce ne sont pas des commandes équivalentes. Si vous faites un git pull
, par défaut, il y a un merge
qui est fait juste après le fetch
.
Voici la description de git pull
(https://git-scm.com/docs/git-pull/fr) :
"Intègre les modifications d’un dépôt distant dans la branche actuelle. Dans son mode par défaut,
git pull
est l’abréviation degit fetch
suivi degit merge FETCH_HEAD
."
Pour éviter toute mauvaise surprise, je conseille donc de faire un git fetch
pour récupérer les modifications distantes. Ou alors soyez conscient des commandes exécutées derrière git pull
par défaut et de leurs conséquences sur votre branche actuelle.