ℹ️ These slides are also available in English!
👩💻 Version autonome (pour lecture en solo)
Un système de contrôle de version (VCS) distribué
= système permettant de gérer différentes versions d'un ensemble de fichiers
(Beaucoup de versions intermédiaires entre deux releases !)
Souvent utilisé pour travailler à plusieurs sur un projet... entre autres !
Git ≠ GitHub, GitLab, Gitea, etc.
Git = outil logiciel (en ligne de commande)
GitHub et GitLab = services d'hébergement de dépôts Git
Linux ≠ OVH, par exemple
Bénéfices sur plusieurs niveaux :
Ça vaut le coup !
Commençons avec une parenthèse sur le mot «distribué»
Vous avez peut-être entendu dire que Git était un système de contrôle de version distribué.
Qu'est-ce à dire ?
❗️ Promis, rien de compliqué ! (il y aura plein d'images)
Git est basé sur un graphe.
Un commit est identifié de manière unique par son hash.
Toutes les informations d'un commit, y compris le contenu des fichiers, sont passées à une fonction de hachage pour obtenir son hash.
Principe d'une fonction de hachage : on lui passe des données (une suite d'octets), elle retourne un nombre («hash») ; deux entrées identiques ⇔ deux hashs identiques.
(Plus d'infos sur Wikipédia pour les curieux)Le hash d'un commit est un très grand nombre, présenté en hexadécimal : 6828f7bf493cd4c9c332ea769e6e38fbbe258821.
Les hashs sont souvent raccourcis (par défaut à 7 caractères) : 6828f7b, c'est ce qu'on utilisera dans ce cours.
Il n'y a pas que les commits qui pointent sur des commits.
Il y a aussi des branches, des tags, et quelques autres choses. (On parlera de leurs différences plus tard)
Pour créer un commit...
... on l'ajoute simplement au graphe.
Il n'y a pas de piège, on ne fait jamais qu'ajouter des commits au graphe.
Parlons tout de même de ce qui se passe quand on le fait.
HEAD
HEAD
désigne le commit qui est actuellement checked out.
C'est-à-dire, il s'agit du commit dont le contenu (les fichiers) est actuellement présent dans le répertoire.
On peut considérer le commit pointé par HEAD
comme «là où on se trouve actuellement».
HEAD
Et quand on crée un nouveau commit ?
HEAD
suit le nouveau commit (il est automatiquement checked out).
Et quand on crée un nouveau commit ?
Une branche suit le commit si et seulement si elle est checked out.
Un tag est inamovible et ne peut pas être checked out, il ne suit donc jamais un nouveau commit.
(Pour «déplacer» un tag, il faut le supprimer et le re-créer ailleurs.)
➔ Une branche sert à suivre quelque chose (développement d'une fonctionnalité...) ; un tag sert à marquer un commit particulier (version...)
Essayez d'éviter les interfaces graphiques si possible.
(Au moins au début.)
Par exemple, leur gestion des erreurs est souvent hasardeuse...
$ git init
Crée un nouveau dépôt dans le répertoire courant.
Réponse : le répertoire1 .git
.
1 Dans certains cas c'est un fichier.
Apparemment il y a eu une erreur ?
Créons quelques fichiers.
Promis c'est le dernier truc
Git permet de choisir quelles modifications vont être enregistrées dans le prochain commit.
On le fait via la commande git add
suggérée par le message d'aide plus tôt.
On vient de voir git commit
ouvrir un éditeur de texte.
Éditeur de texte utilisé par les commandes Git. Cette valeur est intérprétée par le shell quand elle est utilisée. Exemples :~/bin/vi
,$UNE_VARIABLE_D_ENVIRONNEMENT
,"C:\Program Files\Vim\gvim.exe" --nofork
. L'ordre de préférence est la variable d'environnement$GIT_EDITOR
, puis la configurationcore.editor
, puis$VISUAL
, puis$EDITOR
, puis la valeur par défaut choisie à la compilation, qui est habituellementvi
.
GIT_EDITOR
dans git-var
.
L'éditeur utilisé par défaut est vi
, qui a une ergonomie... particulière.
Pour le changer pour nano
(par exemple) :
$ git config --global core.editor "nano"
EDITOR
dans son .bashrc
/.zshrc
fonctionne aussi.
# ...
export EDITOR=nano
# ...
Oui c'est possible !
Il faut cependant s'assurer que la commande ne quitte que quand le fichier est fermé :
$ git config --global core.editor "subl -w"
$ git config --global core.editor "code -w"
Git sur sa machine = outil de backup (et plus)
Git sur plusieurs machines = 🤯
Chaque machine contient un dépôt Git. Répertoire .git
, etc.
On peut «pousser» des modifications vers une autre machine, et «tirer» des modifs depuis.
git clone
git pull
git push
Git modélise les machines distantes via des remotes. («Remote» en anglais = «distant»)
Une remote = un certain repo sur une certaine machine (grosso modo).
On gère les remotes via git remote
!
git fetch
Git ne va pas faire des requêtes à chaque commande.
Pour se tenir au jus : git fetch <remote>
.
(git pull
appelle implicitement git fetch
.)
...mais Git couvre nos arrières.
issotm@sheik-kitty /tmp/test% git push
To example.com:chemin/vers/repo.git
! [rejected] master -> master (non-fast-forward)
error: failed to push some refs to 'example.com:chemin/vers/repo.git'
hint: Updates were rejected because a pushed branch tip is behind its remote
hint: counterpart. Check out this branch and integrate the remote changes
hint: (e.g. 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
... «non-fast-forward» ?
«Fast-forwarder» une branche signifie «la déplacer uniquement vers des commits enfants» :
«Fast-forwarding» parce que «avance rapide» dans le temps.
Fast-forward = toujours safe (on ne peut «perdre» aucun commit).
...et dans les autres cas ?
git merge
git rebase
Avantages :
Inconvénients :
git merge <commit>...
Crée un nouveau commit sur la branche actuelle qui «rassemble» la branche actuelle et tous les <commit>
s.
On expliquera ce que «rassemblement» signifie quand on parlera de rebase
.
Exemple : git merge master
git rebase <nouv-base> [<branche>]
Si <branche>
est omis, la branche courante est modifiée.
Exemple : git rebase master
(ou git rebase master add-dark-mode
)
git init
⚠️ Crée un repo dans le répertoire courant !
git clone <URL>
git status
issotm@sheik-kitty /tmp/rgbds% git status
On branch master
Your branch is up to date with 'origin/master'.
nothing to commit, working tree clean
git status
issotm@sheik-kitty /tmp/rgbds% git status
On branch master
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 restore <file>..." to discard changes in working directory)
modified: .editorconfig
deleted: .checkpatch.conf
no changes added to commit (use "git add" and/or "git commit -a")
git add
issotm@sheik-kitty /tmp/rgbds% git add .editorconfig
issotm@sheik-kitty /tmp/rgbds% git status
On branch master
Your branch is up to date with 'origin/master'.
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
modified: .editorconfig
Changes not staged for commit:
(use "git add/rm <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
deleted: .checkpatch.conf
Un visualiseur plus joli pour git diff
et git blame
: delta
On peut afficher le statut Git dans son prompt de shell (par ex. via powerlevel10k)
Une bonne interface graphique (certes freeware) : Sublime Merge (je recommande car elle liste les commandes exécutées)
Si vous utilisez un IDE, il a peut-être une intégration Git (parfois via extensions), lisez la doc
Les slides sont disponibles en ligne : https://eldred.fr/slides/git!