Git
Table of Contents
1. Alternative
2. Utilisation de Git
auteur: rick <rick@gnous.eu> Fichier sous licence CC-BY-SA 4.0 (https://creativecommons.org/licenses/by-sa/4.0/).
2.1. Configuration
2.1.1. Configuration basique
On utilise la commande git config
suivi de l’option à modifier
(user.name
, user.email
…).
Exemple de commande : git config --global user.name moi
2.1.2. Configuration avancé
Plusieurs niveaux de configurations:
global
: tous les dépôts présents sur le pc (caduque si local)local
: uniquement le dépôt où on se trouve
Le fichier se trouve dans .git/config
(local) et ~/.gitconfig
(global).
git config --global --list
: configuration globale. on peut remplacer--global
par--local
pour voir la configuration locale
Liste non exhaustive des valeurs à configurer:
user.name
: nom utilisateuruser.email
: mail utilisateurcore.editor
: éditeur utilisé pour les commitmerge.tool
: outil pour mergecommit.template
: template pour les commits- …
man git-config
2.2. TODO Connexion avec clé SSH
Il faut en premier générer une clé ssh publique avec `ssh-keygen` puis mettre son contenu sur son profile git. Il faut laisser le nom par défaut sinon il faut préciser la clé dans les paramètres du git clone.
2.3. Création de dépôts
Pour créer un dépôt simple, il suffit de faire git init nom_dossier
ou git init
dans le dossier.
Pour faire un dépôt type serveur, il faut faire git init --shared
--bare nom_dossier
.
2.3.1. Enlever des fichiers ou des dossiers
Pour éviter que git ne synchronise tous les fichiers qui lui passe
sous la main, on peut faire un fichier .gitignore
à la racine du
dossier, qui contient les noms de fichiers à exclure
doc/* *.class
2.3.2. Ajouter une origine au dépôt
Si le dépôt en ligne est vide, il faut le link sur le dépôt
local. git remote add nom https://
permet de le faire. En règle
générale, le nom sera origin
. Il est possible d’avoir des
informations avec git remote -v
ou git remote show nom
.
Lors du premier push, il faut lier la branche locale avec le dépôt
distant et sa branche. Cela se fait avec git push -u origin master
.
Pour pousser des tags sur la branche distante, on peut utiliser 2 commandes :
git push nom tag
: pousse juste le tag sur le remote donnégit push --tags
: pousse tous les tags
2.4. Commandes
2.4.1. Usage classique
Git ne prend en compte que les fichiers, pas les dossiers vides.
Pour ajouter un fichier au git, il suffit de faire git add
fichier
. On peut en ajouter plusieurs d’un coup. Pour savoir quels
fichiers n’ont pas été ajouté au git, il faut faire git status
. Un
fois le fichier ajouté, on va faire un commit afin de connaître les
modifications apporté avec git commit
, il est possible d’ajouté
directement le titre du commit : git commit -m "titre commit"
. On
met ensuite en ligne avec git push
. Pour mettre à jour un dossier
git, on tape git pull
.
- MAJ du dépôt local
git fetch remote
: va mettre à jour le dépôt local avec les informations du dépôt distant (le nom du remote est obligatoire pour le premier fetch). Il faut cependant se déplacer ensuite manuellement pour aller sur le dernier commit.git pull
: met à jour et se déplace sur le dernier commit.
- Commits
- `git revert sha1` : fait un commit contenant l’inverse du sha1
- `git add file && git commit –amend` : ajoute un fichier au dernier commit
- `git commit –amend` : modifie le message du commit précédent
- Voir les modifications
git log
- affiche l’historique du dépôt
--graph
- affiche sous forme de graphe
-p N
- affiche les N derniers commits
git show sha1
- affiche les informations du commit et ses modifications
- Informations sur les fichiers
Pour pouvoir voir plus en détail un fichier et ses modifications, il est possible de faire un
git blame fichier
. La première colonne indique le commit modifiant le fichier (^
= commit ayant créer le fichier), la deuxième l’autheur, puis la date de création et pour finir la ligne du fichier. Avec-L
on peut préciser les lignes à montrer :-L 10,20
- les lignes 10 et 20
-L 10,+
- tout à partir de la ligne 10
-L 10,+4
- 4 lignes après la ligne 10
- Mettre de côté les modifications
Pour mettre de côté des modifications, il est possible d’utiliser la commande
git stash save "message"
afin de les sauvegarder pour plus tard. Pas besoin de faire des commits pour mettre les fichiers de côtés. Ces modifications seront sauvegardés avec un index. Pour les restaurer dans l’espace de travail, il faut fairegit stash pop index
. Pour récupérer la liste des index, il faut fairegit stash list
. Pour voir les informations du stash :git stash show index
.git stash save
=git stash
.git stash pop
= pop le dernier stash.Exemple d’utilisation en cas de conflit:
git pull # erreur ! git stash git pull git stash pop # régler les derniers conflits
- Rebase
Change le parent d’un commit.
Se fait automatiquement avec
git pull --rebase
.- L’utiliser de manière interactive
git rebase -i sha1 # modifier le fichier selon ses gouts # le fichier est trié par ordre chronologique (+ancient au +récent) # ce fichier est un script qui sera exécuté. Pour modifier un commit, # il faut remplacer le pick par r par ex (+d’infos dans le fichier).
Option Description p
Ne rien faire r
Réécrire le commit drop
Supprime le commit, possible de supprimer la ligne au lieu de mettre d. Possibilité de conflit à gérer squash
Fusionne le commit avec son commit parent edit
Laisse la main pour faire ce qu’on souhaite (ajout de fichiers…) Pour découper un commit, on utilise
edit
sur le commit et il suffit de rajouter les fichiers avecadd
et les commit avant de continuer le rebase.Pour changer l’ordre des commits, il faut changer la ligne où ils se trouvent.
pick commitA -> pick commitA pick commitB -> pick commitC pick commitC -> pick commitB pick commitD -> pick commitD
- L’utiliser de manière interactive
- Se déplacer de commit en commit
git checkout sha1
: déplace HEAD sur le sha1git checkout HEAD~2
: déplace HEAD 2 commit en arrière.
HEAD^
= parent du commit actuel - Déplacer la tête de la branche
git reset sha1
: déplace la branche sur le commit (marche aussi avecHEAD~X
)On peut annuler un reset avec
ORIG-HEAD
comme commit. - Historique position
git reflog
: affiche l’historique des différentes positions de HEAD. Il est possible de rajouter-N
qui affichera les N dernières positions (git reflog -4
par ex).Il est aussi possible de rajouter
--reflog
à la commandegit log
.
2.4.2. Commandes pour les branches
Les branches permettent de développer des fonctionnalités de l’application en parallèle de la branche principale et de les fusionner plus tard si la fonctionnalité est concluante.
Pour créer une branche, on tape git branch nom
puis git checkout
nom
pour basculer dessus. Pour fusionner une branche annexe avec la
principale, on bascule sur la principale (git checkout master
) et on
tape git merge nom
.
git branch -a
: montre toutes les branches, y compris les branches
distantes
- Copier un commit dans une branche
git cherry-pick sha1
: duplique le commit passé en pramètre - Rebase d’une branche
Aligne tous les commits de la branche dans l’autre branche (master ici).
# depuis la branche à rebase git rebase master # régler les conflits et si conflits: # git add files # git rebase --continue git checkout master git merge branche
- Suppression
En local:
git branch -d nom
. Il faut ensuite pousser cette suppression avecgit push origin --delete nom
.
2.5. Submodules
Fichier se trouvant dans le dépôt nommé .gitmodules
contient toutes
les informations sur les modules (chemin, version…).
2.5.1. Commandes
git submodule add url chemin
: ajoute le submodule se trouvant dans l’url dans le chemin du dépôt donnépour cloner un repo avec submodules :
git clone git submodule init git submodule update # ou git clone --recurse-submodules
pour pull un repo avec submodules :
git pull git submodule update --remote # --merge ou --rebase pour finir la commande (pas obligatoire)
git push --recurse-submodules=check
: vérifie si les modifications apportées sur le sous module ont bien été push sur son dépôt avant de push le dépôt prinicpal.
On peut aller dans le dossier du sous module et faire un git
checkout
pour changer la version utilisée par le dépôt principal.
git submodule foreach commande
: applique la commande à tous les sous modules
2.6. Annexe
2.6.1. Hooks
Scripts exécutés lors de certaines actions. Ils se trouvent dans
.git/hooks
. Ils doivent avoir le même nom que l’action (pre-commit,
commit-msg…) et être exécutable. Ils ne sont pas dupliqués avec un
clone
. Des exemples sont trouvables avec l’extension .sample
.
On peut lier un dossier externe contenant les hooks à notre projet :
core.hooksPath path
dans la configuration pour mettre le chemin vers le dossier hooks se trouvant dans un autre dépôt git par ex.- Lors du clone / init, ajouter l’option
--template=dir
où le répertoire contient un dossierhooks
.
- Local
Si la valeur de retour n’est pas 0, on arrête tout.
Liste non exhaustive des hooks existant pour un dépôt local:
- pre-commit : juste après
git commit
. Pas d’arguments - prepare-commit-msg : juste après pre-commit, 3 arguments : nom fichier tmp contenant le message, type de commit (-m, -t, merge ou squash), sha1 (pour -c -C ou –amend)
- commit-msg : juste après l’entré du message du commit, 1 argument : nom fichier tmp contenant le message
- post-commit : juste après la création du commit (aucune anulation possible si retourne !0). Pas d’arguments
- post-checkout : juste après commande checkout. 3 arguments : ref HEAD pred, ref nouv HEAD, checkout de branche (1) ou fichier (0). Aucun changement si ret !0
- pre-rebase : juste après commande rebase mais avant la rebase. 2 arguments: branch upstream, branche rebasée (vide si la branche est la même)
On peut les ignorer en ajoutant
-n
à la commande commit. - pre-commit : juste après
- Serveur
Les scripts ont la même règle que les hooks locaux.
Liste non exhaustive des hooks existant pour un dépôt distant:
- pre-receive : en recevant un push et avant d’intégrer le code reçu. Pas d’argument
- update : après le pre-receive. 3 arguments : nom branche maj, sha1 du commit actuel de la branche, sha1 du nouveau commit de la branche
- post-receive : après push réussi. Pas d’arguments et n’arrête rien. Permet de faire des notifications pour le CI/CD par ex.
2.6.2. Voir les références
cat .git/HEAD
: fichier contenant la référence actuelle de HEADgit cat-file -p HEAD
: affiche plus d’infos sur la référence HEADORIG-HEAD
: commit où se trouvait avant HEAD (créé uniquement avec certaines commandes)git diff --cached --submodule
: les chemins vers les sous modules et leur url
2.6.3. Faire une recherche dichotomique pour trouver un bug
Si on sait qu’entre le commit X et Y, il y a un bug et qu’il y a plusieurs commits entre les deux, on peut appliquer la dichotomie pour trouver le bug en question (en prenant le commit à la moitié, en vérifiant s’il contient le bug, etc.).
On peut utiliser git bisect
pour ça.
git bisect start git bisect good sha1 # le commit sans le bug git bisect bad sha1 # le commit avec le bug # good et bad sans sha1 = HEAD. # un git checkout est fait automatiquement en se mettant au milieu # si le bug est toujours présent, on refait git bisect bad # ou git bisect good s’il n’y est plus # lorsque le bug est trouvé de manière sur, il affiche des infos sur le commit git bisect reset # sort du mode bisect et retourne sur le commit précédent cette commande
Pour automatiser la recherche, il est possible de lui passer un script qui sera exécuté à chaque checkout:
git bisect start git bisect good sha1 # le commit sans le bug git bisect bad sha1 # le commit avec le bug git bisect run script # le script retourne 0 = good, autre = bad # attendre git bisect reset
2.6.4. Autres
git commit --amend
: modifie le dernier commit, supprime le tag sur ce commit (toujours possible d’aller dessus mais pas afficher dans log).git log nom
: commits de la branche passée en paramètresgit merge --abort
: annule un merge en cours.
Tableau des commandes :
Commande | Description |
---|---|
clone |
Obtenir une copie d’un dépôt existant |
add |
Place un contenu sous le système de suivi de versions. Indexer un fichier |
init |
Initialise un nouveau dépôt |
rm |
Supprime un contenu |
commit |
Valide les modifications |
push |
Propage les modifications sur un dépôt distant |
pull |
Récupère les objets du dépôt distant et tente de faire un merge avec les objets locaux (git pull =git fetch + git merge) |
diff |
Calcule la différence entre deux versions |
log |
Affiche les journaux des modifications |
fetch |
Met à jour les objets locaux avec ceux d’un dépôt distant (pas de merge) |
branch |
Liste, créé ou supprime une branche |
config |
Configure Git |
status |
Affiche l’état des fichiers locaux |