
---
title: "Dépôt local"
date: 2016-03-31
---

* * * *

L'élément de base d'un projet Git est le dépôt. Il s'agit simplement d'un
dossier classique que l'on demande à Git de versionner (journaliser).

Un dépôt Git contient l'ensemble des commits (versions sauvegardées du projet).
On peut donc revenir à n'importe quelle version du projet. Généralement, on
appelle `master` la dernière version sauvegardée et `HEAD` la version courante.

# Initialiser un dépôt

Allez dans le dossier à versionner puis lancez la commande `git init`. 

![](depot_local_01.png)

Git crée alors un dossier caché `.git` pour y stocker ses metadonnées.  Si vous
ne voulez plus versionner votre dossier, il suffit de supprimer ce dossier.  Le
reste du temps, ne touchez pas à ce dossier si vous n'êtes pas absolument
sûr(e) de ce que vous faites.

# Afficher l'état d'un dépôt

La commande `git status` affiche l'état courant du dépôt : nouveaux fichiers,
fichiers modifiés, fichiers supprimés.  Cette commande est très sûre ; elle ne
peut rien casser.  N'hésitez donc pas à la lancer pour voir où vous en êtes.

![](depot_local_02.png)

La commande `git ls-files` affiche la liste des fichiers versionnés.

# Ajouter des fichiers dans le dépôt

Il faut indiquer explicitement les fichiers que Git doit journaliser.  

Par exemple, imaginons qu'on ouvre un nouveau fichier LaTeX `papier.tex`
dans notre projet.  

![](depot_local_04.png)

*  *  *  *

On affiche l'état du dépôt.

![](depot_local_05.png)

Git nous indique que le fichier `papier.tex` existe bien dans le dossier
(ainsi qu'un fichier de sauvegarde), mais qu'il ne fait pas partie du dépôt. 

*  *  *  *

Pour ajouter un fichier au dépôt, il faut utiliser la commande `git add`. 

![](depot_local_06.png)

Ceci indique que Git doit prendre en compte le fichier lors des prochains
commits (journalisation), ce qu'on peut vérifier avec un `git status`.

![](depot_local_07.png)

*  *  *  *

Si on représente le graphe des commits correspondant à notre projet,
on a pour l'instant qu'un état courant non validé.

![](depot_local_07.svg)

# Valider les modifications (commit)

Après avoir ajouté, modifié ou supprimé des fichiers, on peut valider les
modifications, c'est-à-dire sauvegarder un état du projet (commit). Encore une
fois, seuls les fichiers qui ont été ajoutés au projet (avec `git add`) sont
pris en compte. 

La commande à lancer pour valider toutes les modifications est `git commit -a`.

![](depot_local_08.png)

*  *  *  *

Git lance alors l'éditeur de texte pour le message de commit.
Le message est pré-rempli avec des informations concernant le commit. Ces
informations vous permettent de vérifier que le commit correspond bien à ce que
vous voulez mais ne feront pas partie du message final.
On peut spécifier le message de commit directement dans la ligne de commande
avec `git commit -a -m "mon message"` ou plus simplement `git commit -am "mon
message"`.

Écrivez un message expliquant rapidement les modifications que vous êtes en
train de valider puis enregistrez et quittez. 

![](depot_local_09.png)

*  *  *  *

Git crée alors le nouveau commit, qui valide ici le fichier `papier.tex`.

![](depot_local_10.png)

Vous pouvez le vérifier avec un `git status`.

![](depot_local_11.png)

*  *  *  *

Si on représente le graphe des commits, on a désormais un état validé (un
commit), qui correspond actuellement au `master` (dernier commit) et au `HEAD`
(état courant des fichiers).

![](depot_local_11.svg)

# Fichiers autogénérés et .gitignore

Git est très utile pour gérer des fichiers textes que l'on modifie
régulièrement.  En revanche : 

- Il n'est pas adapté pour gérer des fichiers dans un
format non-textuel (images, données compressées, documents word...).  Si on
ajoute un tel fichier dans le dépôt alors à chaque modification, Git stockera
une nouvelle copie complète (au lieu de stocker uniquement les lignes qui ont
changé), ce qui est inefficace.
- D'autre part, il est inutile de versionner les fichiers autogénérés (créés
automatiquement). 

*  *  *  *

Par exemple, si on compile le code LaTeX de notre projet...

![](depot_local_12.png)

*  *  *  *

... des fichiers intermédiaires sont créés et apparaissent lors des `git status` :

![](depot_local_13.png)

*  *  *  *

Pour ignorer des fichiers lors des `git status`, il suffit de les indiquer dans un
fichier `.gitignore`, dans le répertoire principal du projet. Dans le
`.gitignore`, on peut indiquer des noms de fichier complets (par exemple,
`papier.pdf`) ou utiliser des motifs de noms (par exemple, `*.log`).

![](depot_local_14.png)

On vérifie qu'ils n'apparaissent plus lors des `git status`.

![](depot_local_15.png)

*  *  *  *

Sur le graphe des commits, on a maintenant un nouvel état courant `HEAD` non
commité, le `master` correspondant toujours au dernier commit.

![](depot_local_15.svg)

*  *  *  *

