Workshop Git : initiation
git sur wikipedia
Presentation
L' outil de gestion de versions le plus populaire au monde.
Il est décentralisé : on a pas besoin d'un serveur pour l'utiliser.
Usages
Disclaimer
Plusieurs manières différentes de faire certaines actions
On montre beaucoup de commandes différentes dans cet atelier. L'objectif n'est pas de toute les apprendre, mais de sentir la philosophie et être capable de les retrouver au quotiden.
Lire les indication donnés par git qui sont très très très très utiles
Votre moteur de recherche préféré + stackoverflow sont vos amis pour trouver quoi faire en toute situation
help
git help
man git
tldr git ?
Tuto 1 : débuter en clonant un dépôt git existant (double window CLI / FS_Browser)
git clone git@github.com:mxbossard/mass.git
git clone https://github.com/mxbossard/mass.git
cd mass
git branch
git branch -r
git switch develop
git branch
git log
git log --pretty=oneline --abbrev-commit --graph --decorate
git hist ORIG_HEAD.. --stat --no-merges
Mot clés
repo : repository ou dépôt en français : structure conservant toute nos opérations git (peut être local ou distant) (un espace de stockage, une base de donnée)
tree : (arbre en français) structure de donnée interne représentant d'un dossier et tout son contenu
blob : structure de donnée intern représentant un fichier
commit : collections de fichiers & dossiers représentés par un hash (sha1)
HEAD : On peut voir ça comme une "tête de lecture" qui lit un commit et l'affiche dans notre repertoire de travail.
pathspec : expression representant un ou plusieurs chemins de fichier dans un dépôt
tree-ish : expression représentant un tree (ex: HEAD:README.md) (ex: HEAD) (les commits et tags sont déréférencés pour l'arbre vers lequel ils pointent)
commit-ish : expression représentant un commit (ex: HEAD) (ex: f8f3f58)
worktree / working tree / working directory : repertoire de travail qui reflete le contenu d'un commit
index / staging area : zone tampon qui stoque un tree contenant les modification en attente de commit
tag: pointeur vers un commit
branch : pointeur vers un commit "mouvant" auquel on attache son working tree
Tuto 2 : modifier des fichiers comparer et commit les modifications
git status
git diff
git diff HEAD
git diff HEAD^
echo foo > bar
echo baz >> README.md
mkdir pif
git status
git diff
git add .
git status
git diff
git diff --staged
git commit -m "ma modif"
touch pif/paf
git commit -a --amend
git log
git diff
git diff HEAD
git diff HEAD^
Fonctionnement
Interne
Documentation Git Internals - Git Objects
Décentralisé
Pas besoin de repo central
Tout l'historique en local
On peut commit dans son repo local
La réconciliation peut être compliqué si plusieurs personnes modifie le même fichier simultanément (classique, ce n'est pas magique)
Commit Hash (sha1)
Hash des données et méta-données contenu dans le commit. Une représentation du commit réputé unique dans un repo.
Branch
Une branche pointe vers un commit, mais à la différence du tag, on "travail sur une branche". Cela veut dire que notre espace de travail (working dir) est en général accroché sur une branche. Lorsque l'on effectue un commit, ce commit est attaché à la branche, et devient le dernier commit de la branche.
diff comme patch
Les git diff permettent de produire des fichiers patch qui peuvent être appliqués à la main.
Tuto 3 : Initialiser son propre dépôt git et travailler dessus
git init myrepo
cd myrepo
touch myfile
git commit -a -m message
echo foo > myfile
git commit -a -m foo
echo bar > baz
git checkout -b develop
git commit -a -m baz
echo bar >> baz
git status
git stash
git status
git stash list
git switch master
git status
git switch develop
git stash apply
git commit -m -a "baz2"
git tag 0.0.1
git tag
git checkout HEAD^
git checkout HEAD^^
git checkout 0.0.1
git switch develop
Forges git
Exemples de forges git "Public"
Intérêts
Des outils graphiques en plus (diff, ...)
Un repo central souvent plus pratique pour callaborer
Fork & Pull Request organisé
Pipelines
Pages
...
Exemples de solutions déployable
Il existe des outils pour déployer dans une forge git privé.
Tuto 4 : Creer et suivre (track) un remote repo (dépôt distant) sur une forge git
Demo en live sur framagit.
git remote
git remote add origin git@framagit.org:labomedia/foo.git
git remote
git remote -v
git branch -M main
git push -uf origin main
Visit URL: https://framagit.org/labomedia/foo.git
Quoi commit ?
.gitignore file permet de configurer des fichiers à ne pas commit
Attention, si vous avez commit un secret sur un dépôt distant, il faut considérer que le secret n'est plus secret.
Fichiers à commit
Fichiers à ne pas commit
des secrets (compliqué à retirer correctement)
des binaires (prend beaucoup trop de place)
des fichiers temporaires
la configuration de son IDE
Travail collaboratif
Lorsqu'on travail à plusieurs, Il est important de synchroniser sont repo local le plus souvent possible pour éviter de trop grosses divergences.
A plusieurs, il est toujours compliqué de travailler simultanément sur les même fichiers. Lorsque c'est possible, il vaut mieux s'attribuer à chacun une compétence sur des fichiers différents.
Il faut éviter de modifier les commits partagés cela équivaut à changer l'historique partagé par tous et ne vient pas sans problème sur les travaux en cours.
Reset, Restore, Revert
Il est parfois nécessaire de faire des opérations de "retour en arrière" :
Néttoyer son index (retirer des fichiers stagged) => git restore .
Néttoyer son working tree (on perd tous ses changements en cours) = > git checkout .
Annuler un commit => git revert (cela ne supprime pas le commit, mais créé un nouveau commit qui annule les modifications du commit annulé)
Modifier le dernier commit => git --amend (Il est relativement aisé de modifier des commits tant qu'ils ne sont pas partagés)
Supprimer le dernier commit => git reset HEAD^ (Il est relativement aisé de supprimer des commits tant qu'ils ne sont pas partagés)
Modifier un ancien commit => cela revient à modifier l'historique, c'est compliqué, il faut l'éviter le plus possible
Il est facile de modifier des commit dans son repo local tant qu'ils n'ont pas été partagés dans un autre repo. Toutefois, il est toujours dangereux de modifier l'historique des commit, surtout lorsqu'on travail à plusieurs.
Attention, si vous avez commit un secret sur un dépôt distant, il faut considérer que le secret n'est plus secret.
git restore
Manipule le "working tree" ou le "staging area". Ne change pas l'historique.
git revert
Annule les modifications d'un ou plusieurs commit. Ne change pas l'historique
git reset
Permet de modifier l'historique (à faire avec précaution).
Merge vs Rebase ?
Débat d'ordre philosophique non tranchable. Cela dépend des pratiques de chacun, de l'équipe et du workflow de travail.
Les 2 opérations permettent de fusionner 2 branches en une. Typiquement on va fusionner la branch develop dans la branch main lorsque l'on a terminé ses modifications sur la branch develop.
Les 2 opérations different dans la manière de réaliser cette fusion dans l'historique.
Merge
Ne modifie pas l'historique et ajoute un nouveau commit dans la branch accueillant la fusion.
Rebase
Modifie l'historique afin de faire démarrer la branch fusionné à la fin de la branche accuillant la fusion.
squash
Git workflows
Si on est nombreux sur un repo, il faut synchro son repo local souvent.
Minimal flow : quand on travail essentiellement seul (mon mien)
Au départ je ne m'encombre pas des branches et je travail sur la branche main (anciennement master)
Puis quand ma production est mature et que je veus faire de nouvelles modifications, je créé une branche develop
Lorsque je me lance dans un gros truc je créé une nouvelle branch nommé d'apres les travaux
Je tag avec une version semantic (0.0.1-rc2) chaque commit que je veux publier
J'essaye de remonter les tag commités dans la branch main autant que possible
Git flow : exemple de workflow pour travailler à plusieurs sans se marcher sur les pieds
Une doc en français
Une doc fr du plugin git-flow
Autres
TODO: Linker d'autres git flows
Pull requests
TODO
Trucs utiles
git config
Alias tiptop
git config --global alias.s "status"
git config --global alias.who "shortlog -sne"
git config --global alias.changes "diff --name-status"
git config --global alias.dic "diff --cached"
git config --global alias.d "diff --stat"
git config --global alias.hist "log --pretty=oneline --abbrev-commit --graph --decorate"
git config --global alias.lc \!"git hist ORIG_HEAD.. --stat --no-merges"
git config --global alias.amend "commit --amend"
git config --global alias.undo "git reset --soft HEAD^"
git config --global alias.spull \!"__git_spull() { git pull "$@" && git submodule sync --recursive && git submodule update --init --recursive --remote; }; __git_spull"
git config --global alias.spush "push --recurse-submodules=on-demand"
authent avec ssh
ssh keygen ?
git init --bare
TODO
Feedback 1er atelier
need git config user.email & user.name for fresh install
clone ssh repo may not works out of the box.
Montrer les schéma avant les definitions
Atelier de bout en bout git clone to pull
Atelier de bout en bout fork un repo faire une modif et proposer une PR.
Demander si on manip en premier ou si on fait les definitions en premier.
Si peu de manip, definition en premier peut etre bien.