---
tags: ironhack
---
<style>
img {background-color:transparent!important;}
</style>
Git workflow
===
Voir dans quelle branche on se trouve
---
```shell
$ git branch
christmas-feature
* master
easter-egg
```
> :point_right: Nous sommes ici dans la branche `master`, repérée par l'`*`
:::info
:bulb: La branche `master` est la branche par défaut sur tous les repositories
:::
Créer une nouvelle branche `masuperfeature`
---
```shell
$ git checkout -b masuperfeature --track origin/master
```
Une nouvelle branche du nom de `masuperfeature` est créée et nous nous retrouvons maintenant dedans.
Changer de branche
---
Pour aller dans la branche `coolfeature` (déjà créée) :
```shell
$ git checkout coolfeature
```
:::info
:bulb: Dans le prompt de notre terminal, on peut afficher la branche courante dans laquelle on se trouve, comme par ex :
```
(master) $ git checkout coolfeature
(coolfeature) $
```
Voir [cet article](https://coderwall.com/p/fasnya/add-git-branch-name-to-bash-prompt).
:::
Faire un commit
---
Pour voir où on en est localement, ie :
- les fichiers modifiés/supprimés
- les nouveaux fichiers, dits `untracked`
```shell
$ git status
On branch masuperfeature
Your branch is up to date with 'origin/master'.
Changes not staged for commit:
(use "git add/rm <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: app.js
deleted: old.js
Untracked files:
(use "git add <file>..." to include in what will be committed)
README
```
On `add` ensuite tous les fichiers (nouveaux ou modifiés) que l'on veut inclure à notre commit et l'on `rm` tous ceux que l'on veut supprimer du répo :
```shell
$ git add README app.js
$ git rm old.js
```
Un ultime `git status` avant de faire notre commit histoire de s'assurer que tout est bon (en vert), puis:
```shell
$ git commit -m "Ajout de la doc et cleaning"
```
:::info
:bulb: `git status` donne beaucoup d'info y compris certaines commandes comme par ex pour annuler un changement sur un fichier : `git checkout -- <file>`
:::
Pousser une branche
---
Pour envoyer nos commits locaux vers le serveur distant (Github) :
```shell
$ git push origin masuperfeature
```
:::warning
:point_up: On doit *forcément* être dans la branche locale `masuperfeature` pour pousser vers la branche distance `masuperfeature` (**même nom**).
:::
:::success
:bulb: Si la branche distante n'existait pas encore, elle sera créée automatiquement.
:::
:::info
Pousser une branche permet :
- [x] à d'autres devs de récupérer mon travail
- [x] de faire une sauvegarde de son travail ailleurs (si jamais on perdait son laptop dans le métro)
:::
Merger une branche dans une autre
---
Si je veux récupérer le code d'un collègue bossant sur la branche `api`.
Dans ma propre branche :
```shell
$ git pull origin api
```
:::warning
:point_up: AVANT de faire le `pull`, je m'assure par un `git status` de **n'avoir aucune modification en cours**.
Si c'est le cas, je prends le temps de **faire un commit AVANT**.
:::
Resoudre des conflits (méthode de base)
---
### 💥Boom
Lors d'un [merge](#Merger-une-branche-dans-une-autre), si 2 développeurs ont modifié la même ligne de code, git ne saura pas quelle version prendre... Il mettra alors le merge *en pause*, et vous demandera de résoudre les conflits, avant de pouvoir finaliser le merge :
```shell
$ git pull origin api
From https://github.com/abernier/ironme
Auto-merging public/stylesheets/style.scss
CONFLICT (content): Merge conflict in public/stylesheets/style.scss
Automatic merge failed; fix conflicts and then commit the result.
```
:::success
Vous pourrez retrouver la liste des fichiers en conflit par un `git status` :
```shell
$ git status
On branch features/about
You have unmerged paths.
(fix conflicts and run "git commit")
(use "git merge --abort" to abort the merge)
Unmerged paths:
(use "git add <file>..." to mark resolution)
both modified: public/stylesheets/style.scss
no changes added to commit (use "git add" and/or "git commit -a")
```
NB : Notez le `Unmerged paths`
---
<div style="font-size:120%;text-align:center;">
<code>git status</code> est vraiment notre meilleur ami, il nous donne toujours de bons conseils 🧚🏼♂️</div>
:::
### 💏Résolution
Si l'on inspecte le fichier en conflit :

:::info
:bulb: Le conflit est délimité par des chevrons entre les lignes 4 et 10 :
```
<<<<<<< HEAD
v1
=======
v2
>>>>>>> 6b7380c886e0906f6a5efd2b600be8fcf390fa4d
```
:::
Il nous faut réconcilier `v1` et `v2` ensemble, tout simplement **en éditant le fichier et en enlevant les signes bizarres** :

:::info
🤝Souvent lors de la résolution d'un conflit, on contactera l'auteur avec lequel notre version conflicte pour se mettre d'accord sur la résolution.
:::
### ✅ commit de merge
Une fois le fichier édité et le conflit résolu, il nous faut marquer le fichier comme mergé et faire un commit de merge (sans message) :
```shell
$ git add public/stylesheets/style.scss
```
:::success
Un petit `git status` vous dira maintenant qu'il n'y a plus de conflit :
```shell
$ git status
On branch master
All conflicts fixed but you are still merging.
(use "git commit" to conclude merge)
Changes to be committed:
modified: public/stylesheets/style.scss
```
NB : Notez le message : `use "git commit" to conclude merge`
:::
La commande `git commit` sans message de commit, ouvre un éditeur de texte `Vim` avec un message de commit pré-rempli :
```shell
$ git commit
```
```
Merge branch 'master' of https://github.com/abernier/ironme into features/about
# Conflicts:
# public/stylesheets/style.scss
#
# It looks like you may be committing a merge.
# If this is not correct, please remove the file
# .git/MERGE_HEAD
# and try again.
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# On branch features/about
# All conflicts fixed but you are still merging.
#
# Changes to be committed:
# modified: public/stylesheets/style.scss
#
```
Pour sauvegarder le message de commit et quitter Vim, nous appuyons sur les touches <kbd>:wq</kbd>
:::info
Si l'on aime pas Vim, on peut aussi définir VScode comme éditeur de texte par défaut :
```shell
$ echo "export EDITOR=\"code -w\"" >>~/.profile
```
:::
**And voilà, le conflit est maintenant résolu 🙌**
On oublie pas de pousser le commit de merge, avec que la résolution du conflit puisse profiter à d'autres (et qu'ils n'aient pas à la refaire eux-même) :
```shell
$ git push origin master
```
Résoudre des conflits (avec `git mergetool`)
---
Le principe reste le même, on des conflits, mais pour la résolution, on va cette fois-ci s'aider d'un outil graphique pour mieux visualiser les 2 versions côte-à-côte...
### Configuration
:::info
Pour les utilisateurs sous Windows et Ubuntu, vous devrez installer le logiciel **[Meld](http://meldmerge.org)** et le **[configurer](https://stackoverflow.com/a/43868889/133327)** sur votre machine.
:::
:::info
Pour les utilisateurs sous mac, je vous recommande d'utiliser plutôt **Filemerge**, dont voici **[les instructions pour le configurer](https://gist.github.com/kylefox/4512777)**.
---
NB: Dans les préférences de Filemerge, cochez l'option `Compress white space`:

:::
### Utilisation
La commande `git mergetool` va pour chacun des fichiers en conflit, démarrer l'interface graphique (Meld ou Filemerge) :
```shell
$ git mergetool
Merging:
public/stylesheets/style.scss
Normal merge conflict for 'public/stylesheets/style.scss':
{local}: modified file
{remote}: modified file
```
qui lancera alors une interface graphique pour résoudre le conflit :

> :broken_heart: A gauche et droite : les 2 versions en conflits.
> :green_heart:En bas : notre version "réconciliée" (et éditable !)
:::warning
☝️Occupez-vous seulement des blocks en rouge ! Les autres ne sont pas en conflit.
:::
Une fois le conflit résolu, ne pas oublier de <kbd>+s</kbd> `sauver` le fichier du milieu avant de <kbd>+q</kbd>`quitter` l'interface.
:::warning
Si plusieurs fichiers en conflit, il vous faudra quitter entre chaque. `git mergetool` relancera l'interface pour chaque fichier en conflit.
:::
---
👉Idem, on oublie pas ensuite de faire le ✅commit de merge !