Table des matières

Git

Tuto :

.gitignore

Créer un fichier .gitignore pour ignorer certains fichiers, répertoires, extensions :

.gitignore
*
!*/
*.swp
*.swo
!.gitignore
!README.md
!/dir2/
/dir2/dir1/passwd
!/dir1/dir2/file2

Outils

ungit

gitkraken

Astuces

$ git ls-tree --full-tree -rl HEAD

$ git rev-parse --show-toplevel
/home/gigix/test-github/gigix

$ git rev-list --all --abbrev-commit | xargs git grep -n mon_fichier

$ git rev-list --abbrev-commit --all --max-count=10 | xargs git grep -n mon-fichier

$ git rev-list --all --abbrev-commit | xargs -I{} git grep dir1 {} -- ".xml"

$ git check-ignore -v dir11/file
.gitignore:1:* dir11/file

$ git rev-parse --abbrev-ref HEAD
master

$ git filter-branch --commit-filter '                                                                                      
         if [ "$GIT_AUTHOR_NAME" = "root" ];
         then
                 GIT_AUTHOR_NAME="Ghislain LE MEUR";
                 GIT_COMMITTER_NAME="Ghislain LE MEUR";
                 GIT_AUTHOR_EMAIL="gigi206@users.noreply.github.com";
                 GIT_COMMITTER_EMAIL="gigi206@users.noreply.github.com"; 
                 git commit-tree "$@";
         else
                 git commit-tree "$@";
         fi' -f HEADt commit-tree "$@";
         fi' HEAD

$ git filter-branch --force --index-filter 'git rm --cached --ignore-unmatch mydir/myfile' --prune-empty --tag-name-filter cat -- --all
$ git push origin --force --all
$ git push origin --force --tags
$ git for-each-ref --format='delete %(refname)' refs/original | git update-ref --stdin
$ git reflog expire --expire=now --all
$ git gc --prune=now

Configuration

$ git config --global --replace-all core.pager "less -F -X"

Subcommand

aide

Affiche l'aide :

$ git help <module>
$ git help config

config

Gère la configuration locale ou globale des projets git. Options :

$ git config --global user.name "GigiX"
$ git config --global user.email gigixdvelannes.com

$ git config -l --global 
$ git config -l --local

$ git config -e --global 
$ git config -e --local

$ git remote set-url origin https://github.com/gigi206/test.git

$ git config --get remote.origin.url

init

Initialise un nouveau projet git :

$ git init

$ git init --bare

remote

Gère les remotes.

$ git remote -v
origin	https://github.com/gigi206/test.git (fetch)
origin	https://github.com/gigi206/test.git (push)

$ git remote add origin /home/gigix/test-repo
$ git remote add upstream https://github.com/gigi206/vim-gigix.git

$ git remote remove origin /home/gigix/test-repo

$ git remote rename origin test

En principe on appelle origin le repo sur lequel on envoie les push et upstream le dépôt que l'on a forké pour par exemple envoyé un pull request.

clone

Clone un projet.

$ git clone https://github.com/gigi206/vim-gigix.git myclonerepo

$ git clone --depth 10 https://github.com/gigi206/vim-gigix.git

status

Afficher l'état de notre copie de travail :

$ git status
$ git status -s

add

$ git add mon_fichier

$ git add --all
$ git add -A

$ git add .

rm

$ git rm mon_fichier

$ git rm --cached monfichier

$ git rm -r mon_repertorie

mv

Renomme un fichier, dossier ou lien de l'espace de travail :

$ git mv file1 file2

commit

Gère les révisions localement uniquement.

$ git commit -a -m 'mon message'

$ git commit -m 'mon message' mon-fichier

$ git commit --author "GigiX" -m "message"

$ git add -A
$ git commit --amend –m "message"

push

Envoie les commit, branches, tags au remote

$ git push -u origin master

$ git push --all --tags

fetch

Met à jour le répertoire local depuis un remote :

$ git fetch origin master
$ git fetch --all

pull

$ git pull

$ git pull --rebase

Un pull équivaut à faire un fetch suivi d'un merge merge. Pour que git fasse toujours un rebase à la place d'un merge, il faut ajouter la configuration ci-dessous :
$ git config --global branch.autosetuprebase always

