## Initiation Git par Julien Palard
https://mdk.fr
## Git Git est un gestionnaire de code source distribué.
## Git : qui l'utilise ? - Le kernel Linux - Google, Microsoft, Facebook, Netflix, ... - PostgreSQL - Python, perl, Go, swift, typescript, rust, Julia, scala, ... - ...
## Git : qui l'utilise ? ![](static/stats.png)
## Historique et alternatives - SCCS (1972) (un fichier, local) - RCS (1982) (un fichier, local) - CVS (1986) (projet, client-server) - Subversion (2000) - BitKeeper (2000) - Bazaar (2005) - Mercurial (2005) - git (2005) - Fossil (2007)
## Git est décentralisé Il n'y a ni serveur, ni client : tout le monde est « au même niveau » : - On peut travailler seul sur sa machine sur son projet. - On peut travailler une journée sans connexion à internet.
## Introduction Commençons par imaginer un projet : l'écriture d'un livre.
## Introduction Dans notre projet, `git` va nous simplifier deux choses : - La collaboration. - La journalisation des changements (qui a écrit quoi, quand, pourquoi).
## Collaborer Sans git : > Moi je modifie le fichier les jours pairs et toi les jours impairs. Sinon quand on sauvegarde on écrase les modifications de l'autre !
## Conserver l'historique Sans git, très vite on se retrouve avec : - mybook.tex - mybook-2.tex - Copy of mybook-2.tex - mybook-2-alternative-end.tex - mybook-2-alternative-end-old.tex - mybook-final.tex - mybook-final-1.tex - mybook-final-final.tex - mybook-final-preprint.tex - mybook-final-preprint-corrected.tex - mybook-final-preprint-corrected-final.tex
## Conserver l'historique > Pourtant hier soir, quand je suis parti, ça marchait… ou : > Mais que fait ce code ? Pourquoi il est là ? Qui l'a écrit ? Pourquoi ?
## Conserver l'historique On peut même demander à `git` de nous trouver automatiquement quelle modification à introduit un bug.
## Introduction Comment, sans `git`, pourraît-on résoudre ces deux problèmes ?
## Analogie ![Moteur Vulcain](static/Moteur-Vulcain.jpg)
## Analogie En prenant une photo du projet (entier) à chaque modification. Au dos de la photo on pourrait même rajouter des meta-données : - Nom de celui qui a fait la photo. - Date à laquelle la photo à été prise. - Pourquoi on a pris la photo à ce moment là. - Et pourquoi pas une signature !
## Analogie Est-ce que ces photos résolvent nos problèmes ?
## Analogie Pour conserver l'historique, oui, c'est gagné !
## Analogie Pour collaborer on va devoir s'envoyer les photos par pigeon voyageur. - À chaque fois que je reçois une photo, j'applique la modification à ma version. - À chaque fois que j'ai terminé une étape, j'envoie une photo de ma progression.
## Analogie Parfois deux photos vont se contredire, par exemple : - Un collègue à essayé de nouveaux injecteurs en cuivre. - Vous avez essayé de nouveaux injecteurs imprimés en 3D.
## Analogie Je vais devoir prendre une décision : - Prendre ma version. - Prendre sa version. - Prendre un peu des deux.
## Analogie Le résultat sera un nouvel état, encore plus avancé du projet, vite, je le photographie, je commente au dos de la photo les raisons de ce choix, et je l'envoie au collègue.
## Analogie Mais souvent les séries de photos ne vont pas se contredire : chacun travaille sur sa partie.
## Analogie Catastrophe, une pile de photo est tombée, et personne ne sait comment remettre ça dans l'ordre. Qu'aurai-on pu faire pour ne pas que ça arrive ?
## Analogie Au dos de chaque photo on écrit un identifiant **unique**. Au dos de chaque photo on écrit aussi l'identifiant de la photo précédente !
## Analogie Notez qu'une photo peut ne pas avoir de photo précédente. C'est la première photo.
## Analogie Notez qu'une photo peut avoir deux photos précédentes, c'est la photo faite après la résolution d'une contradiction : - Une des deux précédentes vient de **ma** pile. - L'autre vient de **sa** pile.
## Analogie Notez enfin que l'identifiant d'une photo peut aisément être utilisé **plusieurs fois** : - Soit pour faire plusieurs tests différents à partir d'un même état. - Soit lorsqu'un collègue se met à travailler sans pour autant que je m'arrête.
## Avec git « Prendre une photo » c'est
« faire un `commit` ». Dans un jeu vidéo ce serait « Sauvegarder ». Abusez-en.
## Avec git Ce qui est commit ne peut pas être perdu¹.
¹: Sauf si votre machine brûle.
## Avec git Envoyer un carton de photos c'est « un `push` ».
## Avec git ![In case of fire](static/in-case-of-fire.png)
## Avec git Récupérer un carton de photos c'est « un `fetch` ».
## Avec git Une contradiction entre deux séries de photos c'est « un `conflit` ».
## Avec git La photo de résolution d'un conflit c'est « un `merge` ».
## Avec git Comme avec une photo on peut aussi choisir ce qui sera dans le cadre, ça s'appelle le « staging area », la scène dans notre analogie.
## Avec git Typiquement on ne va pas photographier nos outils, la servante, ... Ils ne font pas vraiment partie du projet : on les pousse hors champ à chaque photo. (C'est le `.gitignore`.)
## Avec git Mais typiquement on va ajouter à la photo chaque nouvelle pièce, dès sa réception, même si elle n'est pas encore bien branchée. (C'est un `git add`.)
## Avec git Comme avec nos photos, chaque `commit` permet de connaitre l'état **complet** du projet au moment où il à été fait.
## Petite parenthèse CLI `git` n'est pas graphique : il nous faut un bon terminal et un bon shell.
## Le terminal Tout émulateur de terminal sur MacOS et Linux fera l'affaire.
## Le terminal Sur Windows : - Oubliez `cmd.exe`, ça n'est plus maintenu depuis plus de 10 ans. - `PowerShell` : sa syntaxe n'est pas standard, mais ça fonctionne. - WSL : Ça vous ouvrira d'autres portes intéressantes. - git-for-windows : L'émulateur de terminal est correct, et ça vous apporte bash.
## Le shell Tout bon shell (bash, zsh, fish, tcsh, ...) fera l'affaire. Les caractéristiques d'un bon shell, pour moi, c'est : - De bons raccourcis clavier. - Une bonne auto-complétion.
## Le shell Les commandes indispensables : - `git` : pour versionner ses projets. - `ls` : pour `list` directory entries. - `cd` : pour `change directory`.
## Le shell Les commandes utiles : - `rm` : pour supprimer. - `mv` : pour renommer ou déplacer. - `mkdir` : pour créer un dossier. - `man` : pour lire le manuel.
## Installation de git Utilisez votre gestionnaire de paquets habituel : ```text apt install git # sur Debian dnf install git # sur Fedora pkg install git # sur FreeBSD brew install git # sur MacOS avec homebrew port install git # sur MacOS avec MacPorts ... ... ```
## Installation de git Sinon, sur Windows, téléchargez git via : https://git-scm.com/download/ ou git, un émulateur de terminal, et un shell via : https://gitforwindows.org/
## Installation de git Est-ce que ça fonctionne chez vous ? ```text git --version ```
## Travailler localement
## `git config` Git aura vite besoin de savoir qui vous êtes, on va commencer par lui dire : git config --global --edit Pour mettre votre nom dans vos commits.
## `git init` À exécuter en étant dans le dossier racine du projet à versionner. Cette commande ne fait qu'une chose : créer le dossier `.git`.
## Le dossier `.git` C'est là où `git` range l'historique du projet, un peu de configuration, quelques méta-informations, ... Petite exploration.
## `git clone` Sert à télécharger un projet (via HTTP, HTTPS, SSH, ...), essayez : ```bash git clone https://github.com/python/cpython cd cpython ```
## `git log` Nous permet de consulter le journal, l'historique du projet : - Chercher le travail d'un auteur en particulier. - Chercher le travail sur un fichier en particulier. - Chercher les modifications qui contiennent un mot spécifique. - ...
## `git log` Trouvez-moi la date du dernier commit de Python 2 via: ```text $ git log v2.7.18 ```
## `git log` Lisez les dernières modifications de cPython via : ```text $ git log ```
## `git log` Jettez un œil aux dernières modifications de la documentation de Python via : ```text $ git log Doc/ ```
## `git log` Trouvez-moi le commit le plus récent de Guido van Rossum en utilisant `--author`. ```text $ man git log ```
## `git status` Vous pouvez abuser de cette commande, elle vous donnera même de bons conseils : ```text $ git status Sur la branche main Fichiers non suivis: (utilisez "git add
..." pour inclure dans ce qui sera validé) main.py README.md ```
## `git add` Dans notre analogie de la photo c'est
« ajouter à la scène ». Ajouter un fichier, ou ajouter une modification, mais ajouter.
## `git grep` Un substitut à `grep`, cherchons la définition de la fonction `random` : git grep "def random(" Rapide, pour chercher dans ~200k lignes de code, n'est-ce pas ?
## `git diff` Dans notre analogie de la photo, `git diff` joue aux sept différences : - Entre notre travail et la `staging area`. - Entre la `staging area` et le dernier commit. - Entre deux commits.
## `git diff` Jettons un œil aux différences entre Python 3.10.0rc2 et Python 3.10.0 : ```text git diff v3.10.0rc2 v3.10.0 ```
## `git show` Dans notre analogie de la photo, `git show` nous montre une photo... ...ou pas : nous afficher le projet entier serait monumental.
## `git show` `git show` montre surtout les métadonnées, et la différence apportée par un commit. Regardons ce commit : ```text git show e1d455f3 ```
## Mise en pratique Créez un dossier, initialisez git, et dans un fichier disons `git-day-1.md` prenez des notes. Créez quelques commits pour apprivoiser : - git add - git commit - git log - git show - git grep
## `git branch` et `git switch`
## `git tag`
## `git switch`
## `git checkout`
## `git rebase -i`
## `git tag`
## `git reset`
## `git mv` Ou `git rm` / `git add` ? C'est pareil.
## Travailler ensemble
## `git remote`
## `git fetch`
## `git push` / `git pull`
## TODO - Technique : blob, tree, commit, tag. - Technique : graphe orienté sans cycles. - Technique low level : En partant des commandes de base. - Analogie "photo" : un commit est une photo (donc immuable) de l'état du projet. - Envoyer la photo par la poste c'est "git push" : une fois poussé il n'y a plus moyen de rien changer. - Tant qu'elle n'est pas postée, on peut toujours la déchirer. Ajouter https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRMWWzVbPEKe6JITYNNJ0AqsqWQlIxV2KDHxQ&usqp=CAU dans une slide :)