Ceci est une ancienne révision du document !
Git
Fonctionnement interne de Git:
Ouvrir tous les fichiers modifiés
https://stackoverflow.com/questions/28280635/how-to-open-all-modified-files-with-git
vim $(git status --porcelain | awk '{print $2}')
Add
N'ajouter que quelques lignes d'un nouveau fichier
git add -N new git add -p new
Diff
Lister les fichiers changés depuis un commit
git diff --name-only 60b504d066 HEAD
Il est possible de préciser un fichier pour voir la différence entre la version actuelle et le commit spécifié.
Comparer un fichier entre deux branches
git diff ..branch fichier_a_comparer
Utiliser un outil externe pour visualiser un diff de branches
https://stackoverflow.com/questions/2006032/view-differences-of-branches-with-meld
git config --global diff.tool meld git difftool master..devel # ouvre meld pour chaque fichier différent git -d difftool master..devel # ouvre meld avec toute l'arborescence
Pour persister les changements apportés pendant le diff, copier le dépôt et se placer sur l'autre branche, puis utiliser meld en comparant deux dossiers (si on passe directement par Git, les dossiers sont copiés dans un dossier temporaire, et les changements ne sont donc pas sauvegardés).
Merge
On se place sur la branche dans laquelle on veut merger.
git merge <branche à merger>
Supprimer un fichier du suivi de Git
Pour Git le fichier est supprimé, mais il reste sur le disque dur:
git rm --cached <file>
Sous-modules
Installer un sous-module
git submodule add git://github.com/chneukirchen/rack.git rack
Ajoute le sous-module dans le dossier rack.
Installer les sous-modules d'un dépôt
git submodule init git submodule update
Git avec SSH
Préciser la clé SSH à utiliser
ssh-agent bash -c 'ssh-add /somewhere/yourkey; git clone git@github.com:user/project.git'
Passer des arguments à SSH
GIT_SSH_COMMAND="ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no" git clone user@host
Ne semble fonctionner que depuis Git 2.3.
Sauvegarder des dépôts Git
Première sauvegarde:
git clone --mirror "$url" "$project"
Mettre à jour la sauvegarde:
git fetch --prune
L'option –prune permet de supprimer localement ce qui ne se trouve plus sur le dépôt distant.
Commits
Changer l'auteur des commits
Le dernier commit (source):
git commit --amend --author "New Author Name <New Author Email>"
Certains anciens commits (source):
git rebase -i -p <sha commit avant le premier concerné> # passer les commits dont il faut changer l'auteur à "edit" git commit --amend --author "New Author Name <New Author Email>" git rebase --continue # ...
Changer la date du dernier commit
git commit --amend --date="$(date)" --no-edit
Ajouter un fichier à un ancien commit
git add <my fixed files> git commit --fixup=OLDCOMMIT git rebase --interactive --autosquash OLDCOMMIT^
OLDCOMMIT est le commit à modifier.
Afficher les infos d'un commit sans le diff
https://stackoverflow.com/questions/1828252/how-to-display-metadata-about-single-commit-in-git
git show --quiet
Scinder un (ancien) commit en plusieurs commits
git rebase -i ${commit_avant} # edit le commit à scinder git reset HEAD~ # faire tous les commits souhaités (git add / git commit) git rebase --continue
Faire un rebase avec le premier commit
git rebase -i --root
Shallow clone
git clone --depth 1 ...
Passer ensuite sur une autre branche distante (source) :
git remote set-branches origin '*' git fetch --depth=1 git checkout $branch
Travailler avec des forks
git remote add upstream https://github.com/octocat/Spoon-Knife.git git remote -v
Synchroniser son dépôt:
git fetch upstream git merge upstream/dev git push
Pour que Git oublie les branches distantes qui ont été supprimées sur les dépôts distants (source):
git remote prune fork # ou git fetch --prune
Stashs
Stasher seulement certains fichiers modifiés
git stash -p
Valider les hunks des fichiers à stasher.
Ne fonctionne pas pour seulement quelques hunks à l'intérieur d'un fichier, car l'application du stash ne fonctionne plus après.
Afficher la date des stashs
git stash list --date=local
Afficher les modifications dans un stash
git stash show <stash> git stash show -p <stash> # produit une sortie comme diff
Branches
Supprimer une branche
Localement:
git branch -d nom_de_branche git branch -D nom_de_branche # si branche non mergée
Sur un serveur:
git push [remote] --delete [branche] # donc: git push origin --delete nom_de_branche # ou: git push [remote] :[branche]
Obtenir le nom de la branche courante
git rev-parse --abbrev-ref HEAD
Obtenir toutes les branches d'un serveur
git branch -a # toutes les branches de tous les serveurs git branch -r # uniquement les branches distantes
Renommer une branche
https://multiplestates.wordpress.com/2015/02/05/rename-a-local-and-remote-branch-in-git/
git branch -m new-name # on est déjà sur la branche git branch -m old-name new-name # on est sur une autre branche
Pour une branche distante:
git push origin :old-name new-name # supprime l'ancienne branche distante et crée la nouvelle branche sur le serveur git push origin -u new-name # pousse le contenu vers la nouvelle branche
Tags
Créer un tag :
git tag <nom_du_tag> # par défaut sur le dernier commit git tag -a v1.2 9fceb02 # sur un commit précédent
Pusher les tags :
git push origin --tags
Pour pusher un tag spécifique :
git push origin nom_du_tag
Supprimer un tag :
git tag -d nom_du_tag git push origin --delete nom_du_tag
Patchs
Toujours en se plaçant dans le dossier racine (à défaut, le paramètre -p <n> peut aider).
git diff > hotfix.patch git apply hotfix.patch
Si le patch est rejeté, possibilité de l'appliquer partiellement et stocker les hunks inapplicables dans les fichiers correspondants en ajoutant l'extension .rej:
git apply --reject --whitespace=fix mypath.patch
Pour générer le patch d'une branche:
git checkout feature git format-patch master git am *.patch
Il est possible d'éditer les patchs avec editdiff ou rediff, fournis par le paquet patchutils.
Annuler les modifications d'une partie d'un fichier
git checkout -p <fichier>
Préciser l'emplacement du dossier Git
Pour lancer des commandes sans être dans le dossier: ajouter l'option --git-dir=chemin/vers/dossier/.git, ou juste l'option -C chemin/vers/le/dossier.
Pour cloner un dépôt, tout en plaçant le dossier .git ailleurs (source):
git clone --separate-git-dir=../../dev/pm2.git git@gitlab.inria.fr:pm2/pm2.git pm2
Obtenir le dossier racine du dépôt
git rev-parse --show-toplevel
Il est donc possible de faire un alias dans son bashrc:
alias gro='cd $(git rev-parse --show-toplevel)'
Obtenir le commit actuel
git rev-parse HEAD git rev-parse --short HEAD
Obtenir la date du dernier commit
Historique d'un fichier
git log [filename] # Affiche les commits impactant le fichier git log -p [filename] # Affiche les diffs du fichier de tous les commits impactant le fichier gitk [filename] # Interface graphique
L'option --follow permet de suivre le fichier si celui-ci a été renommé.
Pour avoir l'historique d'un fichier supprimé, il faut séparer les options de git log et le chemin du fichier avec --.
Supprimer tous les fichiers non suivis
Utiliser la commande git clean.
Options:
-n: dry-run-f: supprime vraiment-d: supprime aussi les dossiers-X: supprime les fichiers ignorés-x: supprime les fichiers ignorés et non ignorés
Chercher dans tout l'historique
Un fichier
git log --all --full-history -- "**/thefile.*"
Grep
git grep foo $(git rev-list --all)
Une solution plus performante est :
git log -Sfoo
Afficher un fichier tel qu'il était à un commit
git show HEAD:fichier
Pour récupérer un fichier tel qu'il est dans une branche (source) :
git checkout branche fichier git show branche:fichier > fichier git restore -s branche fichier
Récupérer un fichier supprimé dans un commit
git checkout <deleting_commit>^ -- <file_path>
Bisect
https://delicious-insights.com/fr/articles/git-bisect/
git bisect start # se placer sur un commit foireux git bisect bad # se placer sur un commit bon git bisect good # itérer git bisect bad/good selon si le commit est correct ou non # Git finit par indiquer le commit qui pose problème git bisect reset # revient au commit lors du start
Forcer un pull à réécrire l'historique local
Lorsque la branche distante a réécrit les commits déjà présents en local:
git fetch git reset --hard origin/master
Si Git râle que fatal: argument ambigu : révision inconnue ou chemin inexistant., la branche n'existe pas pour Git. On peut le vérifier avec git branch --all et mettre à jour si nécessaire .git/config.
Log
Options:
--no-merges: n'affiche pas les commits indiquant un merge--first-parent: n'affiche pas les commits provenant d'un merge--author=“Author”: n'affiche que les commits de Author
Voir l'historique d'une portion de fichier
Pour voir l'historique de la ligne 337 (Source):
git log -L 337,337:rr.tex
Lister tous les fichiers modifié par quelqu'un
En prenant en compte tous ses commits (source) :
git log --pretty= --committer=<username> --name-only | sort -u
Ignorer des fichiers
Ignorer une extension seulement à la racine du dépôt
Préfixer le pattern par un slash: /*.pdf. Les PDFs dans les sous-dossiers seront ainsi versionnés.
Avoir un gitignore global
Créer un fichier ~/.gitignore_global, puis :
git config --global core.excludesfile ~/.gitignore_global
Compter le nombre de commits
git rev-list --count HEAD # branche courante git rev-list --count <branch-name> # spécifie une branche git rev-list --count HEAD ^<branch-name> # depuis la création de la branche git rev-list --no-merges --count HEAD # ignore les commits de merge
Envoi de mails
Configuration
Autoriser Git à remonter les points de montages
Nécessaire lorsqu'un dépôt Git sur un montage réseau souhaite aller chercher des informations dans la configuration globale de l'ordinateur local:
- ~/.zshrc
export GIT_DISCOVERY_ACROSS_FILESYSTEM=1
Configurer l'éditeur de commits
git config --global core.editor "vim"
Alias
Coloration automatique
git config --global color.ui auto
Pas de pager pour lister les branches
git config --global pager.branch false
Lister tous les paramètres possibles
git help --config
Verbosité
time GIT_TRACE=true GIT_CURL_VERBOSE=true GIT_SSH_COMMAND="ssh -vvv" GIT_TRACE_PACK_ACCESS=true GIT_TRACE_PACKET=true GIT_TRACE_PACKFILE=true GIT_TRACE_PERFORMANCE=true GIT_TRACE_SETUP=true GIT_TRACE_SHALLOW=true git pull
Tester si on est dans un dépôt Git
if git rev-parse --git-dir > /dev/null 2>&1; then : # This is a valid git repository (but the current working # directory may not be the top level. # Check the output of the git rev-parse command if you care) else : # this is not a git repository fi