$ git pull --rebase=preserve

Pour que git fasse toujours un preserve, on peut ajouter à la configuration de git :
$ git config --global pull.rebase = preserve

$ git pull --no-ff

$ git pull --ff-only

cherry-pick

Récupère seulement un seul commit effectué sur une autre branche complètement séparée de la branche courante. Elle permet d’appliquer les modifications correspondant à un seul commit sans effectuer de merge ou rebase.

$ git checkout master
$ git cherry-pick <SHA-1>

Il n’est pas nécessaire d’effectuer un commit après cette étape, cherry-pick effectue lui-même un commit. Cette fonctionnalité est très pratique par exemple lorsqu'on a corrigé un bug sur la branche dev et qu'on veut pousser cette correction sur la branche master.

stash

Imaginons, vous avez des modifications en cours de création et vous avez envie de les mettre de côté temporairement, plutôt que de commit les différentes modifications vous pouvez les stocker grâce à stash.

$ git stash -u
$ git stash save -u mon message

$ git stash branch gigix

$ git stash apply
$ git stash apply stash@{1}

$ git stash drop
$ git stash drop stash@{1}

$ git stash drop
$ git stash drop stash@{1}

$ git stash pop
$ git stash pop stash@{1}

$ git stash list

log

Affiche les révisions, auteurs, date, diff des commit.

$ git log --oneline                                                                                                       
$ git log --raw --oneline -10
$ git log --stat
$ git log -p
$ git log --graph --decorate --oneline
$ git log --author="GigiX" -p hello.py
$ git log master..origin/master # Permet de voir les commits entre ma branche master et celle du remote
$ git log 852e094^..852e094 -p
$ git log 852e094..HEAD --oneline
$ git log 852e094..HEAD -L 2,6:mon_fichier
$ git log --grep=gigix
$ git log --since="1 month" --until="1 day" --oneline
$ git log --graph --abbrev-commit --decorate --date=relative --all
$ git log --graph --topo-order --decorate --oneline --all
$ git log --graph --topo-order --decorate --oneline --boundary test..master
$ git log --graph --full-history --all --color --pretty=format:"%x1b[31m%h%x09%x1b[32m%d%x1b[0m%x20%s"

$ git log --all --full-history -- test

$ git config --global alias.lg 'log --graph --full-history --color --oneline --format="%x1B[33m%h%x1B[32m%d %x1B[0m%s %x1B[36m(%an %cr)%x1B[0m"'
$ git config --global alias.lga 'log --graph --full-history --color --oneline --all --format="%x1B[33m%h%x1B[32m%d %x1B[0m%s %x1B[36m(%an %cr)%x1B[0m"'
$ git lg --all
$ git lga
$ git lg --first-parent mybranch
$ git lg --parents mybranch

reflog

Affiche les logs des rebase, merge, etc…

$ git reflog

show

$ git show 651bb22                                                                                                        
$ git show 651bb22:README.md
$ git show --topo-order --decorate --oneline
$ git show --topo-order --decorate --oneline --all

blame

$ git blame myfile 
$ git blame -n myfile
$ git blame -L 3,6 -C myfile

diff

$ git diff HEAD^^
$ diff 8084b3f..edeaa87                                                                     
$ git diff 26e5423:.gitignore  3c99fa1:.gitignore
$ git diff 3c99fa1..26e5423 dir1/dir2/file2

$ git diff --cached

$ git diff 2d8de18..17dc028 > path
$ git apply patch
$ git diff
Ou (utilise plutôt revert) :
$ git diff 2d8de18..17dc028 | patch
$ git status

difftool

Utilise un outil tiers comme vim pour afficher les diff (comme vimdiff par exemple).

$ git difftool  HEAD^..HEAD -t vimdiff

Ajouter la configuration ci-dessous pour ne pas avoir à spécifier à chaque fois -t vimdiff :
$ git config --global alias.vimdiff difftool

branch

Gère les branches.

$ git branch gigix 

$ git branch -d gigix

$ git push -u origin -d gigix

$ git branch -m gigix new

$ git branch -vv --all

checkout

