Git
dVCS != VCS
- dépôt local != dépôt distant
- upstream / origin
- local = sans connexion internet : add, commit, historique...
- brancher facilement
- remiser (stash) ou "mettre sur étagère" (shelf) facilement
- ré-écriture facile de l'historique
git != svn
- git checkout != svn checkout
- git add ~= svn add
- git commit != svn commit
- git push ~~= svn commit
- git fetch ~~= svn update
- git pull ~~= svn update
- git merge ~= svn merge
- git rebase n'existe pas en SVN
- git reset n'existe pas en SVN
- git revert !!!= svn revert
- git cherry-pick n'existe pas en SVN (émulation avec merge)
- git log ~= svn log
- git diff ~~= svn diff
git workflow != svn workflow
GUI vs SHELL
L'interface graphique,
Say le mal,
mais Shell le bien !
Bash ou Zsh ?
(Pfff, quelle question !)
-
La terminologie (Console, Terminal, Shell, CLI)
-
La complétion
- Le prompt
Les entrailles de git
- VCS ?
- dVCS ?
- BDD ?
- Où les données sont-elles stockées ?
- Quelles données ?
Les entrailles de git
Terminologie :
- blob, tree, commit, tag
- ref
- commit message
- hash (SHA-1)
- répertoire de travail (working directory/tree)
- index (staging area)
Les objets stockés dans .git
$ git init test
Initialized empty Git repository in /tmp/test/.git/
$ cd test
$ find .git/objects
.git/objects
.git/objects/info
.git/objects/pack
$ echo 'Hello git!' | git hash-object --stdin
7a860024518c83a85d6e0292e3c3d749b509173e
$ echo 'Hello git!' | git hash-object -w --stdin
7a860024518c83a85d6e0292e3c3d749b509173e
$ git cat-file -t 7a860024518c83a85d6e0292e3c3d749b509173e
blob
$ git cat-file -s 7a860024518c83a85d6e0292e3c3d749b509173e
11
$ git cat-file -p 7a860024518c83a85d6e0292e3c3d749b509173e
Hello git!
Les objets stockés dans .git
$ ls .git/objects/*
.git/objects/7a:
860024518c83a85d6e0292e3c3d749b509173e
.git/objects/info:
.git/objects/pack:
Les objets stockés dans .git
$ git cat-file -p 796c1
tree cbe0780272b6cf0e141079b7e245f3eabac29a06
author Stanislas Ormières <stanislas.ormieres@smartfocus.com> 1436364788 +0200
committer Stanislas Ormières <stanislas.ormieres@smartfocus.com> 1436364788 +0200
First Commit
$ git cat-file -p cbe07
100644 blob 557db03de997c86a4a028e1ebd3a1ceb225be238 README.md
040000 tree db78f3594ec0683f5d857ef731df0d860f14f2b2 new_dir
$ git cat-file -p 557db
Hello World
$ git cat-file -p db78f
100644 blob 557db03de997c86a4a028e1ebd3a1ceb225be238 README.md
$ tree
.
├── new_dir
│ └── README.md
└── README.md
Cycle typique
modification -> add -> commit -> checkout (merge, rebase…)
Terminologie
- Repository = database of the objects
- Modified (état du répertoire de travail courant)
- Staged (état du prochain commit)
Les 3 états du dépôt
- Clean (état du commit courant)
- Modified (état du répertoire de travail courant)
- Staged (état du prochain commit)
Clean
Modified
Staged
Modification
Staging (add)
Commit
Clean
Modified
Staged
Modification
Staging (add)
Commit
reset/co
&& add
Unstaging (reset)
checkout
Terminologie et concepts
Terminologie
Branch
Une "branche" dans Git :
- Conceptuellement : un pointeur mouvant vers la tête d'une ligne de développement, une branche master par défaut existe toujours.
- Physiquement : un fichier de 41 caractères
Conséquences :
- très peu couteux d'en créer, d'en effacer, de modifier le nom...
- très facile à merger
Terminologie
heads, HEAD
- chaque branche dans Git a une tête (head), qui est le pointeur vers le dernier commit de sa ligne de développement ;
- HEAD est le pointeur vers le commit récupéré (checkout) de la branche courante : il n'y a qu'un HEAD par dépôt git ;
- lorsque la HEAD ne pointe pas vers une tête de branche (head), on dit qu'on est sur une tête détachée (detached HEAD).
Commit often, push... less often
- tous les commits sont dans la base de données de git
- on peut récupérer n'importe quel commit (cf plus loin)...
- ...même s'ils sont orphelins (cf plus loin)... (en tout cas s'ils n'ont pas été pris par le ramasse-miettes - GC)
- tous les commits peuvent être remaniés et réordonnés (ré-écriture de l'historique)
- un commit a toujours au moins un parent (sauf le premier commit - root commit) identifié par un hash SHA-1
- une ré-écriture d'historique implique un changement du hash du ou des derniers commits
- si un changement de hash intervient avant le dernier commit publié, les clones du dépôt ne pourront retrouver le commit parent de leurs commits à eux
- ce qui a été publié (git push sur une branche publique) ne doit pas voir son historique ré-écrit (sauf si une seule personne travaille dessus)...
- ...car tous ceux qui travaillent sur un clone du même dépôt qui a cette branche ne pourront plus synchroniser cette branche avec le dépôt distant
Commit often, push... less often
-
git commit --amend
-
git rebase -i <SHA-1>
-
git commit --fixup/squash <old SHA-1> && git rebase -i --autosquash <older SHA-1>
-
git reset <old SHA-1> && git cherry-pick <SHA-1> / git commit
Pourquoi et comment
récrire l'historique
- merge
- rebase
- fast-forward
Stratégies de gestion de branches
Merge
Rebase
Stratégies de gestion de branches
Stratégies de gestion de branches
Merge
Stratégies de gestion de branches
Rebase après fusion
Stratégies de gestion de branches
Fusion après fusion
- Difficile de s'y retrouver
- Difficile de retrouver l'apparition d'un bug
Fusion en avance rapide (fast forward merge)
- Perte d'information des branches
- Quel commit concerne quelle feature ou bugfix ?
Fusion en avance rapide + écrasement
(squash + fast forward merge)
- Perte d'information des commits
- Difficile de retrouver l'apparition d'un bug
- voir le graph --graph
- voir les branches --decorate=short|full
- les commits en une ligne --oneline
- chercher dans les les lignes modifiées commits -S
- voir les patch -p
- ne pas afficher les différences concernant les espaces blancs -w
- aller plus loin : --word-diff=<regex>
Options de log
Les dépôts distants
Terminologie
- upstream, origin, remote, refspec
- les différents types de branches
-
tag simple
- tag annoté
Travailler avec les dépôts distants
- Réviser merge et rebase et s'en servir avec les branches distantes
- savoir utiliser plusieurs dépôts distants
- merge/pull request
-
les différents flowconnus (au moins git flow etgithub flow)
Travail de précision
- ajouter des hunks à l'index
- editer des hunks
- rebaser
- autosquash (déjà-vu)
- reset
- reflog
- savoir récupérer n'importe quel commit
Copy of Git != SVN
By Stanislas Ormières
Copy of Git != SVN
- 588