# Git
une présentation sur le pouce par **Pierre Baillet**
*@octplane* sur twitter
pierre@baillet.name
Septembre 2014-Janvier 2017
## Présentation
- Pierre Baillet @octplane, pierre@baillet.name
- Manager technique et Consultant Senior chez IPPON Technologies
- DevOps chez fotopedia pendant 4 ans et demi
- Directeur du développement puis de la production chez IDM pendant 8 ans
- Utilise des SCMs depuis 1998 seul ou à plusieurs
# Au menu
*en vous souhaitant un bel appétit*
- petit historique
- qu’est Git ?
- ses outils
- en local
- à distance
- interlude
- gestion des branches
- limites de l’outil
- pour aller plus loin
# Historique
*Back to the future*
- SCM ? Software configuration management
- Ancêtre et Concurrents :
- Microsoft Sourcesafe
- RCS
- CVS
- Subversion
- Perforce, Bitkeeper
- baazar, mercurial, arch
## Subversion
- crée en 2000
- écrit pour corriger quelques bugs de CVS
- commit atomique
- support du `rm`, `mv`
- support des permissions
## Subversion - Limites
- forcément client/serveur
- branche/tags/répertoires, tous a la meme enseigne
- gestion du binaire/pas-binaire parfois un peu difficile, $Id$
- line-ending délicats suivant les plateformes
- diff compliqué à effectuer entre plusieurs branches/tags/autres
- pas décentralisé
- dès qu’on commite, **le code part sur le repository**
- parfois un peu poussif
- externals pas très pratique
# Git
*guitte*
## Git qu’est-ce donc ?
- Linus Torvald
- pour maintenir les sources du noyau linux à la place de Bitkeeper (propriétaire)
- nom : « personnage déplaisant »
- gérer les patchs par email
- décentralisable
- plus « bas-niveau » que svn (design opposé à CVS)
## Les outils
- git en CLI
- Sourcetree par Atlassian
- Github, Bitbucket
- Gitlab, Gitosis…
# En local
*dans son garage*
## Les indispensables
- `git help truc` # indispensable et très complet
- `git diff` # grand classique
- `git status` # informations sur l’état de la copie locale
- `git add` # ajout d’un fichier à l’index
- `git rm` # :-)
- `git log` # très configurable
## Les indispensables…
- `commit -a`
- dans SVN, on dit souvent qu’il faut commiter quand « tout compile »
- dans git, c’est moins important parce qu’on peut commiter n fois avant de transmettre ses changements à distance
- **COMMITER SOUVENT**
- peut sauver la carrière d’un imprudent
## Workflow - version 0
git init . # crée un repository vide ici
git add fichier.txt # ajoute fichier.txt à l'index
vim fichier.txt # on modifie le fichier
git status # on affiche le status du repository
git diff
touch fichier2.txt
git add fichier2.txt
git commit .
git rm fichier2.txt
git status
git commit .
git log
# À distance
*a deux ou plus, c’est mieux*
## À distance
- ssh
- git
- webdav
- http
## La décentralisation
- l’origin
# En pratique
*en théorie, il n’y a pas de différence entre la théorie et la pratique.*
## svn checkout…
git clone user@host:path/to/repository.git
- clone un repository distant. Par défaut, une seule branche est complètement clonée, mais les autres références de branches sont récupérées également
- peut prendre un temps certain
## svn update
git pull (--rebase)
- fait avancer la référence locale à la dernière version présente dans l’index pour la référence courante (fetch puis merge)
- si des commits existent en local et pas encore à distance, joue les nouveaux commits par dessus, sauf si `--rebase` où les commits sont rejoués suivant l’ordre temporel.
## svn revert .
git reset --hard
- remet à zéro une partie de l’index ou du répertoire de travail
## mkdir -p repo/branches/mabranche
git branch mabranche
Branch crée des références dans l’arbre des commits. Une référence pointe vers un commit et peut :
- être *déplacée* (push d’une branche locale avec des commits à distance)
- être *supprimée* (push de "" vers la branche distante)
- être *copiée* dans une autre référence (push de la branche vers autre une autre référence)
## cd branches/mabranche
git checkout -b mabranche --track origin/mabranche
## svn update -r 121212
git checkout 121212
## svn revert fichier.php
git checkout fichier.php
## git checkout
- Altère la copie de travail pour la version pointée par le commit donné
- Re-extrait de l’index un fichier qui a été modifié dans l’index
## svn blame
git blame fichier_pourri.php
Idéal pour trouver le coup^C^C responsable du comportement intéressant d’un morceau de code.
## push
git push origin
- opération sur un remote à partir de données locales
- transmet les données au serveur
- Avec `-f`, peut être dangereux
## Workflow - version 1
git clone git@github.com:user/repository.git
git fetch
git checkout branch
vim fichier.php
git diff
git blame fichier.php
git commit .
git pull —rebase
git push origin
# Encore plus fort
## git tag
les tags tels qu’on les connaît
git tag prod-2014-08-01
## git cherry-pick *sha1*
( y compris des commits « plus ou moins disparus »)
## git revert (-n) *sha1*
annule un commit en le rejouant (sans le commiter).
## git stash
Prend les changements du répertoire de travail et les stocke dans un « stash ».
Super diff stockable et qu’on peut ensuite re-appliquer :
vim source.js
git stash
checkout testing
git stash pop
## git merge
git merge origin/production
- applique les commits sur le working directory propre dans l’ordre où ils ont été commités sur une référence passée en paramètre.
- on se retrouve parfois avec des conflits à gérer et il faut bien lire les messages de git pour éviter de s’énerver (peut aussi arriver dans un pull)
- on peut toujours s’enfuir d’un merge qui présente un conflit avec `--abort`…
- la résolution de conflit se fait via edition, `add` et `commit`.
## rebase ( -i )
- applique tous les changements locaux dans une branche dans une nouvelle branche.
- l’usage commun est souvent avec `-i`
- permet la ré-écriture de l’historique local pour le modifier ou le simplifier.
- utilisation plus puissante sans le `-i`
## bisect
- idée simple pour application brillante
- pour trouver des bugs
- nécessite d’avoir beaucoup de commits
- start, good, bad, skip
- peut même executer une commande pour faire le test à votre place
## pull-request
- permet à un developpeur de demander l’intégration de son code dans un remote dont il n’a pas le contrôle.
- usage par email (kernel)
- via une interface web (Github)
## reflog
- dans les logs techniques de git, tous les évènements loggés
- permet de récupérer des commits désormais inaccessibles
## Workflow - version 3
git log origin/testing
git cherry-pick -n af23c4
git stash
git checkout baillet_test_profiling
git stash pop
git commit . -m "Cherry Pick from testing"
vim file.php
git commit . -m "Added debug flag to this class"
git rebase -i origin/baillet_test_profiling
git push origin
# Gestion des branches
*Michel le jardinier informatique*
### Features Branches
<div style="height:500px;">
![](./assets/git-workflow-feature-branch-1.png)
</div>
- nouvelles fonctionnalités
- bugfix
- une seule branche **principale** à distance
### Gitflow workflow
![](/./assets/git-workflow-release-cycle-2feature.png)
- branches par version/environnement
- branches par niveau de développement
- branches pour le support des vieilles versions
## La décentralisation (bis)
- plusieurs origin
- github
- test/prod
# Limites de l’outil
*Attention: script méchant*
## Limites
- pas de tracking fichier par fichier : si un fichier est renommé, le suivre dans toute sa vie est difficile.
- pas de numéro de version « simple », un SHA1, et trouver l’ancêtre commun entre deux commits peut être difficile (bissect peut donner des résultats curieux)
- pas de centralisation par défaut (donc comprendre les origins est indispensable)
Note: On considère que le « groupe » de code forme un tout « opaque » dans lequel ce genre d’interaction est un détail.
## Limites - suite
- apprentissage (un peu) plus complexe : fonctionnalités complexes et difficiles à maîtriser
- Partie server side : ACL assez techniques à mettre en oeuvre (utilisation d’un service tiers indispensable)
- Authentification souvent par SSH, nécessite une formation supplémentaire sur SSH (clefs privés avec mot de passe, agent…)
- submodules difficiles à utiliser
# Pour aller plus loin
## Sur l’internet
- [http://git-scm.com/book/fr](http://git-scm.com/book/fr)
- [https://www.atlassian.com/fr/git/](https://www.atlassian.com/fr/git/)
- StackOverflow
## Sous le capot
- **index** qui contient les changements non encore commités
- base **clef-valeurs** (clef: SHA1)
- des **arbres** avec des listes d’objet + permissions
- un noeud de l’arbre étant juste un fichier qui contient ses propriétés (parent…) et ses sous-noeuds.
- des **commits** avec des arbres, des parents en termes de commit + un auteur et un message
- notion d’ancêtre importante dans git pour déterminer la possibilité d’appliquer des changements dans le code
- commit: **b375ec**0ff5d11aeca0f47c5bce313b9ae4b627ad
- reflog
Note: expliquer le contenu de l’index, d’un commit. Différence entre le Working directory et l’état interne de git.
## Derniers rappels
![](http://people.zoy.org/~oct/public/svn-git-hints.png)
# Questions ?
## et merci :-)