Change de branche ou restaure un fichier d'un autre commit.

$ git checkout HEAD^^
$ git checkout 8084b3f
$ git checkout master
$ git checkout mabranche

$ git checkout 8084b3f 1

$ git checkout -b gigix

revert

$ git revert 416515b
$ git revert 7db7d1c..852e094
$ git revert 17dc028 --no-commit

reset

Retourne à un ancien commit et supprime le log.

$ git reset --soft 181d77f
$ git log --graph --topo-order --decorate --oneline --all --color
$ git status
$ git diff --cached
$ git commit -m "message"

$ git reset --mixed 181d77f
$ git log --graph --topo-order --decorate --oneline --all --color
$ git status
$ git diff
$ git commit -a -m "message"

$ git reset 181d77f myfile
$ git log --graph --topo-order --decorate --oneline --all --color
$ git status
$ git diff
$ git commit -a -m "message"

$ git reset

L'option –hard supprimera vos fichiers et votre historique. L'ensemble de votre travail sera donc perdu. Utiliser reset avec précaution !

$ git reset --hard 181d77f

$ git reset --hard

clean

Supprime les fichiers non trackés.

$ git clean -i
$ git clean -n
$ git clean -f

rebase

Rapatrie les commit d'une autre branche dans celle courante.

$ git rebase -i test

$ git rebase -i HEAD~3

Les commit sont indiqués du plus vieux au plus récent (l’ordre est inversé).

$ git rebase master dev
#ou
$ git rebase -i master dev
#On peut ensuite avancer master au niveau de dev et supprimer dev
$ git checkout master
$ git merge dev --ff-only
$ git branch -d dev

Prenons le cas ci-dessous :

Pour fusionner la sous-branche client de server dans master, on fera :

$ git rebase --onto master server client

Ce qui donnera :

merge

Fusionne 2 branche et garde une trace dans l'historique.

$ git merge test

$ git merge test --ff-only

$ git merge test --no-ff

$ git checkout master
$ git merge --squash gigix
$ git diff --staged
$ git commit -a -m "New feature gigix"
#Si on souhaite supprimer gigix
$ git push origin -d gigix

shortlog

Affiche les statistiques.

$ git shortlog -sn

archive

Créer une archive du dépôt git.

$ git archive -l

$ git archive --format=tar.gz -o gigix.tar.gz master
$ git archive --format=tar.gz -o gigix.tar.gz HEAD^1

tag

Gère les tags.

$ git tag
$ git tag -n
$ git tag -l -n

$ git tag test 6452b46

$ git tag -a test 6452b46 -m "gigix"

$ git tag -d test

grep

Recherche dans les fichiers :

$ git grep --all-match -e "^gigix$" -e "modif"
$ git grep -i 'gigix' $(git rev-list --all --abbrev-commit)

bisect

Trouver par recherche dichotomique la modification qui a introduit un bug :

submodule

git config --local status.submoduleSummary true
git config --local diff.submodule log

git submodule add -b docker-edge-to-nightly --force https://github.com/geerlingguy/ansible-role-docker dev/docker
git submodule add -b main https://github.com/roles-ansible/ansible_collection_time.git dev/ntp
git submodule add https://github.com/bennojoy/nginx dev/nginx

cat .gitmodules
cat .git/config

git clone --recursive https://xxx xxx

git submodule update --init --recursive

git submodule update --init --recursive --remote --rebase

git submodule status --recursive

git ls-tree -r HEAD dev/docker
160000 commit c700df55425430d352d16b2a59bea2ab67a6a8bb dev/docker

git submodule status --recursive
git fetch --recurse-submodules --prune
git submodule foreach --recursive 'git reset --hard'
git submodule foreach --recursive 'git clean -fdx'

git submodule set-branch --branch master dev/docker
git submodule set-branch --default dev/docker

git submodule deinit -f -- nginx
git rm -f nginx
rm -rf .git/modules/nginx

worktree

git worktree add -b myfeature ../wk/myfeature main

$ git worktree list 
/home/gigi/git_test4       d67857c [main]
/home/gigi/wk/myfeature    d67857c [myfeature]

* Supprimer un worktree:

git worktree remove /home/gigi/wk/myfeature