Feuille de route Git
Lundi 7 Novembre 2016 à 22:01

J’ai eu besoin de produire une feuille de route sur Git, couvrant les principaux cas d’usage. La version pdf de la suite de cet article est disponible ici.

Configuration et recherche d’informations

git config

Gère la configuration des options du système et des répertoires. Le couteau suisse.

 # Choisit le fichier de configuration à utiliser
 # local : .git/config
 # global : ~/.gitconfig
 # system : /etc/gitconfig
 # file : fichier à fournir
 git config --[local|global|system|file <file>]
 # Définir son identité
 git config --global user.name "Linus Torvalds"
 git config --global user.email "linux@torvalds.com"
 # Récupère la valeur d'une clé
 git config user.name
 # Enlever une clé
 git config --unset user.name
 # Changement d'éditeur de texte par défaut pour les messages de commit
 git config --global core.editor vim
 git config --global core.editor nano
 git config --global core.editor "'C:/Program Files/Notepad++/notepad++.exe' -multiInst -nosession"
 # Définir des alias/sous-commandes
 git config --global alias.co checkout
 git co # Exécute `git checkout`
 git config --global alias.br branch

 # Quelques alias un peu plus utiles
 # Voir le dernier commit
 git config --global alias.last 'log -1 HEAD'

 # Voir un joli graphe de commits
 git config --global alias.loggy "log --graph --pretty=format:'\%Cred\%h\%Creset -\%C(yellow)\%d\%Creset \%s \%Cgreen(\%cr) \%C(bold blue)<\%an>\%Creset' --abbrev-commit --all"

 # Enlève un fichier de la zone de staging (ne modifie pas le fichier)
 git config --global alias.unstage 'reset HEAD --'

 # Annule le dernier commit (seulement en local !)
 git config --global alias.undo 'reset --soft HEAD^'

 # Reformule le dernier commit
 git config --global alias.amend 'commit --amend'
 # Activer le cache des identifiants HTTP et les garder 1h.
 git config --global credential.helper 'store --file ~/.credentials --timeout 3600'

git diff

Affiche les changements entre deux index.

 # Affiche les différences fichier par fichier entre les fichiers modifiés et ceux de la zone de staging.
 git diff
 # Affiche les différences entre la zone de staging et le dernier commit
 git diff --staged
 # Afficher uniquement les noms des fichiers modifiés (pratique pour les gros commits)
 git diff --name-only
 # Affiche le diff d'un fichier spécifique
 git diff <file>
 # Différences entre deux branches (pas forcément locale)
 git diff master feature\_branch
 git diff master origin/master

 # Différences entre deux commit
 git diff fe2b292 8257efb
 git diff fe2b292 8257efb <file>

git status

Récupère des informations sur l’état du répertoire.

 # Affiche tous les fichiers modifiés et les fichiers suivis du répertoire
 git status
 # Même affichage, mais simplifié
 git status --short
 # Affiche aussi les fichiers ignorés
 git status --ignored

Jouer avec les branches

git branch

Manipule les différentes branches

 # Affiche les branches connues, ainsi que la branche active
 git branch --list
 git branch # Équivalent
 # Affiche le dernier commit sur chaque branche
 git branch -v
 # Affiche les branches déjà fusionnées avec la branche courante
 git branch --merged
 # Créé une nouvelle branche nommée 'feature'
 git branch feature
 # Supprime une branche qui a déjà été fusionnée
 git branch -d merged

 # Force la suppression d'une branche, même non fusionnée (ATTENTION: le travail est définitivement perdu)
 git branch -D notmerged
 # Renomme une branche
 git branch -m feature_1 # Renomme la branche courante en 'feature\_1'
 git branch -m feture feature # Renomme la branche 'feture' en 'feature'
 # Change la branche amont(upstream) de la branche courante
 git branch -u origin/master

git checkout

Déplacement entre les branches.

 # Bouge le pointeur de tête sur une autre branche. Si la branche n'existe pas, git essaye de récupérer origin/<nom de la branche> et de la créer localement.
 git checkout master

 # On peut aussi aller voir l'état du répertoire à un commit ou un tag donné
 git checkout v1.4
 git checkout f29d518
 # Créé une nouvelle branche et se déplace dessus
 git checkout -b new_branch

 # Se déplace sur la nouvelle branche ft, configurée pour suivre origin/feature
 git checkout -b ft origin/feature
 # Après modification d'un fichier, il est possible de le réinitialiser à son état initial (tel qu'il est dans la zone de staging, ou tel qu'il est sur le pointeur de tête)
 git checkout README
 git checkout -- README # Si il y a une branche nommée 'README'

git fetch

Télécharge le contenu depuis un répertoire distant (ne l’intègre pas à l’espace de travail).

 # Récupère le contenu du répertoire distant donné (par défaut origin)
 git fetch
 git fetch origin

Travailler et le partager

git add

Permet d’ajouter des fichiers à suivre et de les inclure dans la zone de staging.

 # - Ajoute un fichier
 # - Suite à un conflit de fusion, git add permet de marquer le conflit comme résolu pour ce fichier
 git add __init__.py

 # Ajoute tous les fichiers qui finissent en .go
 git add *\.go
 # Ajoute tous les fichiers (supprimés, modifiés, non suivis)
 git add -A
 # Force l'ajout d'un fichier, quand il a été ignoré par exemple
 git add -f <file>