Il est courant d'ajouter le `.gitignore` au dépôt, ainsi qu'un
fichier `README.md` qui servira de page d'accueil au format
[markdown](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet).
Sous Linux et Mac, la commande `echo` permet d'ajouter du texte dans un fichier.

![](depot_local_16.png)

Après ce `git commit`, on a un nouveau commit correspondant au `master` et au
`HEAD`.

![](depot_local_16.svg)


# Renommer et supprimer des fichiers

La commande `git mv` permet de renommer un fichier versionné. Il ne faut pas
utiliser la commande système (`mv`) car dans ce cas Git ne saura pas qu'il faut
renommer le fichier (il pensera que le fichier manque et essaiera de le
recréer). Pour rappel, utilisez la commande `git help` pour consulter l'aide
d'une commande (par exemple ici, `git help mv`).

![](depot_local_17.png)

![](depot_local_17.svg)

*  *  *  *

De même, la commande `git rm` permet de supprimer un fichier versionné.

![](depot_local_18.png)

![](depot_local_18.svg)


# Afficher l'historique des commits

Faisons d'abord une modification « commitée » puis une autre non commitée.

![](depot_local_19.png)

Ce qui correspond au graphe suivant.

![](depot_local_log.svg)

*  *  *  *

La commande `git log` (ou `git log --abbrev-commit`) permet d'afficher
l'historique des commits.

![](depot_local_20b.png)

*  *  *  *

On peut également le voir avec un client graphique comme `gitg`.

![](depot_local_21.png)

Le « unstaged » correspond aux modifications courantes non commitées (`HEAD`).

# Supprimer les modifications courantes

La commande `git checkout -- . ` supprime les modifications courantes. Le dépôt revient
alors dans l'état du dernier commit (`master`).

![](depot_local_checkout_01.svg)

# Revenir à un commit précédent (sans suppression)

La commande `git checkout 3ca...` permet de revenir au commit « 3ca... ». On passe
ainsi dans un mode « détaché » (`HEAD` ne pointe plus sur un commit terminal).

![](depot_local_checkout_02.svg)

Au lieu d'utiliser le numéro de commit, on peut également utiliser les
étiquettes : par exemple `git checkout master` pour aller au dernier commit
principal ou `git checkout HEAD~1` pour aller à 1 commit avant le commit
courant...

# Marquer un commit

La commande `git tag` permet d'étiqueter des commits.

![](depot_local_22.png)

![](depot_local_checkout_03a.svg)

*  *  *  *

Ces étiquettes permettent d'indiquer des versions du projet et de revenir plus
facilement à un commit particulier.

![](depot_local_22b.png)

![](depot_local_checkout_03b.svg)

# Supprimer des commits précédents

La commande `git reset 13a...` place le `master` sur le commit « 13a... » et
supprime tous les commits suivants **sans supprimer les modifications
correspondantes**, qui sont alors regroupées dans l'état courant, non commité.

![](depot_local_checkout_04.svg)

*  *  *  *

La commande `git reset --hard 13a...` est équivalente à la commande précédente
sauf qu'elle **supprime les modifications correspondantes**.
Les fichiers sont donc remis dans l'état du commit « 13a... », et `master` et
`HEAD` pointent vers ce commit.

![](depot_local_checkout_05.svg)

# Résumé 

---|---|
`git init` | initialise le dossier courant (nouveau dépôt Git) |
`git status` | affiche l'état courant des fichiers |
`git ls-files` | affiche la liste des fichiers versionnés |
`git add <fichiers>` | demande à Git de versionner des fichiers |
`git commit -a` | valide toutes les modifications courantes |
`git mv <nom1> <nom2>` | renomme des fichiers versionnés |
`git rm <fichiers>` | supprime des fichiers versionnés |
`git log` | affiche la liste des commits |
`git checkout -- .` | supprime les modifications courantes (revient au commit)|
`git checkout <commit/etiquette>` | revient à un commit sans rien supprimer |
`git tag` | affiche la liste des étiquettes |
`git tag <etiquette> <commit>` | crée une nouvelle étiquette sur un commit donnée |
`git tag <etiquette>` | crée une nouvelle étiquette sur le commit courant |
`git reset <commit>` | supprime des commits et regroupe les modifications correspondantes dans l'état courant|
`git reset --hard <commit>` | supprime des commits ainsi que les modifications correspondantes|

# Conseils 

- Privilégiez les petits dépôts, correspondant à différents travaux, plutôt
  qu'un gros dépôt regroupant tous vos travaux de l'année.
- Faites des commits réguliers et correspondant à des petites tâches successives. 
- Évitez de commiter un projet cassé (par exemple, du code qui ne compile pas).
- Ne versionnez pas les fichiers auto-générés.

# Exercice

- Créez un nouveau dépôt local, ajoutez des fichiers et faites quelques
  modifications+commits ; affichez l'état du dépôt à chaque étape.
- Renommez et supprimez quelques fichiers.
- Affichez l'historique des commits et revenez dans un état précédent du dépot.
  Vérifiez que vos fichiers reviennent bien à l'état correspondant au commit.
- Ajoutez une étiquette à un ancien commit et vérifiez que vous la voyez dans
  l'historique des commits ou avec un client Git graphique.
- Testez les suppressions de commits.

