Git
Pense-bête
Faire un diff entre la version actuelle et la précédente
git diff HEAD^ HEAD
Afficher la version d'un fichier à une révision spécifique
git show 0ac056dcc7895d222eccb6ab40e9b2f911ba2634:mon_fichier.c
Effacer tous les changements effectués sur une copie locale
git checkout -f # pour effacer tout changement fait sur l'intégralité des fichiers
git checkout -f fichier.txt # pour effacer les changements faits sur le fichier "fichier.txt"
Récupérer des fichiers contenus dans une autre branche
git checkout mon_autre_branche mon/fichier.txt
Annuler le dernier commit
git reset --soft 'HEAD^'
À ne faire que si le commit n'a pas été poussé sur un dépôt distant.
Modifier le message du dernier commit
git commit --amend
Attention, ceci ne fonctionne que pour le dernier commit (HEAD
), et si le commit n'a pas été poussé sur un dépôt distant.
Créer une branche indépendante
Il est possible de créer dans un dépôt une nouvelle branche qui ne soit pas corrélée à une autre branche – elle est considérée “orpheline” :
git checkout --orphan <nom de la nouvelle branche>
Supprimer une branche distante
git push origin --delete <nom de la branche>
Supprimer en local les branches distantes qui n'existent plus par rapport à l'origine distante
Le titre est un peu confus, mais visualisez la situation suivante : vous synchronisez votre dépôt local par rapport un dépôt distant (“origin”), et récupérez donc ses branches. Au bout d'un certain temps, quelqu'un supprime une ou plusieurs branches sur cette origine, mais les branches que vous avez récupéré auparavant figurent toujours dans la liste des branches de votre dépôt local.
Dans notre exemple, nous commençons avec plusieurs branches “historiques” obtenues par notre référent distant “origin” :
[email protected]:~/mon_projet% git branch --all
0.1
feature4
* master
remotes/origin/0.1
remotes/origin/HEAD -> origin/master
remotes/origin/feature1
remotes/origin/feature2
remotes/origin/feature3
remotes/origin/feature4
remotes/origin/master
[email protected]:~/mon_projet% git branch --remote
origin/0.1
origin/HEAD -> origin/master
origin/feature1
origin/feature2
origin/feature3
origin/feature4
origin/master
Nous synchronisons notre dépôt local par rapport à l'origine (ici github.com:moi/mon_projet) :
[email protected]:~/mon_projet% git fetch --prune
From github.com:moi/mon_projet
x [deleted] (none) -> origin/feature1
x [deleted] (none) -> origin/feature2
x [deleted] (none) -> origin/feature3
[email protected]:~/mon_projet% git branch --remote
origin/0.1
origin/HEAD -> origin/master
origin/feature4
origin/master
Notre dépôt local est désormais synchronisé avec les branches présentes sur l'origine, les branches obsolètes feature1
, feature2
et feature3
ont été supprimées :
[email protected]:~/mon_projet% git branch --all
0.1
feature4
* master
remotes/origin/0.1
remotes/origin/HEAD -> origin/master
remotes/origin/feature4
remotes/origin/master
Supprimer un tag distant
git tag -d v42
git push origin :refs/tags/v42
Astuces
Exclure définitivement certains fichiers du versionnage
Si vous ne voulez pas que Git prenne en compte les fichiers temporaires (ex : fichiers temporaires .xxxxx.swp
générés par Vim) ou encore les fichiers non pertinents (ex : fichiers de cache .pyc
de Python), ajoutez les patterns correspondant dans le fichier .gitignore
à la racine de votre copie de travail :
*.pyc
*.swp
Commandes Git raccourcies grâce aux aliases
Les mots-clés raccourcis (co
, ci
, up
…) de Subversion vous manquent ? Pas de panique, il est possible d'utiliser les commandes de Git avec des alias raccourcis. Dans votre fichier ~/.gitconfig
, ajoutez les lignes suivantes :
[alias]
ci = commit
co = checkout
st = status
…et ainsi de suite, selon vos envies.
Colorier l'affichage des messages de Git
Pour mettre un peu de couleurs dans l'affichage de Git selon la nature des messages affichés, ajoutez la configuration suivante à votre fichier ~/.gitconfig
:
[color]
ui = auto
[color "branch"]
current = yellow bold
[color "diff"]
frag = magenta bold
meta = yellow bold
new = blue bold
old = red bold
[color "status"]
added = green bold
changed = red bold
Vous trouverez la liste exhaustive des mots-clés dans le man git-config(1)
.
Utiliser un dépôt distant “d'échange”
Si vous avez besoin d'un dépôt central Git servant uniquement de transition entre 2 ou plusieurs autres dépôts distants, voici la procédure à suivre. Pour l'exemple, nous appellerons “X” le dépôt faisant la transition entre 2 autres dépôts “A” et “B”.
Depuis le dépôt X (situé sur le serveur un.serveur.distant.com) :
# Créé le dépôt minimal dans "chemin/vers/depot"
git init --bare chemin/vers/depot
Depuis le dépôt A :
cd depot
# Ajoute une nouvelle origine distante "<un.serveur.distant.com>:chemin/vers/depot"
git remote add origin <un.serveur.distant.com>:chemin/vers/depot
# Pousse la branche master du dépôt local vers l'origine précédemment définie
git push origin master
Pour éviter d'avoir à spécifier “origin” à chaque fois que vous voulez mettre à jour le dépôt A, ajoutez les lignes suivantes dans le fichier depot/.git/config
:
[branch "master"]
remote = origin
merge = refs/heads/master
Depuis le dépôt B :
# Clone le dépôt distant
git clone <un.serveur.distant.com>:chemin/vers/depot
Transformer un dépôt “normal” en dépôt “bare”
Git gère 2 types de dépôts : les dépots “normaux” — qui sont des copies de travail locales, contenant les fichiers versionnés — et les dépôts dits “bare” qui ne servent qu'à recevoir les commits sans permettre de manipuler directement les fichiers qui y sont versionnés. Pour “transformer” un dépot normal en un dépot “bare”, deux méthodes possibles :
a) cloner le dépôt existant :
git clone -l --bare blah blah.git # "blah.git" est la version "bare" du dépôt normal "blah"
b) manuellement :
cd blah
mv .git .. && rm -fr *
mv ../.git .
mv .git/* .
rmdir .git
git config --bool core.bare true
cd .. && mv blah blah.git # facultatif, "<nom du dépôt>.git" est juste une convention
Afficher uniquement la branche courante
Si vous avez besoin de récupérer le nom de la branche actuellement utilisée sans Patrick fioritures — par exemple pour utilisation dans un script —, voici une commande pratique :
git rev-parse --abbrev-ref HEAD
Alterner rapidement entre deux branches
Si vous alternez souvent entre deux branches lors de votre développement, il existe un raccourci pratique pour accéder à la branche utilisée précédemment en spécifiant le caractère -
(tiret) au lieu du nom de la branche :
git checkout dev # passe sur la branche "dev"
git checkout master # passe sur la branche "master"
git checkout - # retourne sur la branche "dev"
Mettre à jour simultanément un dépôt local et ses submodules
Si vous utilisez des submodules dans un dépôt, vous avez probablement remarqué qu'il est pénible de devoir les mettre à jour par rapport à leur origine (git pull
) indépendemment du dépôt “hôte”. À l'aide de l'alias suivant (git pullall
), il est possible de synchroniser un dépôt et ses submodules en une commande :
git config --global alias.pullall '!git pull --all && git submodule foreach git pull --all'