La commande add fonctionne en prenant une image d’un fichier pour l’ajouter à la zone de staging. Si une modification ultérieure a lieu, il faut ré-ajouter le fichier, sans quoi les dernières modifications ne seront pas prises en compte.

 # Permet de choisir quelles modifications seront ajoutées. Cette commande est particulièrement pratique lorsque beaucoup de modifications ont été faites sur le même fichier: il est toujours possible de les séparer.
 git add -e <file>
 # Effectue l'ajout en mode interactif pour choisir les fichiers à ajouter ou non
 # Se référer au manuel pour l'usage complet
 git add -i <file>

git commit

Un petit peu le cœur de git, le commit prend le contenu de la zone de staging et génère une nouvelle entrée dans l’historique -> le commit. Il met aussi à jour le pointeur HEAD.

 # Commit basique, ouvre l'éditeur configuré pour entrer le message du commit
 git commit
 # Commit avec le message donné
 git commit -m "message here"
 # Commit tous les fichiers déjà suivis et modifiés sans se préocupper de la zone de staging.
 git commit -a
 # Ajoute le contenu de la zone de staging au dernier commit et permet de le reformuler
 git commit --amend
 # Signer cryptographiquement le commit
 git commit -S

git merge

Fusionne deux branches ensemble

 # Fusionne la branche feature avec la branche courante
 git merge feature
 # Réalise une fusion sans avance rapide -> créé un commit de fusion même si il pouvait être évité
 git merge --no-ff feature
 # Si la fusion se passe mal, permet de l'annuler
 git merge --abort

git pull

Récupère le travail amont et tente de l’intégrer au répertoire courant.

 # - Si la branche amont est en avance sur la votre, pas de problème.
 # - Si la branche amont et la votre ont divergé, le pull va échouer.
 git pull
 # En vrai, c'est équivalent à ce qui va suivre:
 git fetch
 git merge

 # Tente de récupérer le travail amont et de rejouer vos commits par dessus
 git pull --rebase
 # En vrai, c'est équivalent à ce qui va suivre
 git fetch
 git rebase

Bref git pull est bien utile lorsque l’historique est assez simple, que les conflits sont raisonnables.

git push

Met à jour les répertoires distants.

 # Comportement par défaut, push les commits en avance sur la branche amont. Dans la configuration par défaut, il s'agit de origin/<branche courante>
 git push

 # Push sur le répertoire et la branche spécifiée
 git push origin master
 git push <repertoire> <branche>
 # Lorsque la branche amont et la votre ont divergé, réécrit l'historique des commits distants avec le votre (ATTENTION: Ceci est un des seul moyens de perdre effectivement des modifications avec git. En cas de doute, ne pas utiliser)
 git push --force

 # Après avoir supprimé une branche localement, supprime la branche sur le répertoire distant
 git push origin --delete deleted

 # Après avoir créé un ou plusieurs tags, les push sur la branche amont.
 git push --tags.

git rebase

Le rebasage rejoue un ensemble de commits à partir d’un autre point de départ. Se référer à la documentation pour des exemples complets.

 # Rejoue les commits de la branche courante sur la branche master
 git rebase master

 # Rejoue les commits de la branche feature sur la branche master
 git rebase master feature
 # Rejoue les commits de la branche client depuis l'ancêtre commun avec la branche server sur master. Cf schéma.
 git rebase --onto master server client
 Exemple 1:

 C1 -- C2 -- C3 <- master
  \
   C4 -- C5 -- C6 <- server
    \
     C7 -- C8 <- client

 git rebase --onto master server client

           master
             |
             v
 C1 -- C2 -- C3 -- C7' -- C8' <- client
  \
   C4 -- C5 -- C6 <- server


 Exemple 2:

 C1 -- C2 -- C3 <- master
               \
                C4 -- C5 -- C6 <- server
                              \
                              C7 -- C8 <- client

 git rebase --onto master server client

 C1 -- C2 -- C3 <- master
             | \
             |  C4 -- C5 -- C6 <- server
              \
              C7' -- C8' <- client
 # Lorsqu'il y a un conflit de rebasage, possibilité de continuer, aborter ou sauter la patch
 git rebase --continue
 git rebase --abort
 git rebase --skip
 # Démarre le mode interactif. Permet de réecrire l'historique des commits pour le rendre plus propre (Ne change pas les fichiers).
 git rebase -i HEAD~3 # Réécrit les trois derniers commits (HEAD, HEAD-1, HEAD-2)
 git rebase -i master # Réécrit les commits jusqu'à l'ancêtre commun entre la branche courante et master.

Note: Un rebasage réécrit l’historique, alors qu’un merge ajoute un commit à l’historique. De manière générale, il faut éviter de rebaser des branches déjà publiques (d’autant que cela implique un force push).

git tag

Un tag est une référence vers un commit. Il est plus simple de se souvenir d’un tag que d’un hash de commit.

 # Créé un nouveau tag sur le commit pointé par la tête
 git tag v1.0

 #Créé un nouveau tag sur un commit spécifique
 git tag v1.0 7872c2e

 # Liste tous les tags
 git tag
 git tag -l
 # Créé un tag annoté. Le tag contiendra le nom de l'auteur, son adresse mail et un message
 git tag -a v1.0

 # Créé un tag annoté avec le message 'message'
 git tag -a v1.0 -m 'message'

 # Signe cryptographiquement un tag annoté
 git tag -a -s v1.0

Back to posts