---
# System prepended metadata

title: 'Conférence sur l''outil Git [2020]'

---

# Conférence sur l'outil Git [2020]

Bonjour à tous,

Ce TP, réalisé par [Efrei Linux](https://www.efrei-linux.fr/), fait suite à une conférence git réalisé en partenariat avec [SEPEFREI](https://sepefrei.fr/) et [FAP Efrei](https://fapefrei.com/).
Par ailleurs, ce TP est une mise à jour d'une [ancienne itération](https://hackmd.io/8PJu5dFnTu6pkN-BNKxBRQ).

<div style="text-align:center;">
    <img src="https://i.imgur.com/n1jyH7x.png" style="width:15%;margin:2em;" alt="Efrei Linux" title="Efrei Linux"/>
    <img src="https://sepefrei.fr/img/hat.png" style="width:15%;margin:2em;" alt="SEP Efrei" title="SEP Efrei"/>
    <img src="https://i.imgur.com/HVunEyo.png" style="width:15%;margin:2em;" alt="FAP Efrei" title="FAP Efrei"/>
</div>

Ce TP a pour but de vous apprendre les commandes de base pour pouvoir vous servir de l'outil Git dans vos futurs projets de développement en groupe à l'Efrei.

Si besoin, un programme simple est à votre disposition [ici](https://github.com/nerstak/TP_Git_Efrei_Linux/blob/main/main.py).

## Sommaire

[TOC]

## Initiation

### Installation

Nous allons maintenant passer à l'installation de l'outil Git.

#### Procédure d'installation sous Windows :

Avez-vous un éditeur de texte (autre qu'un IDE comme code::blocks) installé ? 
Si ce n'est pas le cas, nous vous invitons à en installer un avant de commencer l'installation de Git.

Vous pouvez installer par exemple :

* [Notepad++](https://notepad-plus-plus.org/)
* [Visual Studio Code](https://code.visualstudio.com/)
* [Sublime Text](https://www.sublimetext.com/)
* [Atom](https://atom.io/)

Si vous n'en connaissez aucun, nous vous conseillons Notepad++ qui est simple d'utilisation.

Maintenant que vous avez installé votre éditeur de texte préféré, vous pouvez télécharger l'installateur de git via ce lien : https://git-scm.com/download/win

Vous pouvez lancer l'installation.
:::warning
Nous vous demandons juste de faire attention à quelques étapes :
:::

![](https://i.imgur.com/YBHRqds.png)

Ici, on vous demande **quel éditeur vous souhaitez utiliser avec Git**. 
En effet, vous allez être ammené à modifier des fichiers lors de ce TP. 

Par défault, Nano et Vim sont proposés, mais ce sont des éditeurs en ligne de commande qui, bien que parfois utiles, ne sont pas forcément simple à utiliser, surtout quand on ne les connaît pas. 

Vous pouvez donc choisir dans le menu déroulant l'éditeur que vous souhaitez utiliser (**choisissez l'éditeur que vous avez installé précédement**).

___

![](https://i.imgur.com/CR3Pa7V.png)

:::info
**Sélectionnez l'option n°2**
:::

Cela vous permettra d'utiliser Git depuis l'interpreteur de commande `Git Bash` mais aussi depuis CMD et Powershell.

Nous utiliserons `Git Bash` pour ce TP.

Cependant, pouvoir utiliser git sur les interpréteurs de commande officiels de windows (CMD, powershell) peut aussi s'avérer être utile. 

Nous vous expliquerons ce qu'est un interpréteur de commande plus tard, si cela ne vous parle pas.

___

![](https://i.imgur.com/wzGHIl9.png)

:::success
Vous pouvez maintenant lancer l'application `Git Bash` !
:::

#### Procédure d'installation sous Mac OS :

L'installation sous Mac se fait, au choix : 
- par l'utilisation d'une commande brew
- par un installateur classique


https://git-scm.com/download/mac

#### Procédure d'installation sous Linux :

```sh=
# Debian, Ubuntu, ...
$ sudo apt install git

# Fedora, Red Hat, CentOS, ...
$ sudo dnf -y install git

# Archlinux, Manjaro, ...
$ sudo pacman -S git

# Gentoo Linux, btw I use Arch
$ sudo emerge -a git
```

Pour le reste, votre moteur de recherche préféré vous apportera sûrement une réponse...

### La ligne de commande

:::success
La meilleur façon de comprendre le fonctionnement de git est de l'utiliser en ligne de commande. 
:::

> [name=Geek][color=red] **Interpreteur de ligne de commande (CLI) ? Je connais bien !**

Je peux passer cette partie en cliquant sur ce <a href="#debut_tuto">lien</a>.

> [name=Personne saine d'esprit (pour le moment)][color=blue] **Interpreteur de ligne de commande (CLI) ? Kézako ?**

<p style="display:none">
Référence évidente à Matrix pillule bleu pillule rouge
</p>

Si le terme d'interpreteur de ligne de commande (CLI) ne vous parle pas trop, je vous invite à lire cette partie.

![](https://i.imgur.com/nvD1a9M.png)

:::warning
Un interpreteur de ligne de commande ou Command-line interpreter (CLI) en anglais est un programme qui va attendre que l'utilisateur entre une commande pour ensuite l'interpreter. Les interpreteurs de commandes existaient avant les interfaces graphiques. Ils sont encore utilisés aujourd'hui car souvent considérées comme plus pratiques et rapides à utiliser (quand on sait s'en servir).
:::
L'interpreteur de commande que nous utiliserons se trouve à un endroit précis dans l'arborescence de vos fichiers. Toutes les commandes s'appliqueront uniquement sur l'endroit où il se trouve.

Voici quelques commandes de bases qui vous seront utile pour la réalisation du TP :

* **pwd** : Indique le chemin absolu du dossier dans lequel vous vous trouvez actuellement
* **ls** : Liste les fichiers et dossiers présent dans le dossier courant.
* **mkdir** : Créé un dossier.

Par exemple

```bash=
$ mkdir efrei
```

Crée un dossier vide nommé "efrei".

* **cd** : Permet de changer le dossier courant.

Par exemple

```bash=
# Aller dans votre dossier efrei
$ cd efrei

# Aller dans le dossier parent
$ cd ..

# Aller dans C:/Users/nom, par exemple
$ cd /c/users/nom
```

Durant tout le TP, nous travaillerons donc avec la commande **git**. Pour vérifier que tout est bien installé, vous pouvez taper la commande `git --version`:

![](https://i.imgur.com/PdUu8vW.png)

<div id="debut_tuto"></div>

## TP Débutant

### Création d'un répertoire git

*<u>Mise en situation :</u> Vous vous apprêtez à faire un projet de développement en groupe (à tout hasard, un projet transverse). Vous décidez d'utiliser Git pour éviter un développement trop chaotique.
Voici la marche à suivre :*

La **première étape** est donc d'**initialiser le dossier de votre projet avec l'outil git**. Ainsi, git aura accès à ce dossier : il pourra alors conserver et versionner les fichiers contenus dans celui-ci.

Via votre terminal, placez vous dans le dossier à initialiser. Ici, le dossier s'appelle `Dossier_groupe_projet`, qui se trouve lui même dans le dossier `EFREI` qui lui même est dans `Documents`. Vous pouvez remplacer ce chemin par un chemin menant à votre propre dossier.

```sh=
$ cd Documents/EFREI/Dossier_groupe_projet
```

Maintenant qu'on se trouve dans le dossier, initialisons-le :

```sh=
## Si vous voulez utiliser Github comme serveur avec un nouveau dépôt
$ git init -b main


## Pour les autres serveurs ou anciens dépôts Github
$ git init
```

### Lier ce répertoire à un serveur git distant

La **seconde étape** consiste à relier votre dossier local à un serveur qui va stocker votre projet, pour le rendre accessible à vos collègues de travail. 

Pour cela, il va falloir créer votre projet git sur un site d'hébergement de projet git. L'ensemble des sites hébergent vos projets gits gratuitement.

Voici une liste de ces sites (non-exhaustive):

* [GitHub](https://github.com/)
* [GitLab](https://about.gitlab.com/)
* [Bitbucket](https://bitbucket.org/)

Nous allons utiliser la plateforme GitHub pour notre exemple. 
Rendez-vous sur leur site afin de créer votre compte.

Une fois votre compte créé, il faudra vous rendre en haut à droite de votre écran sur l'icône **+ puis New repository**.

![](https://i.imgur.com/5eBLN5J.png)

___

Vous êtes maintenant sur l'interface de création de dépôt.
Vous pouvez choisir le titre que vous souhaitez comme nom de projet.
Sur l'image, vous pouvez observer que j'ai choisi le nom `LinuxIsLove`.

Afin que le projet ne soit pas accessible et visible par tout le monde, je choisis de rendre le projet privé (*Private*).
Je pourrais par la suite ajouter mes camarades sur le dépôt afin qu'ils puissent participer au projet.

Je peux maintant créer le dépôt git en appuyant sur `Create repository`.

![](https://i.imgur.com/CEUQYDI.png)

___

Ça y est ! Le dépôt est créé !

Il reste maintenant la dernière étape, relier votre dossier local au dépot distant.

Pour votre plus grand bonheur, GitHub vous mâche le travail et vous propose directement les commandes à taper pour relier le projet.

Vous n'avez plus qu'à copier coller la commande encadrée en rouge qui apparait à votre écran.
![](https://i.imgur.com/TvQiy4Y.png)

___

C'est cette commande qui définit dans quel dépôt l'outil Git va envoyer les modification et les commits (sauvegardes). 

``` sh=
## SSH
$ git remote add origin git@github.com:<username>/<nom_repo>.git

## HTTPS
$ git remote add origin https://github.com/<username>/<nom_repo>.git
```


Copions le lien HTTPS (vous pouvez choisir au niveau du bouton [HTTPS|SSH] ).

Maintenant que vous avez initialisé ce dépôt, vous allez pouvoir commencer à écrire le premier ou les premiers fichiers de votre projet.

:::info
Note :
Vous avez vu comment initialiser un dépôt, puis le lier à dépôt sur un serveur. Cependant, il existe une méthode alternative.

Celle-ci consiste à créer le dépôt Git sur le serveur, puis à le [cloner](#clone).
:::

### Status

Afin d'observer les changements qui ont été réalisés dans votre projet depuis le dernier `commit` (votre dernière sauvegarde), vous allez pouvoir obtenir une vue d'ensemble avec la commande suivant : 

```sh=
$ git status
```

Ainsi, vous obtiendrez la liste des nouveaux fichiers ajoutés, des fichiers modifiés non-validés et validés.

S'il n'y a eu aucune modification, vous obtiendrez le message suivant :

```=
Sur la branche main
Votre branche est à jour avec 'origin/main'.

rien à valider, la copie de travail est propre
```

S'il y a eu des modifications mais qu'elles ne sont pas encore validées, on obtient ce message :

```=
Sur la branche <nomDeLaBrancheCourrante>
Votre branche est à jour avec 'origin/main'.

Modifications qui ne seront pas validées :
  (utilisez "git add/rm <fichier>..." pour mettre à jour ce qui sera validé)
  (utilisez "git checkout -- <fichier>..." pour annuler les modifications dans la copie de travail)

    modifié :         <monAutreFichierModifié>
```

Finalement, vous obtiendrez un message ayant ce format en retour de votre commande, si le fichier a été modifié et qu'il a été validé : 

```=
Sur la branche <nomDeLaBrancheCourrante>
Votre branche est à jour avec 'origin/main'.

Modifications qui seront validées :
  (utilisez "git reset HEAD <fichier>..." pour désindexer)

    modifié :         <monFichierModifié>
```

Nous aborderons par la suite du TP les différentes sections présentées dans ce message de retour lorsque des modifications sont enregistrées.

### Ajouter les modifications à enregistrer

Lors de l'utilisation de git, il est important de bien comprendre le concept suivant :

Le serveur qui héberge votre projet git va garder l'historique des modifications.

Cependant, si vous ne lui envoyez pas vos modifications, elles resteront toujours en local sur votre ordinateur.

Cela empêchera vos camarades d'obtenir le travail que vous avez réalisé, enlevant ainsi l'intéret principal de l'outil.
![](https://i.imgur.com/fgJYpkl.png)

Les explications qui vont venir permettent de réaliser des enregistrements en local. Nous verrons plus tard comment envoyer ces modifications au serveur.

___

Maintenant que ce point est clair, attaquons la partie la plus difficile à assimiler ! 

*(courage, ça va le faire vous êtes fort  :muscle:)*

Par défaut, un fichier que l'on vient de créé n'est pas suivi par git. Il prend connaissance de son existance, mais le laisse tranquille.
Ce statut s'appelle **Untracked**.

Une fois qu'un fichier est suivi (tracked), le fichier peut alors avoir trois états :

* **Unmodified** : le fichier n'a pas été modifié depuis le dernier commit (depuis la dernière sauvegarde).
* **Modified** : le fichier a été modifié depuis le dernier commit. 
* **Staged** : le fichier a été modifié depuis le dernier commit et a été sélectionné par l'utilisateur pour être enregistré dans le prochain commit (la prochaine sauvegarde).

Nous allons nous intéresser à la manière d'ajouter un fichier à l'état **Staged**.

Pour cela, nous allons utiliser la commande `git add`, comme cela nous était suggéré lors de l'utilisation de la commande `git status` vu précédemment.

```sh=
# Pour ajouter toutes les modifications d'un seul fichier
$ git add <chemin_vers_le_fichier>

# Pour ajouter toutes les modifications de tous les fichiers
$ git add -A
$ git add .
$ git add *
```

Résumé de l'explication en schémas :

![](https://i.imgur.com/SryFEG0.png)

___

![](https://s2.qwant.com/thumbr/700x0/5/c/6ec929bd333574c612b8207b2fd83cdc7a18c2590135abe6572542f3bfe035/git-lifecycle.png?u=http%3A%2F%2Fwww.nullptr.me%2Fimages%2Fgit-lifecycle.png&q=0&b=1&p=0&a=1)

Nous vous invitons maintenant à créer un fichier, de rédiger ce que vous souhaitez dedans (si vous n'avez pas d'idées, vous pouvez rédiger un poème d'amour à Linux ou copier le fichier [suivant](https://github.com/bergth/tp_git_efrei_linux/blob/main/calculatrice.py)).

Utilisez alors la commande `git add` pour passer ce fichier à l'état de **staged**. Pour vérifier que cela a bien fonctionné, aidez-vous de la commande `git status` qui vous indiquera si le fichier est bien ajouté.

### Réaliser un commit

Maintenant que vous avez ajouté le fichier créé précédemment à l'état de staged, il est temps de valider votre sauvegarde.

La commande commit permet donc d'enregistrer l'ensemble des fichiers ayant le statut staged. Il faut aussi ajouter un commentaire afin d'expliquer les changements/création que l'on enregistre.

```sh=
$ git commit -m "Mon commentaire COMPREHENSIBLE sur les changements réalisés"
```

:::warning
Il est **important** dans les projets de groupe de donner un **commentaire lisible et compréhensible** afin que tous vos camarades puissent comprendre les changements que vous avez réalisé sans avoir à ouvrir les détails du commit.
:::

### Pousser le commit sur le serveur

Jusqu'à maintenant, toutes les modifications que vous avez réalisées, puis enregistrées dans git via la commande `git commit`, se trouvent sur votre ordinateur. Elles ne sont pas accessibles par vos camarades de travail.

Pour les rendre accessibles, il va falloir envoyer toutes vos modifications sur le serveur distant hébergeant votre dépôt git.

Ainsi, vos collègues pourront récupérer les modifications que vous avez apportées sur le projet en communiquant avec le serveur distant.

Pour cela, il vous faudra utiliser une des deux commandes suivantes : 

```sh=
#Commande à utiliser lors du premier push réalisé sur le serveur depuis votre ordinateur
$ git push -u origin main

#Commande utilisée dans la plupart des cas
$ git push 
```

:::warning
:warning: **Attention** la commande `git push` envoie uniquement au serveur les commits que vous avez réalisé, sur la branche courante. (cf notion de branche)

Si vous avez réalisé des modifications sans les sauvegarder via un ou plusieurs commits, rien ne sera envoyé sur le serveur.
:::

### Récupérer les modifications du serveur
Contribuer au projet, c'est bien, mais il faut aussi récupérer le travail que les autres ont envoyé sur le serveur !

Pour cela, nous allons télécharger les modifications en utilisant la commande `git pull`.

```
git pull
```


### .gitignore

Lors de vos projets, il est possible que vous ayez des fichiers indépendants du code source qui soient générés, tel que la configuration du projet pour l'IDE, les builds, etc.
Hors, cette information est différente chez chacun des utilisateurs. 
Il est aussi possible que vous ayez des fichiers sensibles (comme des mots de passe...) que vous préférez ne pas envoyer.

Il est alors pertinent de demander à Git d'arrêter définitivement d'enregistrer les modifications sur cet élément.

Pour ce faire, il va falloir créer un fichier qui s'intitulera `.gitignore`, de préférence à la racine du projet.

On pourra créer ce fichier avec l'éditeur de notre choix, ou juste avec un simple clique droit. 

```sh=
# En fonction de votre éditeur préféré
vim .gitignore
nano .gitignore
gedit .gitignore &
```

Une fois dans l'éditeur, il va falloir indiquer le lien vers le(s) fichier(s) que l'on veut ignorer lors de futures modifications.

```sh=
# Ici, on exclue spécifiquement le fichier `ignorerfichier`

/chemin/vers/le/fichier/a/ignorer.fichier

# Dans ce cas-là, tout le contenu dans le dossier `ignorer` sera exclue
/chemin/vers/le/dossier/a/ignorer/*
```

Enfin, on ajoute le fichier gitignore. C'est à ce moment là qu'il prend effet (et n'oubliez tout de même pas de commit après !).

```sh=
$ git add .gitignore
```

:::warning
:warning: **Si vous ignorez des fichiers qui ont déjà été ajoutés** dans le répertoire, **il ne seront pas supprimés automatiquement**. La démarche devra se faire manuellement (un moteur de recherche et stack overflow sera ton meilleur ami pour cette procédure (indice: `git rm --cached`)).
:::

:::info
Parce que c'est long d'éditer un fichier gitignore, il existe des projets qui permettent d'en générer automatiquement en fonction du langage, de l'IDE, etc. Celui-ci en est un exemple : [https://gitignore.io](https://gitignore.io). 

Exemple d'utilisation : je fais un projet en C avec mon binôme. Dans la barre de recherche je tape le language `C`, mon OS `Linux`, ... Et bien sûr comme mon binôme est sous macOS je le rajoute ce qui m'évitera tous les fichiers `.DS_Store`.
**Bien utilisé ce fichier permet d'avoir un dépôt propre avec uniquement le nécessaire**
:::

### Clone

Vous avez créé votre projet et l'avez partagé sur le serveur git, c'est un très bon début.

Mais qu'en est-il de vos camarades souhaitants activement participer à ce fameux projet transverse ?
Nous n'allons quand même pas les laisser dans la détresse de ne pas pouvoir participer !

Voici la solution pour qu'ils puissent eux aussi accéder au projet : 

La commande `git clone` permet donc de récupérer le projet disponible sur le serveur git sur votre ordinateur en local.

HTTPS:

```sh=
$ git clone https://github.com/<username>/<nom_repo>.git

#Exemple concret : 
$ git clone https://github.com/bergth/tp_git_efrei_linux.git
```

SSH:

Vous devez d'abord créer une clé ssh pour vous identifier. Vous pouvez utiliser cette documentation github pour faire cela : [Générer des clés SSH pour Git](https://help.github.com/en/articles/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent)

```sh=
$ git clone git@github.com:<username>/<nom_repo>.git

## Exemple concret :
$ git clone git@github.com:bergth/tp_git_efrei_linux.git
```

:::info
Le `.git` à la fin est facultatif
:::

### Log

Cette simple commande affiche l'ensemble des commits et de leurs informations réalisés sur la branche où l'on se trouve.

```sh=
$ git log
```
Pour quitter le log, appuyez sur la touche `q`.

## TP Intermédiaire

### Créer une branche

Sur Git, on peut travailler sur différentes **branches**.

Créer une branche signifie que l'on créé une ligne de développement qui se sépare de celle sur laquelle on se trouvait auparavant. 

Ainsi, plus besoin de se pré-occuper de ne pas casser le code des autres.
Chaque branche est indépendante et les modifications réalisées sur l'une n'est pas répercutée sur l'autre.

Cela vous permettra de réaliser des tests, de créer de nouvelles fonctionnalités sans être impacté par les changements des autres.

On peut créer une branche via la ligne de commande suivante :

```ssh=
## Création de la branche
git branch nom_de_ma_branche
```

### Changer de branche

En effet, la commande montrée précedemment ne fait que créer la branche, mais ne vous déplace pas dessus.

Pour se déplacer de branches en branches :monkey:, il faut utiliser la commande suivante :

```ssh=
## Changement de la branche courante vers la branche "ma_branche"
git checkout nom_de_ma_branche
```

:::warning
:warning: Vous ne pourrez pas changer de branches tant que vous n'aurez pas réalisé un commit des modifications effectuées sur cette branche.
Cela permet d'éviter de perdre tout le travail que vous avez réalisé sur cette branche, car sinon il serait écrasé lors du changement.
:::info
**Expert tips !**
Pour ceux qui maitrisent déjà parfaitement les changements de branches/fusion : en fait on peut changer de branche sans commit avec des modifications ! Il serait vraiment malsain de commiter un travail non terminé/non fonctionnel juste parce que nous voulons changer de branche. Il existe pour cela les commandes `stash` et `pop`. Vous pouvez faire des sauvegardes locales de votre états d'avancement de votre travail à l'aide de ces commandes. Pour savoir comment faire, je vous invite à la lire la doc : [git-scm.com : Remisage](https://git-scm.com/book/fr/v1/Utilitaires-Git-Le-remisage)
:::

:::info
**Une pierre, deux coups !**
Combine la création et le déplacement sur `nom_de_ma_branche` en une commande :

> **`git checkout -b nom_de_ma_branche`**
> :::

### Fusionner des branches

L'intéret principal des branches est que l'on peut les fustionner lorsqu'on le souhaite.

Cela permet donc de gagner grandement en organisation !

Voici un example du cycle de vie de la branche `feature1` :
![](https://s2.qwant.com/thumbr/700x0/e/1/ba0c5fb11178ce878f1d00be8e4af1ebd927e2222fa8a2d7280514ebe0cdab/branch-1.jpg?u=http%3A%2F%2Fwww.allafinedelpalo.it%2Fwp-content%2Fuploads%2F2016%2F06%2Fbranch-1.jpg)

Fusionner une branche dans une autre a un sens. Si on reprend l'exemple précédent, on fusionne la branche `feature1` dans la branche `main`.

Il faut donc d'abord se déplacer sur la branche `main`, puis lancer la commande suivante :

```
git merge ma_branche
```

Cependant, lors de la fusion entre deux branches, on peut faire face à ce qu'on appel un conflit.

Un conflit lors de la fusion entre deux branches est dû à la modification de manière différente de lignes de codes à la base similaire entre les branches.

Git ne pourra pas choisir pour vous qu'elles lignes conserver. Il sera alors de votre devoir de réaliser un choix pour savoir quelle ligne conserver.

Voici à quoi ressemble un conflit en exemple :

```
...
<<<<<<< yours:code.txt
nouvelle ligne que j'ai ajouté
=======
ancienne ligne de l'époque des dinosaures
>>>>>>> theirs:code.txt
...
```

Pour le résoudre, il suffira de laisser (on prend la décision de garder que la ligne récemment ajoutée) dans le fichier la ligne suivante.

```
...
nouvelle ligne que j'ai ajouté
...
```

Puis, il faudra ajouter cette modification avec la commande `git add` puis enregistrer avec la commande `git commit`.

:::success
Une **bonne pratique**, lors d'un développement à plusieurs, est d'avoir les branches suivante :

```
____ Branche main (contient un code qui fonctionne à coup sûr)
 |
 |__ Branche développement (contient les nouvelles fonctionnalités, peut planter)
 |
 |__ Branche feature (contient le développement d'une fonctionnalité)
```

Il est important de garder une branche où l'on a la certitude que tout fonctionne dessus. On peut donc dire que la **branche `main`** ou `production` **doit être stable**.

Ensuite, la **branche `développement`** va contenir les **nouvelles fonctionnalités**, pas encore forcément testées les unes entre les autres.

Finalement, **pour chaque fonctionnalité**, il est intéressant de **créer une branche à part appelée `feature-nom-de-ma-fonctionnalité`**. 
Elle sera ensuite fusionnée avec merge sur la branche de développement lorsque celle-ci est totalement développée.

Une fois les **fonctionnalitées testées** et considérées comme **fiables** et utilisables, on **fusionne** la **branche développement** avec la **branche main** (ou production).

Exemple :
![](https://cdn-images-1.medium.com/max/1600/1*L0jHGLTJwZO5CTtpsn-dKA.png)
:::

### Retirer une modification ajoutée avec `git add`

```sh
git reset mon_fichier_ajoute_avec_add
```

### Annuler une modification pas encore commit

```sh
git checkout mon_fichier
```

### Rajouter un fichier lors d'un oubli dans le plus récent commit

Il arrive souvent que l'on commit rapidement, puis qu'on se rend compte que l'on a laissé une faute de frappe.

Une solution simple et efficace existe, l'option `--amend`.

Ajoutez dans un premier temps les modifications au manquantes au dernier commit, puis lancez un nouveau commit avec l'option `--amend`.

```sh
git add mon_fichier_oulié
git commit --amend
```

### Les tags

Les tags permettent de réaliser un suivi de version pour votre projet. 
Ils permet de poser une étiquette sur les grandes étapes et nouvelles fonctionnalitées de votre projet.

Dans le cadre de TP en cours, cette fonctionnalité sera sûrement inutile, cependant il est important de connaître cette notion pour l'entreprise.

```sh=
## Liste les tags
git tag

## Création d'un tag annoté
git tag -a v1.4 -m "my version 1.4"
```

### Fork

Comme l'indique son nom, `fork` permet de créer une fourche d'un projet déjà existant.

Cela permet de réaliser plusieurs actions en conséquence :

* Reprendre un projet déjà existant pour le modifier et l'adapter à votre goût.
* Soumettre une `pull request` sur un projet git dont vous ne possédez pas les droits d'écriture.

:::info
**Pull request** : Demande à l'auteur original de `merge` (ajouter) nos modifications dans son projet.
:::

### Alias

Ne trouvez vous pas fatiguant de taper de nombreuses fois ces longues commandes telles que : `git commit -m "mon message"` ou `git status`

Il existe **une solution** à ce problème :

:::warning
Non ! Pas l'interface graphique, hérétique :smile: !
:::

On peut utiliser des **alias** afin de réduire la taille des commandes à taper.

Par exemple, on peut définir que `git checkout` s'écrira maintenant `git co`.

Ces alias se configurent de la manière suivante :

```sh=
git config --global alias.<monRaccourcis> <commandeGit>
```

Les alias proposés dans la documentation de git sont les suivants :

```sh=
git config --global alias.co checkout
git config --global alias.ci commit
git config --global alias.st status
git config --global alias.br branch
```

Avec ces commandes, on obtiendra les raccourcis suivants :
`git checkout` =>`git co`
`git commit` => `git ci`
`git status` => `git st`
`git branch` => `git br`

:::info
Vous pourrez toujours utiliser les commandes de bases, on ne fait que créer des alias/raccourcis.
:::

### .gitkeep

Parfois vous aurez besoin de commit une architecture de dossier vide. Pour cela il existe une convention, créé un fichier vide avec comme nom : `.gitkeep`. 

**Rappel créer un fichier vide en ligne de commande**

```sh=
touch .gitkeep
```

Cela peut vous être très utile par exemple avec des projets en C. Vous faites un makefile et vous voulez mettre les fichiers de sortie dans un dossier `build`, si vous ne créez pas ce dossier dans votre Makefile et s'il n'existe pas, vos collègue qui vont pull votre dépôt auront une error à l'exécution. Mais comment garder ce dossier `build` ? En rajoutant les binaires qui se trouvent à l'intérieur ? Surtout pas malheureux ! Rajoute simplement un fichier `.gitkeep` et n'oublie pas d'ignorer les binaires !

### Diff

Vous avez vu que la commande `git status` vous permet de voir les changements effectués depuis le dernier commit de votre projet. Il existe cependant une autre commande, dans ce même état d'esprit, qui vous permet de comparer différent commits.

```shell=
$ git diff
```

En exécutant la commande sous sa plus simple forme, vous verrez les différences entre votres derniers commits et votre travail actuel. Mais la puissance de cette commande réside dans la comparaison de commit.

```shell=
# Compare deux commits
$ git diff Commit1 Commit2
# Exemple concret
$ git diff HEAD^ HEAD

# Compare les derniers commits de deux branches
$ git diff branch1..branch2

# Permet de voir les changements sur branch1 depuis le lancement de branch2
$ git diff branch2...branch1
```

Si vous avez juste lancé la commande `git diff` mais que rien ne se passe, pas de panique ! Essayez plutôt la commande suivante, qui permet de voir les changements staged.

```shell=
$ git diff --staged
```