Cours GIT : révision des commandes de base; Principe de git flow et hooks
% Git - Niveau2
% Manuel Tancoigne
% Novembre 2017
Révisions
Pour de l'aide sur une commande git : git <commande> --help
Dossiers et fichiers:
dossier .git
: Dossier où sont stockées les informations du dépôt. Il suffit de le supprimer pour enlever Git.
fichier .gitignore
: Exceptions (git ls-files --other --ignored --exclude-standard
pour la liste des fichiers ignorés.
fichier .gitattributes
: Spécifications sur les formats de fichiers (encodage, fin de ligne, etc...)
Autres:
dossier .github
: Fichiers de config spécifiques à github.
Configuration avec git config
La configuration peut être faite pour le dépôt, ou être globale pour l'utilisateur courant (avec l'option --global
).
git config user.name "name"
: Définit le nom pour la signature des commits.
git config user.email "email
: Email servant de sugnature aux commits.
Création
git init "dépôt"
: Créée un dépot vide du nom de dépôt.
git init .
: Créée un dépot dans le dossier actuel.
git clone "adresse"
: Clone le dépot de l'adresse spécifiée dans un nouveau dossier
git clone "adresse" "destination
: Clone le dépot dans le dossier destination.
Appliquer des changements
git status
: Affiche l'état du dépôt
git diff
: Affiche les différences non appliquées (hors stage)
git add "fichier"
: Applique un changement (stage)
git add .
: Ajoute tous les fichiers modifiés à la liste de modifications (stage)
git reset "fichier"
: Enlève un fichier de la liste de modifications (unstage)
git diff --staged "fichier"
: Affiche les différences entre le fichier stagé et sa dernière version
git commit -m "message"
: Créée un commit avec le "message". Seuls les fichiers stagés seront commités
git commit -am "message"
: Ajoute tous les fichiers modifiés à la liste de modifs (stage) et créée un commit.
Etiquettes
git tag
: Liste des étiquettes
git tag -n
: Liste des étiquettes avec messages
git tag -l "v2.5.*"
: Liste les étiquettes avec un certain nom
git tag v2.5
: Créée une étiquette sans description (lightweight) sur le commit actuel
git tag v2.5 -m "Nouvelle version"
: Créée une étiquette avec une description sur le commit actuel
git tag -a v3 "sha" -m "Version 3 !"
: Créé une étiquette sur un commit anterieur correspondant au hash donné
git show "tag"
: Affiche les informations de commit sur un tag donné
Déplacement/suppression
git rm "fichier"
: Supprime un fichier et applique le changement (stage)
git rm --cached "fichier"
: Supprime un fichier de git mais garde le fichier localement. Pratique pour enlever un fichier de git avant de l'ignorer.
git mv "fichier source" "fichier-dest"
: Renomme/déplace "fichier source" et applique le changement (stage)
Rembobiner
git reset "commit"
: Défait tous les commits après "commit" mais garde les changements locaux.
git reset --hard "commit"
: Défait tous les commits après "commit" et ne garde pas les changements.
Historique
git log
: Affiche l'historique, version complète
git log --oneline
: Affiche l'historique, version condensée.
git log --follow "fichier"
: Affiche l'historique de "fichier". Prends en compte les changements de nom.
git diff "branche1" "branche2"
: Affiche les différences entre deux branches.
git show "commit"
: Affiche les informations relatives à un commit.
git show "etiquette"
: Affiche les informations relatives à un commit.
git blame "fichier"
(voir 1)
: Affiche les personnes ayant modifié chaque ligne d'un fichier.
(1) - Exemple de git-blame "fichier"
007bfcdd (Olive 2017-04-02 22:39:33 +0200 3) <div class="form-card__body">{{delegate.title}} {{delegate.first_name}} {{delegate.last_name}}</div>
007bfcdd (Olive 2017-04-02 22:39:33 +0200 4)
007bfcdd (Olive 2017-04-02 22:39:33 +0200 5) <div class="form-card__actions">
0aa7a163 (Manuel Tancoigne 2017-10-23 16:30:34 +0200 6) <button @click="displayPanel('edit')"><i class="fa fa-pencil"/><span class="visually-hidden">Editer</span>
0aa7a163 (Manuel Tancoigne 2017-10-23 16:30:34 +0200 7) </button>
0aa7a163 (Manuel Tancoigne 2017-10-23 16:30:34 +0200 8) <button @click="displayYesNo('delete')"><i class="fa fa-times"/><span class="visually-hidden">Supprimer</span>
0aa7a163 (Manuel Tancoigne 2017-10-23 16:30:34 +0200 9) </button>
212ce984 (Manuel Tancoigne 2017-03-30 12:32:45 +0200 10) </div>
Branches
git branch
: Affiche les branches et la branche actuelle (avec un *
) (voir 2))
git branch -v
: Affiche les branches et leurs derniers commit (voir 3)
git branch "nom"
: Créée une nouvelle branche
git checkout "branche"
: Se place sur la branche "branche" et met à jour les fichiers. Garde les changements si possible
git checkout -b "branche"
: Créée une nouvelle branche et se place sur celle-ci.
git branch -d "branche1"
: Supprime la "branche1", localement si elle a été mergée.
git branch -D "branche1"
: Supprime la "branche1", localement même si elle n'a pas été mergée.
(2) - Exemple de git branch
dev
feature/newgui
fix/Important
* master
olive
release/1.2.0
(3) - Exemple de git-branch -v
dev 3129407 Updated roadmap and changelog
feature/newgui ab10ccc Updated changelog and version
fix/Important 2e21708 Fixed modal structure for v-bar
* master 3129407 Updated roadmap and changelog
olive c884b63 WS tests
release/1.2.0 84c2708 Updated roadmap
Combinaison de branches
git merge "branche"
: Combine la branche spécifiée dans la branche courante.
git merge "branche1" "branche2"
: Combine la "branche1" dans la "branche2"
git merge --no--ff
: Force la création d'un merge commit lors de la combinaison de branche. Pratique pour garder une trace (ex: pour une fin de tâche spécifique par exemple)
git merge --ff-only
: Ne combine les branches que s'il n'y a pas besoin de créer de commit (ex: s'il n'y a pas de conflit à gérer)
Manipulation de commits
git rebase --interactive --autosquash HEAD~N
: Fusionne N
commits pour n'en faire qu'un
git cherry-pick -n "sha"
: Incorpore le commit avec le hash donné
git revert -n "sha"
: Créée un commit qui annule le commit avec le hash donné
Synchronisation distante
git remote -v
: Liste les differentes copies distantes enregistrée;
git remote add "url"
: Ajoute une référence vers une copie distante.
git fetch "remote"
: Télécharge l'historique d'une copie distante. Ne change rien au dépôt local
git fetch "remote" "branche"
: Télécharge l'historique d'une branche donnée d'une copie distante. Ne change rien au dépôt local
git merge "remote"/"branche"
: Combine une branche distante dans la branche courante.
git push
: Envoie les derniers commits de la branche actuelle sur la remote principale
git push "remote"
: Envoie les derniers commits de la branche actuelle sur la remote spécifiée
git push "remote"/"branche"
: Envoie les derniers commits de la branche actuelle sur la branche spécifiée de la remote spécifiée...
git pull
: Récupère et applique les changements provenant de la remote principale
git pull --rebase
: Récupère les changements provenant de la remote principale et applique les vôtres.
Git-flow
Git flow est une méthode de travail permettant de standardiser son flux de versions:
- Fonctionnalités
- Releases
- Hotfixes
La branche principale est la branche master
; elle est stable et doit pouvoir être poussée en prod
La branche de travail est develop
ou dev
; c'est elle qui va acueillir les nouveautés
Fonctionnalités:
Une fonctionnalité, ou feature commence obligatoirement à partir de la branche de développement. Elle doit avoir un nom commençant par feature/
Bien que les fonctionnalités sont généralement uniquement locales, elles peuvent tout de même être partagée comme une branche standard aux autres développeurs.
# On part de dev
git checkout dev
# On créée la fonctionnalité et on bascule sur la nouvelle branche
git checkout -b feature/mailer
Une fois terminée, la fonctionnalité doit être combinée à la branche de développement avec un commit. Celà permet de garder un arbre de versionning propre, tout en gardant la trace des actions liées à une fonctionnalité donnée.
La feature doit ensuite être supprimée, afin d'éviter les futures erreurs.
# ... On a fait plein de commits
# On rebascule sur dev
git checkout dev
# On merge avec un commit
git merge feature/mailer --no-ff
# On supprime ensuite la branche:
git branch -d feature/mailer
Hotfixes
Les hotfixes sont des branches partant de master, destinées à corriger un bug en production. Elles doivent avoir un nom commençant par hotfix/
.
# On part de master
git checkout master
# On créée le hotfix et on bascule sur la nouvelle branche
git checkout -b hotfix/bug-login
Une fois terminé, le hotfix doit être mergé au master (et étiquetée) et à la branche de développement. Chaque développeur pourra ensuite l'incorporer à ses propres fonctionnalités.
La branche du hotfix sera ensuite supprimée.
# ... On a fait plein de correctifs
# On rebascule sur master
git checkout master
# On merge avec un commit
git merge hotfix/bug-login --no-ff
# On créée l'étiquette
git tag bug-login -m "Correctif bug login"
# On merge avec dev:
git checkout dev
git merge hotfix/bug-login --no-ff
# On supprime ensuite la branche:
git branch -d feature/mailer
Attention, ne pas oublier de pousser l'étiquette :
git push --tags
Releases
Les realeases sont des branches préparant une nouvelle version. Elles permettent de finaliser le développement et de corriger les bugs restants lorsque toutes les fonctionnalités d'une version sont prêtes. Elles sont donc créées à partir de la branche de développement et doivent commencer par release/
.
# On a fini les features nécessaires
# On passe sur dev
git checkout dev
# On créée la branche de release et on bascule dessus
git checkout -b release/v1.0.0
Une fois terminée, la release est mergée au master avec un merge-commit. Une étiquette est ensuite associée à ce commit pour le référencer. Puis, la branche est mergée à dev.
# On a fait les modifs nécessaires sur la branche de release
# On passe à master
git checkout master
git merge release/v1.0.0 --no-ff
# On créée l'étiquette
git tag v1.0.0 -m "Version 1 terminée"
# On merge dans dev
git checkout dev
git merge release/v1.0.0 --no-ff
# On supprime la branche
git branch -d release/v1.0.0
Attention, ne pas oublier de pousser l'étiquette :
git push --tags
Outils
Il existe un outil, git flow
permettant de réaliser ces taches de manière plus rapide. Il est généralement intégré aux clients git type SourceTree, GitKraken ou SmartGit.
Git hooks
Les hooks sont des scripts lancés avant ou après qu'un commit ait eu lieu. Il permet :
- d'interagir sur le commit et de bloquer sa validation (ex: messages trop courts, fautes, tests unitaires)
- déclencher des actions si le commit est validé (ex: passage en production)
Ce sont des scripts placés dans .git/hooks
, et chaque dépôt vide est initialisé avec des exemples:
pre-commit.sample:
#!/bin/sh
#
# An example hook script to verify what is about to be committed.
# Called by "git commit" with no arguments. The hook should
# exit with non-zero status after issuing an appropriate message if
# it wants to stop the commit.
#
# To enable this hook, rename this file to "pre-commit".
[...]
Format des fichiers
Les fichiers de hook sont executables, il faut donc vérifier leur permission (chmod +x
). De plus tous les fichiers se terminant par .sample
sont ignorés.
Les fichiers de hook n'ont pas d'extension; l'interpréteur est déterminé par le shebang du fichier et il est tout à fait possible d'utiliser des langages de programmation plus poussés que le simple shell (ex: #!/usr/bin/env python
pour un hook en python).
Portée
Les hooks sont locaux: ils ne sont pas commités et partagés entre les dépôts. Ce qui veut dire que vous ne pouvez forcer personne à les utiliser.
Hooks locaux
Les hooks "locaux" sont uniquement utilisés sur les clients (sur les machines des développeurs). Ils servent généralement à aider le développeur dans ses tâches
- pre-commit (juste avant que git ne demande un message lors d'un
commit
) - prepare-commit-msg (prépare le message de commit)
- commit-msg (Juste après que le message soit entré. Peut stopper le commit)
- post-commit (Ne peut pas stopper le commit. Sert principalement de notification)
- post-checkout (juste après
git-checkout
. ex: supprimer une build avant màj) - pre-rebase (Juste avant
git rebase
)
Hooks serveur
Les hooks serveur sont uniquement utilisés sur les serveurs git (type GitHub, BitBucket,...). Ils servent à tester et rejeter des commits ne correspondant pas aux standards voulus (style du code, tests non validés, etc...). Les messages d'erreur sont renvoyés au client, ce qui lui permet de comprendre ce qu'ils se passe en cas de problème. (note: tant que le serveur n'a pas envoyé de réponse, le terminal utilisateur est bloqué...)
- pre-receive (sur
git push
) - update (après le pre-receive)
- post-receive (en fin de
git push
, lors d'un succès)
Templates
Il est possible de créer des templates pour le dossier .git
(par défaut: /usr/share/git-core/templates
).
Pour utiliser un template lors de la création d'un dépot, utiliser l'option --template="chemin/vers/le/dossier/de/template"
.
Si --template
n'est pas défini, git va regarder dans les dossiers suivants :
--template
$GIT_TEMPLATE_DIR
si définiinit.templateDir
(défini avecgit config --global init.templateDir="chemin"
)- le dossier par défaut,
/usr/share/git-core/templates
Leave a comment
You want to react to this content or ask something to the author? Just leave a comment here!
Note that the comments are not publicly visible, so don't worry if you don't see yours.
All the information you give will only be visible to the author. We don't share anything with anyone.