Git au quotidien : les seules commandes que j'utilise vraiment
Tags: git
Published: 2021-04-09 12:28:20

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](https://blog.stack-labs.com/code/devops_conventional_changelog/).

### 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](https://blog.stack-labs.com/code/git_force_with_lease/).

### 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](https://git-scm.com/docs/git-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](https://git-scm.com/docs/git-stash/fr#_exemples).

### 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 de `git fetch` suivi de `git 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.