« Git » : différence entre les versions

De Banane Atomic
Aller à la navigationAller à la recherche
 
(85 versions intermédiaires par le même utilisateur non affichées)
Ligne 3 : Ligne 3 :
* [https://git-scm.com/docs/ Documentation]
* [https://git-scm.com/docs/ Documentation]
* [http://git-scm.com/book/fr Pro Git book]
* [http://git-scm.com/book/fr Pro Git book]
= [https://github.com/ohmyzsh/ohmyzsh/tree/master/plugins/git/ OhMyZsh Aliases] =
{| class="wikitable wtp wtmono1 wtmono2"
! Alias
! Command
|-
| g || git
|-
| ga || git add
|-
| gaa || git add --all
|-
| gc || git commit --verbose
|-
| gc! || git commit --verbose --amend
|-
| gcmsg || git commit --message
|-
| gca || git commit --verbose --all
|-
| gca! || git commit --verbose --all --amend
|-
| gcan! || git commit --verbose --all --no-edit --amend
|-
| gcam || git commit --all --message
|-
| gsw || git switch
|-
| gswc || git switch -c
|-
| gswm || git switch $(git_main_branch)
|-
| gcp || git cherry-pick
|-
| gf || git fetch
|-
| gfa || git fetch --all --prune
|-
| ggfl || git push --force-with-lease origin $(current_branch)
|-
| ggl || git pull origin $(current_branch)
|-
| ggp || git push origin $(current_branch)
|-
| grs || git restore
|-
| grst || git restore --staged
|-
| grh || git reset
|-
| grhh || git reset --hard
|-
| gpristine || git reset --hard && git clean -dffx
|-
| gst || git status
|-
| gsta || git stash push
|-
| gstu || git stash --include-untracked
|-
| gstp || git stash pop
|}


= init =
= init =
<kode lang=bash>
{{code | lang=bash | code=
# execute the command from the root of the future repo
# execute the command from the root of the future repo
git init
git init
</kode>
}}


= [https://git-scm.com/docs/git-clone clone] =
= [https://git-scm.com/docs/git-clone clone] =
Ligne 46 : Ligne 108 :
git add -p file.ext
git add -p file.ext
</kode>
</kode>
Options pour chaque bloc de modification du fichier :
<pre>
y - stage this hunk
n - do not stage this hunk
q - quit; do not stage this hunk or any of the remaining ones
a - stage this hunk and all later hunks in the file
d - do not stage this hunk or any of the later hunks in the file
e - manually edit the current hunk
indexer cette partie [y,n,a,d,/,j,J,g,e,?]?
y - indexer cette partie
n - ne pas indexer cette partie
a - indexer cette partie et toutes celles restantes dans ce fichier
d - ne pas indexer cette partie ni aucune de celles restantes dans ce fichier
g - sélectionner une partie à voir
/ - chercher une partie correspondant à la regexp donnée
j - laisser cette partie non décidée, voir la prochaine partie non encore décidée
J - laisser cette partie non décidée, voir la prochaine partie
k - laisser cette partie non décidée, voir la partie non encore décidée précédente
K - laisser cette partie non décidée, voir la partie précédente
s - couper la partie courante en parties plus petites
e - modifier manuellement la partie courante
? - afficher l'aide
</pre>


= [https://git-scm.com/docs/git-commit commit] =
= [https://git-scm.com/docs/git-commit commit] =
Ligne 105 : Ligne 142 :


= [https://git-scm.com/docs/git-restore restore] =
= [https://git-scm.com/docs/git-restore restore] =
Undo changes in the Working Tree and/or the Index (unstage).
<kode lang='bash'>
<kode lang='bash'>
# undo the unstaged changes made in file.txt
# undo the unstaged changes made in file.txt
Ligne 111 : Ligne 149 :
# undo all the unstaged changes
# undo all the unstaged changes
git restore .
git restore .
# unstage changes made in file.txt (same as git reset --mixed file.txt)
git restore file.txt --staged
# unstage then undo the changes made in file.txt (same as git reset --hard file.txt)
git restore file.txt --staged --worktree
</kode>
</kode>


Ligne 119 : Ligne 163 :
# default values: git reset --mixed HEAD
# default values: git reset --mixed HEAD


# undo all changes made in the working directory + unstage all
# unstage all then undo all changes made in the working directory
git reset --hard
git reset --hard
</kode>
</kode>


<kode lang='bash'>
<kode lang='bash'>
# undo the last commit
# merge the changes from HEAD to HEAD~x with the current index
# keep the current index and merge the index from the parent commit into the current index, in cases of conflict current index overwrites parent commit index
# in cases of conflict, current index overwrites changes from commits
# working directory is not changed
# working directory remains unchanged
git reset --soft HEAD~
# delete all the commits from HEAD to HEAD~x (not included)
git reset --soft HEAD~x


# undo the last commit
# merge the changes from HEAD to HEAD~x with the current index
# undo the current index and the index from the last commit
# then move and merge the index with the working directory
# keep the working directory and merge current index and index from the last commit in it
# in cases of conflict working directory overwrites current index which overwrites changes from commits
# in cases of conflict working directory overwrites current index which overwrites parent commit index
# delete all the commits from HEAD to HEAD~x (not included)
git reset HEAD~
git reset HEAD~x


# undo the last commit
# delete all the commits from HEAD to HEAD~x (not included)
# undo the current index and the index from the last commit
# unstage all then undo all changes made in the working directory
# undo modifications made in the working directory
git reset --hard HEAD~x
git reset --hard HEAD~
</kode>
</kode>


Ligne 152 : Ligne 196 :


= Modify a previous commit =
= Modify a previous commit =
<kode lang=bash>
<kode lang=bash>
# rebase the branch on the parent of the commit to modify
# rebase the branch on the parent of the commit to modify
git rebase -i HEAD~x
git rebase -i [HEAD~x|commit_id]
git rebase -i [commit id (6 first char)]
# last commit : HEAD , before last commit : HEAD~1 , parent of the before last commit : HEAD~2
# last commit : HEAD , before last commit : HEAD~1 , parent of the before last commit : HEAD~2
# first commit: --root
# first commit: --root
# use 'git log' to get the HEAD~x or the commit id
# use 'git log' to get the HEAD~x or the commit id


# select the commits to modifiy → remplace pick par edit (e)
# you can edit (e), reword (r), drop (d), squash (s)


# update the files and add them to the index
# update the files and add them to the index
Ligne 173 : Ligne 215 :
{{info | All the commits between the one which will be modified and HEAD will be re-written. }}
{{info | All the commits between the one which will be modified and HEAD will be re-written. }}


= Commandes utiles =
= [https://git-scm.com/docs/git-stash stash] =
{| class="wikitable wtp wtmono1 wtmono2"
! Commande
! Alias
! Explication
|-
| git init || || initialise un nouveau dépôts
|-
| git clone url-dépôt [/dossier] || || clone un dépôt
|-
! colspan="3" | Fichiers
|-
| git add file.ext || ga file.ext || ajoute les modifications de {{boxx|file.ext}} à l'{{boxx|index}}
|-
| git add --all || gaa || ajoute les modifications de tous les fichiers du dépôts à l'{{boxx|index}} ({{boxx|-n}})
|-
| git reset HEAD file.ext || grh file.ext || retire {{boxx|file.ext}} de l'{{boxx|index}}
|-
| git checkout HEAD file.ext || gco HEAD file.ext || annule les modifications de {{boxx|file.ext}} (garde l'{{boxx|index}})
|-
| git reset --hard && git clean -dfx || gpristine || annule toutes les modifications, supprime l'{{boxx|index}} et les fichiers non-suivis
|-
! colspan="3" | Status
|-
| git status || gst || affiche les fichiers indexés, non-indexés et non-suivis
|-
| git status --short || gss || affiche dans un format court les fichiers indexés, non-indexés et non-suivis
|-
| git diff || gd || affiche les modifications non-indexées
|-
| git diff --cached || gdca || affiche les modifications indexées
|-
! colspan="3" | Commit
|-
| git commit -v || gc || affiche et valide les modifications indexées
|-
| git commit -v --amend || gc! || modifie le dernier commit en validant les modifications indexées et en changeant le message de validation
|-
| git commit -v --all || gca || indexe tous les fichiers versionnés (pas les nouveaux) et valide le tout
|-
! colspan="3" | Branches
|-
| git branch Branche1 || gb Branche1 || créé Branche1, sans argument liste les branches locales
|-
| git branch --all || gba || liste les branches locales et distantes
|-
| git branch -d Branche1 || gbd Branche1 || supprime Branche1 seulement si les changements locaux ont été pushés
|-
| git checkout Branche1 || gco Branche1 || bascule sur Branche1
|-
| git checkout master || gcm || bascule sur master
|-
| git checkout develop || gcd || bascule sur develop
|-
| git checkout -b Branche1 || gcb Branche1 || créé Branche1 et bascule sur Branche1
|-
| git merge Branche1 || gm Branche1 || fusionne Branche1 dans la branche courante
|-
| git rebase master || grb master<br />grbm || rebase la branche courante au bout de master
|-
! colspan="3" | Dépôts distants
|-
| git remote add origin url || gra origin <url> || ajout du dépôt distant origin avec son url
|-
| git remote remove origin || grrm origin || retire le dépôt distant origin
|-
| git remote -v || grv || lister les dépôts distants
|-
| git fetch origin || gf origin || récupère les changements de toutes les branches du dépôt distant origin
|-
| git fetch --all --prune || gfa || récupère les changements de toutes les branches de tous les dépôts distants et supprime les refs des branches qui n'existent plus sur les dépôts distants.
|-
| git branch Branche1 origin/Branche1 || gb Branche1 origin/Branche1 || copie Branche1 du dépôt distant origin dans un branche locale Branche1
|-
| git checkout --track origin/Branche1 || gct origin/Branche1 || copie Branche1 du dépôt distant origin dans un branche locale Branche1<br />et bascule sur cette la branche locale Branche1
|-
| git pull origin master || gl origin master || récupère les changements de la branche master du dépôt distant origin<br />et fusionne les changements dans la branche locale master
|-
| git pull --rebase origin master || gup origin master || récupère les changements de toutes les branches du dépôt distant origin<br />et rebase les changements au bout de la branche locale master
|-
| git push --tags origin master || gpt origin master || pousser la branche locale master et ses tags<br />pour mettre à jour la branche master du dépôt distant origin
|-
| git push --force-with-lease || gpf ||
|}
 
= [https://git-scm.com/docs/gitrevisions git revision] =
{| class="wikitable wtp wtmono1"
|-
| HEAD~N || Nth ancestor
|}
 
= Créez un dépôt =
<kode lang=bash>
# depuis le répertoire qui deviendra la racine du dépôt
git init
</kode>
 
== Ignorez des fichiers ==
<filebox fn=.gitignore lang=bash>
# ignorez les fichiers temporaires
*~
# ignorez un dossier
MonDossier/*
</filebox>
{{info | Le fichier {{boxx|.gitignore}} affecte le dossier dans lequel il se trouve ainsi que les sous-dossiers.<br />
On peut donc créer des fichiers {{boxx|.gitignore}} spécifiques pour certains sous-dossiers.}}
 
* [[Visual_studio_et_git#gitignore|ASP.NET applications]]
 
== ignore locally without .gitignore ==
Works as {{boxx|.gitignore}} but this file is not tracked.
<filebox fn='.git\info\exclude'>
 
</filebox>
 
= [https://git-scm.com/docs/git-clone Clonez un dépôt] =
<kode lang=bash>
# créé un dossier contenant une copie du dépôt distant
git clone git://url/projet.git [destination]
# si destination n'est pas précisée, git extrait un nom de l'url, ici: projet
 
# Récupérer seulement les n dernier commit de la branche pointé par HEAD
git clone --depth n git://url/projet.git
 
# Récupérer seulement une branche (par défaut, la branche pointé par HEAD)
git clone git://url/projet.git [--branch master] --single-branch [destination]
 
# Partial clone
## Blobless clone: without files content
git clone --filter=blob:none git://url/projet.git [destination]
 
## Treeless clone: without files content and folders
git clone --filter=tree:none git://url/projet.git [destination]
 
# Shallow clone: get only the n last commits
git clone --depth n git://url/projet.git [destination]
</kode>
* [https://github.blog/2020-12-21-get-up-to-speed-with-partial-clone-and-shallow-clone Get up to speed with partial clone and shallow clone]
 
= [https://git-scm.com/docs/git-add Add: from the Working Directory to the Index] =
<kode lang=bash>
# add MonFichier from the Working Copy to the Index
git add MonFichier
 
# add all the files and folders from the Working Copy to the Index
git add .
# git add -u  → add only the modified and deleted, but not the new and untracked files
# git add -n  → dry-run
 
# remove MonFichier from the Index and keep it in the Working Directory
git rm --cached MonFichier
# remove all the files and folders from the Index and keep them in the Working Directory
git rm --cached -r .
</kode>
 
== Indexation partielle ==
Permet de ne valider qu'une partie des modifications d'un fichier.<br />
Utilisez l'option patch de git : <syntaxhighlight lang=bash inline>git add -p</syntaxhighlight><br />
Options pour chaque bloc de modification du fichier :
<pre>
indexer cette partie [y,n,a,d,/,j,J,g,e,?]?
y - indexer cette partie
n - ne pas indexer cette partie
a - indexer cette partie et toutes celles restantes dans ce fichier
d - ne pas indexer cette partie ni aucune de celles restantes dans ce fichier
g - sélectionner une partie à voir
/ - chercher une partie correspondant à la regexp donnée
j - laisser cette partie non décidée, voir la prochaine partie non encore décidée
J - laisser cette partie non décidée, voir la prochaine partie
k - laisser cette partie non décidée, voir la partie non encore décidée précédente
K - laisser cette partie non décidée, voir la partie précédente
s - couper la partie courante en parties plus petites
e - modifier manuellement la partie courante
? - afficher l'aide
</pre>
 
= Commit: from the Index to the Head =
<kode lang=bash>
# Valider l'index
git commit
 
# Ajouter tous les nouveaux fichiers et les fichiers modifiés à l'index puis valider l'index
git commit -a
</kode>
* [https://git-scm.com/docs/git-commit git commit]
 
= Visualiser les modifications =
<kode lang=bash>
# visualiser l'état dans lequel se trouve les changements: indexé, non-indexé, non-versionné
git status
 
# visualiser les modifications qui n'ont pas encore été ajoutées à l'index
git diff
 
# visualisez les modifications ajoutées à l'index
git diff --cached
 
# comparer un fichier entre 2 branches
git diff master MaBranche -- MonFichier.ext
</kode>
* [https://git-scm.com/docs/git-status git status]
* [https://git-scm.com/docs/git-diff git diff]
 
= Supprimer / déplacer des fichiers =
<kode lang=bash>
# supprimer MonFichier de git (arrêtez le suivi de version du fichier) et de la copie de travail
git rm MonFichier
 
# supprimer le MonFichier de git (arrêtez le suivi de version du fichier) mais le conserver dans la copie de travail
git rm --cached MonFichier
 
git mv ancien_fichier nouveau_fichier
# équivalent de:
# mv ancien_fichier nouveau_fichier
# git rm ancien_fichier
# git add nouveau_fichier
</kode>
* [https://git-scm.com/docs/git-rm git rm]
{{info | Le dossier parent peut être renommé sans influence sur le dépôt local ou distant.}}
 
= Visualisez l'historique des validations =
<kode lang=bash>
# énumère en ordre chronologique inversé les commits réalisés
git log
</kode>
<u>Options :</u>
* <tt>-p</tt> : montre les différences introduites entre chaque validation
* <tt>-2</tt> : limite la sortie de la commande aux 2 entrées les plus récentes
* <tt>-pretty=format="%h - %an, %ar : %s"</tt> :  décrit précisément le format de sortie
* <tt>--name-only</tt> : affiche la liste des fichiers modifiés
* <tt>--name-status</tt> : affiche la liste des fichiers affectés accompagnés du staus ajout, modification ou suppression
 
<kode lang=bash>
# Utilisez une interface graphique pour visualiser l'historique
gitk
</kode>
 
= Modifier l'historique =
<kode lang='bash'>
# accès à l'historique de MaBranche (HEAD par défaut)
git reflog MaBranche
# possibilité de reset à un moment de l'historique
</kode>
{{warn | Si les modifications ont déjà été envoyées au serveur, il est toujours possible d'écraser les commits envoyés <syntaxhighlight lang='bash' inline>git push --force-with-lease</syntaxhighlight>}}
 
== Modifier le dernier commit ==
<kode lang=bash>
# Modification du dernier commit en y ajoutant les modifications des fichiers indexés
git commit --amend
# Modifier l'auteur du dernier commit
git commit --amend --author "New Author Name <email@address.com>"
# Modifier le commentaire du dernier commit
git commit --amend -m "Nouveau commentaire"
</kode>
 
=== [http://stackoverflow.com/questions/12481639/remove-files-from-git-commit Retirer un fichier du dernier commit sans le supprimer] ===
<kode lang=bash>
# delete the file from the git repository without deleting it on the file system
git rm --cached unwanted-file.ext
# amend the latest commit
git commit --amend
 
# other solution: met le dernier commit en édition
git reset --soft HEAD~
 
# retire de l'index le fichier souhaité
git reset unwanted-file.ext
 
# sauvegarde le commit avec le même message et le même timestamp
git commit -c ORIG_HEAD
# -C: reuse-message, take an existing commit object, and reuse the log message and the authorship information (including the timestamp) when creating the commit.
# -c: reedit-message, like -C, but with -c the editor is invoked, so that the user can further edit the commit message.
# ORIG_HEAD: is previous state of HEAD, set by commands that have possibly dangerous behavior, to be easy to revert them.
</kode>
 
== Modifiez un commit autre que le dernier ==
<kode lang=bash>
# pour modifier l'avant-dernier commit
git rebase -i HEAD~2
# ici on désigne le parent du commit à modifier : HEAD~2
# dernier commit : HEAD , avant-dernier commit : HEAD~1 , parent de l'avant-dernier commit : HEAD~2
# first commit: --root
 
# marquer les commits à modifier → remplacer pick par edit
 
# apporter les modifications nécessaires puis éditer le dernier commit
git commit --amend
 
# pour terminer, continuer le rebase qui va réécrire tous les commits suivant
git rebase --continue
</kode>
{{info | Tous les commit entre celui qui sera modifié et HEAD seront réécrit }}
 
=== [https://stackoverflow.com/questions/52096295/git-modify-an-old-commit-with-the-file-currently-in-my-working-directory Modify a commit with the content of working directory] ===
<kode lang='bash'>
<kode lang='bash'>
# first create a new commit with the content of working directory
# move the changes of the WD and the Index to a temporary branch
git add file.txt
git commit
 
# rebase on the parent of the commit you want to change
git rebase -i xxxxx
 
# move the commit you newly created just after the one you want to change
# and mark it as fixup (like squash but retains the commit message of the commit being squashed into)
 
# finish the rebase
git rebase --continue
</kode>
 
=== [https://stackoverflow.com/questions/2719579/how-to-add-a-changed-file-to-an-older-not-last-commit-in-git Ajouter une modification à l'avant-dernier commit] ===
<kode lang=bash>
# mettre de côté la modification
git stash
git stash
# --include-untracked / -u stash untracked files too
# --keep-index / -k        move only the changes of the WD
# --staged / -S            move only the changes of the Index


# rebase jusqu'au commit à modifier HEAD~2: parent de l'avant-dernier commit
# move back the changes to the WD and the Index
git rebase -i HEAD~2
# delete the temporaray branch
# marquer l'avant-dernier commit à modifier → remplacer pick par edit
 
# ressortir la modification
git stash pop
git stash pop


# ajouter le fichier contenant la modification
# list the stashes
git add my-file.txt
git stash list
 
# drop a specific stash
# modifier le commit
git stash drop stash@{x}
git commit --amend
# drop all the stashes
 
git stash clear
# terminer le rebase
git rebase --continue
</kode>
 
=== [https://git-scm.com/book/en/v2/Git-Tools-Rewriting-History Squashing Commits] ===
Exemple: squash commits HEAD~3..HEAD
<kode lang=bash>
# HEAD~3: target the 3rd parent of last commit
# Edit the last 3 commits (HEAD~0, HEAD~1, HEAD~2)
git rebase -i HEAD~3
 
# replace the "pick" word by "squash" or "s" on commits HEAD~0, HEAD~1, HEAD~2
# so they will be merged into a new commit
</kode>
 
In case of the following error: [https://stackoverflow.com/questions/39595034/git-cannot-squash-without-a-previous-commit-error-while-rebase cannot 'squash' without a previous commit]<br>
When squashing, the commit selected for squashing is combined with the commit that precedes it in the (edited) list, i.e. the commit from the previous line.<br>
In your case - there is no previous commit for 56bcce7. You have to do one of the following
<kode lang='bash'>
# reword the first commit in the list
1 r 01cc5a08 ...
2 s a2b6eecf ...
</kode>
 
=== Diviser l'avant-dernier commit ===
<kode lang=bash>
# HEAD~2: parent de l'avant-dernier commit
git rebase -i HEAD~2
# marquer l'avant-dernier commit à modifier -> edit
 
# défait le commit et laisse les fichiers modifiés non indexés
git reset HEAD^
 
# indexation d'une partie des fichiers non indexés
git add -p
# commit de la première partie
git commit -m "partie1"
# commit du reste
git commit -m "partie2"
 
# terminer le rebase
git rebase --continue
</kode>
 
== Stopper temporairement le suivi d'un fichier ==
<kode lang=bash>
# ignore temporairement tous les changement apportés à MonFichier
git update-index --assume-unchanged MonFichier
 
# reprend le suivi de MonFichier
git update-index --no-assume-unchanged MonFichier
</kode>
 
== Supprimer les modifications non-commitées ==
<kode lang=bash>
# Réinitialisez un fichier
git checkout -- fichier_à_réinitialiser
 
# Réinitialisez tous le dépôt
git reset --hard && git clean -dfx
</kode>
 
== Supprimez les éléments non-versionnés ==
<kode lang=bash>
git clean -dxf
</kode>
<u>Options</u> :
* <tt>-d</tt> : affecte les dossiers en plus des fichiers
* <tt>-n</tt> : affiche les éléments qui seront supprimés mais ne supprime rien
* <tt>-x</tt> : ne pas utiliser les règles d'exclusion (.gitignore, $GIT_DIR/info/exclude)
* <tt>-f</tt> : obligatoire si la variable <tt>clean.requireForce</tt> est à true
 
== Supprimer les derniers commits ==
* [https://stackoverflow.com/questions/3528245/whats-the-difference-between-git-reset-mixed-soft-and-hard What's the difference between git reset --mixed, --soft, and --hard?]
 
=== [https://www.atlassian.com/git/tutorials/undoing-changes#git-reset reset pour les commits locaux] ===
* [https://git-scm.com/book/en/v2/Git-Tools-Reset-Demystified Reset Demystified]
 
{| class="wikitable wtp"
|-
| HEAD || Pointer to the current commit. Parent of the next commit.
|-
| Index || Staged files proposed to the next commit.<br>
Stage convert working directory into index.<br>
Commit convert Index into a commit.
|-
| Working directory || Sandbox. The actual files.
|}
 
Fait reculer HEAD, les commits resetés sont perdus.
<kode lang=bash>
# move HEAD to the previous commit, reset commit is merge in Index and Working directory is unchanged
git reset --soft HEAD~1
 
# move HEAD to the previous commit, reset Index, reset commit is merged in Working directory
git reset --mixed HEAD~1
 
# move HEAD to the previous commit, reset Index and Working directory, reset commit is lost
git reset --hard HEAD~1
# instead of HEAD~1 you can use the 8 first characters of a commit id
 
# obtenir l'id des commits
git log --pretty=oneline
 
# il peut être utile de créer une branche qui pointe sur le dernier commit avant de faire reculer HEAD
git branch test
</kode>
 
=== [https://www.atlassian.com/git/tutorials/undoing-changes#git-revert revert pour les commits publics] ===
Créé un nouveau commit qui contient les modifications inverses du commit à annuler.<br />
Permet d'annuler un commit qui n'est pas le dernier.
<kode lang='bash'>
git revert --hard xxxxxxxx
# xxxxxxxx : 8 premiers caractères du code du commit
# --hard: overwrites all uncommitted changes in the working directory
</kode>
</kode>


== [https://git-scm.com/docs/git-cherry-pick -appliquer un commit] ==
= [https://git-scm.com/docs/git-cherry-pick cherry-pick] =
<kode lang='bash'>
<kode lang='bash'>
git cherry-pick xxxxxxxx
git checkout my-branch
# xxxxxxxx : 8 premiers caractères de l'id du commit
# apply a specific commit to the current branch
git cherry-pick [commit-id]
</kode>
</kode>
{{info | Utiliser {{boxx|git log}} pour connaitre les ids des commits.}}


== [https://eddmann.com/posts/move-last-git-commit-to-new-or-existing-branch/ Déplacer les commits d'une branche locale vers une autre] ==
= Undo the modifications =
Des commits locaux ont été fait sur la branche {{boxx|badone}} par erreur. Il faut les déplacer vers la branche {{boxx|goodone}}.
<kode lang='bash'>
<kode lang='bash'>
# Si la branche goodone n'existe pas encore: depuis la branche badone, création de la branche goodone
# remove the WD modifications of file.ext only
git checkout goodone
git checkout -- file.ext
# Si la branche goodone existe déjà: on merge badone dans goodone
git checkout goodone
git merge badone
 
# suppression de tous les commits locaux sur la branche badone
git checkout badone
git reset --hard origin/badone
</kode>
 
= [https://git-scm.com/book/en/v2/Git-Tools-Reset-Demystified git reset] =
<kode lang='bash'>
# unstage all
git reset
# default values: git reset --mixed HEAD


# undo all changes made in the working directory + unstage all
# remove the WD and Index modifications of the whole repository
git reset --hard
git reset --hard
# delete the unversioned files
git clean -dfx
# -d  recurse into folders
# -f  needed if clean.requireForce is set to true
# -x  don’t follow the ignore rules (.gitignore, $GIT_DIR/info/exclude)
# -n  dry-run
</kode>
</kode>


= Move the HEAD =
<kode lang='bash'>
<kode lang='bash'>
# undo the last commit
# move the HEAD to a specific commit (detached head state)
# keep the current index and merge the index from the parent commit into the current index, in cases of conflict current index overwrites parent commit index
git checkout [commit-id]
# working directory is not changed
git reset --soft HEAD~
 
# undo the last commit
# undo the current index and the index from the last commit
# keep the working directory and merge current index and index from the last commit in it
# in cases of conflict working directory overwrites current index which overwrites parent commit index
git reset HEAD~
 
# undo the last commit
# undo the current index and the index from the last commit
# undo modifications made in the working directory
git reset --hard HEAD~
</kode>
 
= Se déplacer dans l'arbre =
<kode lang='bash'>
# se déplacer à un commit précis (detached head state)
git checkout [commit id]
 
# retourner au dernier commit (se réattacher à la branche)
git checkout [branch name]
 
# pour lister les commit ids
git log
</kode>
 
= [https://git-scm.com/docs/git-stash Remisage: git stash] =
<kode lang='bash'>
# remise les modifications non-commitées
git stash push -u
# -u, remise aussi les untracked files puis les supprime avec un clean
 
# lister les remises
git stash list
 
# afficher le contenu de la dernière remise
git stash show
 
# applique la dernière remise, puis la supprime
git stash pop


# scénario: impossible de faire un pull à cause de conflits
# move back to the last commit
# remiser les modifications locales
git checkout [branch-name]
git stash
# récupérer les modifications distantes sans conflics
git pull
# ré-appliquer les modifications locales et gérer les éventuels conflits
git stash pop
</kode>
</kode>
[https://git-scm.com/book/fr/v1/Utilitaires-Git-Le-remisage Le remisage]


= Étiquetage (Tags) =
= Étiquetage (Tags) =
Ligne 732 : Ligne 295 :
git show v1.0.0
git show v1.0.0
</kode>
</kode>
= [https://git-scm.com/docs/git-branch branch] =
<kode lang=bash>
# create a new branch from the last commit of the current branch
git branch [NewBranch]
# create a new branch from another branch or a specific commit or a tag
git branch [NewBranch] [BranchName|CommitId|HEAD~x|Tag]
# switch to another branch
git switch [BranchName]
# unable to switch if you have local changes
# -c create the branch if needed
# -m merge local changes to the destination branch
# delete a fully merged branch
git branch -d [BranchName]
# -D if the branch is not fully merged
# rename the current branch
git branch -m [NewBranchName]
</kode>
== [https://git-scm.com/docs/git-merge Merge] ==
<kode lang=bash>
# merge branch1 into main:
# 1 - switch to main
git switch main
# 2 - merge branch1 into the current branch: main
git merge branch1
# in case of conflicts starts the merge tool
git mergetool
</kode>
=== Undo a merge as last commit ===
<kode lang='bash'>
git reset --merge HEAD~1
</kode>
== [https://git-scm.com/docs/git-rebase Rebase] ==
<kode lang=bash>
# rebase branch1 onto main
git rebase main branch1
</kode>
=== Undo a rebase ===
<kode lang='bash'>
# get the head commit before the rebase started
git reflog
# reset to head commit just before the rebase started
git reset --hard HEAD@{X}
</kode>
==  [https://www.atlassian.com/git/tutorials/merging-vs-rebasing Rebase vs Merge] ==
* Merge: create a new commit in the destination branch with the changes from the source branch
* Rebase: rewrite the divergent commits on top of the source branch
{{warn | Don't rebase commits already pushed on a shared remote repository, because it will rewrite the history and may trouble those who already worked on that version of the branch.}}
<u>General rules:</u>
* When pulling changes from origin/develop onto your local develop use {{boxx|rebase}}.<br>You are the only one to use this local branch so you can rewrite the history without trouble.
* When finishing a feature branch {{boxx|merge}} the changes back to develop.<br>It will squash all the commits of the branch into one commit into the shared branch.


= Dépots distants =
= Dépots distants =
Ligne 743 : Ligne 367 :


# if the remote branch doesn't exist yet, push the current branch and set the remote as upstream
# if the remote branch doesn't exist yet, push the current branch and set the remote as upstream
git push --set-upstream origin master
git push --set-upstream origin main
# origin = <remote repository name>
# origin = <remote repository name>
# master = <local branch name>
# main = <local branch name>


# si la brache distante existe déjà, lier origin/master à la branche courante
# si la brache distante existe déjà, lier origin/master à la branche courante
git branch -u origin/master
git branch -u origin/main
# -u origin/master : --set-upstream-to=origin/master
# -u origin/main : --set-upstream-to=origin/main
# origin/master = <remote branch name>
# origin/main = <remote branch name>


# renommez un dépôt distant
# renommez un dépôt distant
Ligne 799 : Ligne 423 :
git config --get remote.origin.url
git config --get remote.origin.url


# supprimez la branche MaBranche sur le dépôt distant origin
# supprimez branch-to-delete sur le dépôt distant origin
git push origin :MaBranche
git push origin --delete branch-to-delete
</kode>
git push origin :branch-to-delete
 
= [https://git-scm.com/docs/git-branch Branches locales] =
<kode lang=bash>
# listez les branches locales et indique quelle est la branche courante
git branch
 
# listez les branches qui ont déjà été fusionnées et qui peuvent donc être supprimées
git branch --merged
 
# listez les branches qui n'ont pas encore été fusionnées
git branch --no-merged
 
# listez toutes les branches locales et distantes
git branch -a
</kode>
 
<kode lang=bash>
# création de MaBranche à partir du dernier commit de la branche courante
git branch MaBranche
 
# création de MaBranche à partir du dernier commit d'une AutreBranche ou d'un ID de commit ou d'un tag
git branch MaBranche [AutreBranche|Commit-ID|Tag]
 
# bascule vers MaBranche
git checkout MaBranche
 
# créé une nouvelle branche et bascule dessus
# les changements non commités reste inchangés et peuvent être commités sur cette nouvelle branche
git checkout -b NouvelleBranche
 
# supprimer la branche locale NouvelleBranche
git branch -d NouvelleBranche
 
# renommer une branche locale
git branch -m NewBranchName
# supprimer la branche distante avec le mauvais nom et créer la branche distante avec le nouveau nom
git push origin :OldBranchName NewBranchName
git push origin -u NewBranchName
 
# récupérer un fichier d'une autre branche
git checkout AutreBranche path/file.ext
</kode>
{{info | git ne permet de basculer vers une branche que si toutes les modifications de la branche courante ont été commitées}}
 
== Merge ==
<kode lang=bash>
# fusion de MaBranche avec master :
# 1 - bascule vers master
git checkout master
# 2 - fusion de MaBranche avec la branche courante (master)
git merge MaBranche
# 3 - suppression de MaBranche
git branch -d MaBranche
 
# en cas de conflits
# lancez l'outils graphique d'édition de conflits
git mergetool
# marquez le conflit comme résolu pour MonFichier.ext
git add MonFichier.ext
 
# merge partiel de MaBranche dans master: seulement jusqu'au commit <commit-hash>
git merge --ff-only <commit-hash>
</kode>
 
== Rebase ==
<kode lang=bash>
# 1 - rebase de MaBranche au bout de master
git rebase master MaBranche
# ou en 2 temps
# 1 - bascule vers MaBranche
git checkout MaBranche
# 2 - rebase de la branche courante (MaBranche) au bout de master
git rebase master
 
# 3 - retour sur master
git checkout master
# 4 - avance rapide (fast forward) de la branche courante (master) vers MaBranche
git merge MaBranche
 
# suppression de MaBranche
git branch -d MaBranche
</kode>
</kode>


=== Undo a rebase ===
= [https://stackoverflow.com/questions/4348590/how-can-i-make-git-ignore-future-revisions-to-a-file Ignore future modifications] =
<kode lang='bash'>
<kode lang='bash'>
# get the head commit before the rebase started
# only on the local branch
git reflog
git update-index --assume-unchanged <file>
# list files that are ignored locally
git ls-files -v . | grep ^h
# undo
git update-index --no-assume-unchanged <file>


# reset to head commit just before the rebase started
# on both local and upstream
git reset --hard HEAD@{X}
git update-index --skip-worktree <file>
# list files that are ignored both locally and upstream
git ls-files -v . | grep ^S
</kode>
</kode>
==  [https://www.atlassian.com/git/tutorials/merging-vs-rebasing Rebase vs Merge] ==
* Réécrit les commits de la branche à rebaser (MaBranche) comme des tout nouveaux commit au sommet de la branche courante (master)
* Permet de simplifier l'historique.
{{warn | Ne rebasez jamais des commits qui ont déjà été poussés sur un dépôt public}}
Règle générale:
* When pulling changes from origin/develop onto your local develop use rebase.
* When finishing a feature branch merge the changes back to develop.


= Noms de branches insensible à la casse =
= Noms de branches insensible à la casse =
Ligne 978 : Ligne 519 :


== [https://git-scm.com/download/gui/linux GUI] ==
== [https://git-scm.com/download/gui/linux GUI] ==
* [https://github.com/Murmele/Gittyup Gittyup] (linux / windows)
* {{boxx|gitk}}, installé avec {{boxx|git}}. Nécessite l'installation du paquet {{boxx|tk}}. À lancer dans le répertoire à analyser.
* {{boxx|gitk}}, installé avec {{boxx|git}}. Nécessite l'installation du paquet {{boxx|tk}}. À lancer dans le répertoire à analyser.
* [https://gitfiend.com GitFiend]
* [https://gitfiend.com GitFiend] (linux)
* [https://www.gitkraken.com GitKraken] (la version gratuite ne supporte pas les dépôts privés ni azure)
* [https://www.gitkraken.com GitKraken] (la version gratuite ne supporte pas les dépôts privés ni azure)
* [https://live.gnome.org/giggle giggle] (linux)
* [https://live.gnome.org/giggle giggle] (linux)
Ligne 985 : Ligne 527 :


== [https://git-for-windows.github.io Git for Windows] ==
== [https://git-for-windows.github.io Git for Windows] ==
<kode lang='ps'>
choco install git
</kode>
* MinGW64
* MinGW64
* MinTTY, thèmes: {{boxx|C:\Users\<Moi>\.mintty\themes\*.minttyrc}}
* MinTTY, thèmes: {{boxx|C:\Users\<Moi>\.mintty\themes\*.minttyrc}}
* [http://jesuswasrasta.com/gitpills/git-pills-customize-your-windows-git-shell-mintty.html Customize your Windows Git shell, MinTTY]
* [http://jesuswasrasta.com/gitpills/git-pills-customize-your-windows-git-shell-mintty.html Customize your Windows Git shell, MinTTY]
<filebox fn='.bashrc' lang='bash' collapsed>
alias g='git'
alias ga='git add'
alias gaa='git add --all'
alias gc='git commit --verbose'
alias gc!='git commit --verbose --amend'
alias gcmsg='git commit --message'
alias gca='git commit --verbose --all'
alias gca!'=git commit --verbose --all --amend'
alias gcan!='git commit --verbose --all --no-edit --amend'
alias gcam='git commit --all --message'
alias gb='git branch'
alias gba='git branch -a'
alias gbdr='git push origin --delete'
alias gsw='git switch'
alias gswc='git switch -c'
alias gswm='git switch $(git_main_branch)'
alias gcp='git cherry-pick'
alias gf='git fetch'
alias gfa='git fetch --all --prune'
alias ggfl='git push --force-with-lease origin $(current_branch)'
alias ggl='git pull origin $(current_branch)'
alias ggp='git push origin $(current_branch)'
alias grs='git restore'
alias grst='git restore --staged'
alias grh='git reset'
alias grhh='git reset --hard'
alias gpristine='git reset --hard && git clean -dffx'
alias gst='git status'
alias gsta='git stash push'
alias gstu'=git stash --include-untracked'
alias gstp='git stash pop'
# Enable the __git_complete function to autocomplete aliases once you press TAB
source '/c/Program Files/Git/mingw64/share/git/completion/git-completion.bash'
__git_complete ga _git_add
__git_complete gc _git_checkout
__git_complete gsw _git_switch
__git_complete gswc _git_switch
__git_complete gm _git_merge
__git_complete gb _git_branch
__git_complete gba _git_branch
__git_complete gbdr _git_branch
__git_complete l _git_log
function git_main_branch() {
  def=`git remote show origin | sed -n '/HEAD branch/s/.*: //p'`
  echo $def
}
function git_current_branch() {
  local ref
  ref=$(__git_prompt_git symbolic-ref --quiet HEAD 2> /dev/null)
  local ret=$?
  if [[ $ret != 0 ]]; then
    [[ $ret == 128 ]] && return  # no git repo.
    ref=$(__git_prompt_git rev-parse --short HEAD 2> /dev/null) || return
  fi
  echo ${ref#refs/heads/}
}
function __git_prompt_git() {
  GIT_OPTIONAL_LOCKS=0 command git "$@"
}
</filebox>
=== [https://interworks.com/blog/2021/09/15/setting-up-ssh-agent-in-windows-for-passwordless-git-authentication/ SSH] ===
# [[SSH#Install_OpenSSH_Client|Install OpenSSH Client]]
# [[SSH#Enable_SSH_Authentication_Agent|Enable SSH Authentication Agent]]
<kode lang='ps'>
# Configuring Git to Leverage the Windows SSH-Agent
git config --global core.sshCommand C:/Windows/System32/OpenSSH/ssh.exe
</kode>


=== [https://stackoverflow.com/questions/22575662/filename-too-long-in-git-for-windows Filename too long] ===
=== [https://stackoverflow.com/questions/22575662/filename-too-long-in-git-for-windows Filename too long] ===
<kode lang='ps'>
<kode lang='ps'>
git config --system core.longpaths true
git config --system core.longpaths true
</kode>
=== [https://stackoverflow.com/questions/23885449/unable-to-resolve-unable-to-get-local-issuer-certificate-using-git-on-windows SSL Certificate problem: unable to get local issuer certificate] ===
Configure Git to use {{boxx|Secure Channel}} instead of {{boxx|OpenSSL}}. This means that it will use the Windows certificate storage mechanism.
<kode lang='ps'>
git config --global http.sslbackend schannel
</kode>
</kode>


Ligne 1 011 : Ligne 638 :


== Commandes ==
== Commandes ==
<kode lang=bash>
<kode lang=bash collapsed>
git config --global core.editor "nano -w"
git config --global core.editor "nano -w"


Ligne 1 030 : Ligne 657 :


# LF - CRLF
# LF - CRLF
# lors du checkout converti les LF CRLF
# for Windows user: convert to LF while commiting and convert to CRLF while checking out
git config --global core.autocrlf true
git config --global core.autocrlf true
# lors du commit converti les CRLF → LF
# for Linux users: convert to LF while checking out in case there are unexpectedly
git config --global core.autocrlf input
git config --global core.autocrlf input
# checkout et commit des fichiers tels quels
# checkout et commit des fichiers tels quels
Ligne 1 047 : Ligne 674 :
<filebox fn=~/.gitconfig lang=ini>
<filebox fn=~/.gitconfig lang=ini>
[core]
[core]
editor = nano -w
    editor = nano -w
    autocrlf = input  ; for GNU/Linux OS
 
[user]
[user]
name = Prénom Nom
    name = Prénom Nom
email = compte@email.com
    email = compte@email.com
 
[color]
[color]
ui = true
    ui = true ; get the color in the console
 
[merge]
[merge]
tool = meld
    tool = meld
    tool = kdiff3
[mergetool "kdiff3"]
    path = C:/Program Files/KDiff3/kdiff3.exe
    trustExitCode = false
 
[credential]
[credential]
helper = cache | store
    helper = cache | store
</filebox>
</filebox>


Ligne 1 107 : Ligne 743 :
<filebox fn='~/.gitconfig' lang='ini'>
<filebox fn='~/.gitconfig' lang='ini'>
[diff]
[diff]
external = /path/to/git-diff-meld.sh
    external = /path/to/git-diff-meld.sh
</filebox>
 
== [https://www.aleksandrhovhannisyan.com/blog/crlf-vs-lf-normalizing-line-endings-in-git Normalizing Line Endings] ==
<filebox fn='.gitattributes' lang='ini'>
; at the source of your repo
; normalizes all line endings to LF when committing text files into your repo
; does not modify line endings in your working tree when checking-out
; equivalentb of autocrlf=input
* text=auto
</filebox>
 
<kode lang='bash'>
# after the creation or a modification of line endings setting in .gitattributes
# apply the change to the repo: updates all tracked files in your repo
git add --renormalize .
 
# verifying Line Endings
git ls-files --eol
# i/lf: index (repo), LF
# w/crlf: working directory, CRLF
# i/mixed: index, mixed of LF and CRLF
# i/none: index, no line ending
# i/-text: index, binary file
</kode>
 
{| class="wikitable wtp wtmono1"
|+ {{boxx|core.autocrlf}}
! Value
! checkout
! commit
! OS
|-
| input || - || LF || GNU/Linux
|-
| true || CRLF || LF || Windows OS
|-
| false || - || - || -
|}
 
= git-filter-repo =
== Change the author of all the commits ==
<filebox fn='mailmap'>
NewName <new@email.com> <old@email.com>
</filebox>
</filebox>
<kode lang='bash'>
cd MyProject
git filter-repo --mailmap ../mailmap --force
# Git filter-repo deletes the remote address repository to protect from accidental overwrites.
git remote add origin user@server:repo.git
git push --set-upstream origin main --force
</kode>


= [https://git-scm.com/book/fr/v2/Git-sur-le-serveur-Protocoles Serveur Git] =
= [https://git-scm.com/book/fr/v2/Git-sur-le-serveur-Protocoles Serveur Git] =
Ligne 1 194 : Ligne 882 :
== [https://wiki.archlinux.org/index.php/Gitolite Gitolite] ==
== [https://wiki.archlinux.org/index.php/Gitolite Gitolite] ==
* [[Ubuntu_arm_18.04#Gitolite|Gitolite]] on Ubuntu ARM 18.04
* [[Ubuntu_arm_18.04#Gitolite|Gitolite]] on Ubuntu ARM 18.04
== [[Gogs]] ==

Dernière version du 23 octobre 2024 à 09:25

Links

OhMyZsh Aliases

Alias Command
g git
ga git add
gaa git add --all
gc git commit --verbose
gc! git commit --verbose --amend
gcmsg git commit --message
gca git commit --verbose --all
gca! git commit --verbose --all --amend
gcan! git commit --verbose --all --no-edit --amend
gcam git commit --all --message
gsw git switch
gswc git switch -c
gswm git switch $(git_main_branch)
gcp git cherry-pick
gf git fetch
gfa git fetch --all --prune
ggfl git push --force-with-lease origin $(current_branch)
ggl git pull origin $(current_branch)
ggp git push origin $(current_branch)
grs git restore
grst git restore --staged
grh git reset
grhh git reset --hard
gpristine git reset --hard && git clean -dffx
gst git status
gsta git stash push
gstu git stash --include-untracked
gstp git stash pop

init

Bash.svg
# execute the command from the root of the future repo
git init

clone

Bash.svg
# create a folder containing a copy of the remote repo
git clone git://url/projet.git [destination]
# if destination is not set, git will extract the destination name from the url (here: projet)

# get only the latest version of a repo
git clone --depth 1 --recurse-submodules --shallow-submodules git://url/projet.git
# --branch <branch_name>  get another branch or tag
# --filter=blob:none      get a blobless clone: without files content
# --filter=tree:none      get a treeless clone: without files content and folders

add

Move files from the Working Directory to the Index.

Bash.svg
# add file.ext from the Working Copy to the Index
git add file.ext

# add all the files and folders from the Working Copy to the Index
git add .
# git add -u  → add only the modified and deleted, but not the new and untracked files
# git add -n  → dry-run

# remove file.ext from the Index and keep it in the Working Directory
git rm --cached file.ext
# remove all the files and folders from the Index and keep them in the Working Directory
git rm --cached -r .

patch

Select interactively blocks of modifications to index them.

Bash.svg
git add -p file.ext

commit

Move changes from the Index into a new commit to the Head.

Bash.svg
# create a new commit and move in it the staged files (Index)
git commit
# -m 'commit message'

# move from the Working Directory to the Index all the modified and new files
# then create a new commit and move in it the staged files (Index)
git commit -a

status

Bash.svg
# display paths that have been modified
git status
# -v   show the textual changes that are staged to be committed (like git diff --cached)
# -vv  also show the changes in the working tree (like git diff)

diff

Bash.svg
# display changes in the working tree not yet staged for the next commit
git diff

# display changes between the index and your last commit
git diff --cached

# compare file.ext between 2 branches
git diff master MaBranche -- file.ext

restore

Undo changes in the Working Tree and/or the Index (unstage).

Bash.svg
# undo the unstaged changes made in file.txt
git restore file.txt

# undo all the unstaged changes
git restore .

# unstage changes made in file.txt (same as git reset --mixed file.txt)
git restore file.txt --staged

# unstage then undo the changes made in file.txt (same as git reset --hard file.txt)
git restore file.txt --staged --worktree

reset

Bash.svg
# unstage all
git reset
# default values: git reset --mixed HEAD

# unstage all then undo all changes made in the working directory
git reset --hard
Bash.svg
# merge the changes from HEAD to HEAD~x with the current index
# in cases of conflict, current index overwrites changes from commits
# working directory remains unchanged
# delete all the commits from HEAD to HEAD~x (not included)
git reset --soft HEAD~x

# merge the changes from HEAD to HEAD~x with the current index
# then move and merge the index with the working directory
# in cases of conflict working directory overwrites current index which overwrites changes from commits
# delete all the commits from HEAD to HEAD~x (not included)
git reset HEAD~x

# delete all the commits from HEAD to HEAD~x (not included)
# unstage all then undo all changes made in the working directory
git reset --hard HEAD~x

amend

Update the last commit.

Bash.svg
# add the modification to the index
# then update the last commit with the changes from the index
git commit --amend
# --author "New Author Name <email@address.com>"  update the author
# -m "New comment"                                update the comment

Modify a previous commit

Bash.svg
# rebase the branch on the parent of the commit to modify
git rebase -i [HEAD~x|commit_id]
# last commit : HEAD , before last commit : HEAD~1 , parent of the before last commit : HEAD~2
# first commit: --root
# use 'git log' to get the HEAD~x or the commit id

# you can edit (e), reword (r), drop (d), squash (s)

# update the files and add them to the index
git add .
# then update the current commit
git commit --amend

# finish the rebase
git rebase --continue
All the commits between the one which will be modified and HEAD will be re-written.

stash

Bash.svg
# move the changes of the WD and the Index to a temporary branch
git stash
# --include-untracked / -u stash untracked files too
# --keep-index / -k        move only the changes of the WD
# --staged / -S            move only the changes of the Index

# move back the changes to the WD and the Index
# delete the temporaray branch
git stash pop

# list the stashes
git stash list
# drop a specific stash
git stash drop stash@{x}
# drop all the stashes
git stash clear

cherry-pick

Bash.svg
git checkout my-branch
# apply a specific commit to the current branch
git cherry-pick [commit-id]

Undo the modifications

Bash.svg
# remove the WD modifications of file.ext only
git checkout -- file.ext

# remove the WD and Index modifications of the whole repository
git reset --hard
# delete the unversioned files
git clean -dfx
# -d  recurse into folders
# -f  needed if clean.requireForce is set to true
# -x  don’t follow the ignore rules (.gitignore, $GIT_DIR/info/exclude)
# -n  dry-run

Move the HEAD

Bash.svg
# move the HEAD to a specific commit (detached head state)
git checkout [commit-id]

# move back to the last commit
git checkout [branch-name]

Étiquetage (Tags)

Par défaut la commande git push n'envoie pas les étiquettes vers les serveurs distants.
Pour ce faire : git push --tags

Créez des étiquettes

Bash.svg
# Étiquette la dernière validation
git tag v2.0

# Étiquette la dernière validation dont la somme de controle commence par 9fceb02
git tag v1.2 9fceb02

# Supprimez le tag v1.2
git tag -d v1.2
# Supprimez le tag v1.2 sur la branche distante
git push --delete origin v1.2

Listez vos étiquettes

Bash.svg
# Listez les étiquettes existantes
git tag

# Recherchez les étiquettes correspondant à un motif particulier
git tag -l 'v1.*'

# Affichez le commit correspondant au tag v1.0.0
git show v1.0.0

branch

Bash.svg
# create a new branch from the last commit of the current branch
git branch [NewBranch]
# create a new branch from another branch or a specific commit or a tag
git branch [NewBranch] [BranchName|CommitId|HEAD~x|Tag]

# switch to another branch
git switch [BranchName]
# unable to switch if you have local changes
# -c create the branch if needed
# -m merge local changes to the destination branch

# delete a fully merged branch
git branch -d [BranchName]
# -D if the branch is not fully merged

# rename the current branch
git branch -m [NewBranchName]

Merge

Bash.svg
# merge branch1 into main:
# 1 - switch to main
git switch main
# 2 - merge branch1 into the current branch: main
git merge branch1

# in case of conflicts starts the merge tool
git mergetool

Undo a merge as last commit

Bash.svg
git reset --merge HEAD~1

Rebase

Bash.svg
# rebase branch1 onto main
git rebase main branch1

Undo a rebase

Bash.svg
# get the head commit before the rebase started
git reflog

# reset to head commit just before the rebase started
git reset --hard HEAD@{X}

Rebase vs Merge

  • Merge: create a new commit in the destination branch with the changes from the source branch
  • Rebase: rewrite the divergent commits on top of the source branch
Don't rebase commits already pushed on a shared remote repository, because it will rewrite the history and may trouble those who already worked on that version of the branch.

General rules:

  • When pulling changes from origin/develop onto your local develop use rebase.
    You are the only one to use this local branch so you can rewrite the history without trouble.
  • When finishing a feature branch merge the changes back to develop.
    It will squash all the commits of the branch into one commit into the shared branch.

Dépots distants

Ajoutez des dépôts distants

Bash.svg
# listez les dépôts distants
git remote -v

# ajoutez un dépôt distant (nom donné au dépôt: origin)
git remote add origin git://github.com/createur/projet.git

# if the remote branch doesn't exist yet, push the current branch and set the remote as upstream
git push --set-upstream origin main
# origin = <remote repository name>
# main = <local branch name>

# si la brache distante existe déjà, lier origin/master à la branche courante
git branch -u origin/main
# -u origin/main : --set-upstream-to=origin/main
# origin/main = <remote branch name>

# renommez un dépôt distant
git remote rename current_name new_name

# retirez un dépôt distant
git remote rm repo_name

# modifier l'url du dépôt distant
git remote set-url origin https://github.com/createur/projet.git

Mise à jour et validation

Bash.svg
# récupère les modifications effectués sur le dépôt distant origin (met à jour les branches distantes origin/*)
# ne modifie pas la branche courante ni ne bascule vers une autre branche
git fetch origin

# fusionne la branche distante origin/master dans la branche locale courante
git merge origin/master

# récupérer la branche MaBranche du dépôt distant origin et la nommer localement MaBranche
git branch MaBranche origin/MaBranche
# équivalent avec checkout en plus
git checkout -b MaBranche origin/MaBranche
git checkout --track origin/MaBranche

# fetch + merge : récupère les modifications effectués sur le dépôt distant et les fusionne avec la branche courante
git pull origin master

# Pousser son travail sur un dépôt distant
git push --tags origin master
# --tags permet de pousser ses tags vers le dépôt distant, ce que ne fait pas push par défaut

# Pousser une branche locale nouvellement créée
git push -u origin <Ma_Nouvelle_Branche>

Branches des dépôts distants

Bash.svg
# listez les branches distantes
git branch -r

# listez toutes les branches
git branch -a

# url d'une branche distante
git config --get remote.origin.url

# supprimez branch-to-delete sur le dépôt distant origin
git push origin --delete branch-to-delete
git push origin :branch-to-delete

Ignore future modifications

Bash.svg
# only on the local branch
git update-index --assume-unchanged <file>
# list files that are ignored locally
git ls-files -v . | grep ^h
# undo
git update-index --no-assume-unchanged <file>

# on both local and upstream
git update-index --skip-worktree <file>
# list files that are ignored both locally and upstream
git ls-files -v . | grep ^S

Noms de branches insensible à la casse

Les noms de branches git ne sont pas sensible à la casse

Bash.svg
# checkout d'une branche distante en minuscule vers une branche locale en majuscule
git checkout -b My_New_Branch /origin/my_new_branch
# pull fonctionne, mais lors du push, création d'une nouvelle branche en majuscule

# renommer My_New_Branch en my_new_branch
# comme git est insensible à la casse il faut passer par une branche intermédiaire
git branch -m My_New_Branch tmp_branch
git branch -m tmp_branch my_new_branch

Autre solution: forcer git à ignorer la casse

%HomePath%\.gitconfig
[core]
    ignorecase = true
Bash.svg
# supprimer les branches locales et locale-remote
# mettre à jour les branches distantes
git fetch -p

Exportez dans une archive

Bash.svg
git archive mon_tag -o mon_archive.zip -9 --prefix=mon_dossier/
# -9 compression max de l'archive, -0 pas de compression
# HEAD peut-être utilisé comme tag

# tar.gz
git archive mon_tag --prefix=mon_dossier/ >mon_archive.tar.gz

Blame

Bash.svg
# Affiche les lignes 12 à 22 de fichier.ext avec pour chaque ligne son auteur et la révision associée
git blame -L 12,22 fichier.ext

# seulement la ligne 12
git blame -L 12,12 fichier.ext

# avec une interface graphique, ouvre fichier.ext à la ligne 12
git gui blame --line=12 fichier.ext

# blame a deleted file
# git blame works when providing a commit reference that contains the file. Find the most recent one with log
git log -2 --oneline -- deletedFile.cs
# ac173c96f Merged PR 121163: File already deleted
# 37f91c2fa Merged PR 113177: Before deleting file
git blame 37f91c2fa -- deletedFile.cs
git gui blame 37f91c2fa deletedFile.cs

bisect

Définit un commit de début et un commit de fin et permet de lancer un test sur chaque commit intermédiaire.
Permet de localiser un commit introduisant un bug.

Installation

Bash.svg
sudo pacman -S git tk
# tk pour gitk
# sans tk l'erreur suivante s'affiche: /usr/bin/gitk: line 3: exec: wish: not found
~/.bashrc
# activer l'autocomplétion
source /usr/share/git/completion/git-completion.bash

GUI

  • Gittyup (linux / windows)
  • gitk, installé avec git. Nécessite l'installation du paquet tk. À lancer dans le répertoire à analyser.
  • GitFiend (linux)
  • GitKraken (la version gratuite ne supporte pas les dépôts privés ni azure)
  • giggle (linux)
  • Git Extensions (windows)

Git for Windows

Ps.svg
choco install git
.bashrc
alias g='git'
alias ga='git add'
alias gaa='git add --all'
alias gc='git commit --verbose'
alias gc!='git commit --verbose --amend'
alias gcmsg='git commit --message'
alias gca='git commit --verbose --all'
alias gca!'=git commit --verbose --all --amend'
alias gcan!='git commit --verbose --all --no-edit --amend'
alias gcam='git commit --all --message'
alias gb='git branch'
alias gba='git branch -a'
alias gbdr='git push origin --delete'
alias gsw='git switch'
alias gswc='git switch -c'
alias gswm='git switch $(git_main_branch)'
alias gcp='git cherry-pick'
alias gf='git fetch'
alias gfa='git fetch --all --prune'
alias ggfl='git push --force-with-lease origin $(current_branch)'
alias ggl='git pull origin $(current_branch)'
alias ggp='git push origin $(current_branch)'
alias grs='git restore'
alias grst='git restore --staged'
alias grh='git reset'
alias grhh='git reset --hard'
alias gpristine='git reset --hard && git clean -dffx'
alias gst='git status'
alias gsta='git stash push'
alias gstu'=git stash --include-untracked'
alias gstp='git stash pop'

# Enable the __git_complete function to autocomplete aliases once you press TAB
source '/c/Program Files/Git/mingw64/share/git/completion/git-completion.bash'

__git_complete ga _git_add
__git_complete gc _git_checkout
__git_complete gsw _git_switch
__git_complete gswc _git_switch
__git_complete gm _git_merge
__git_complete gb _git_branch
__git_complete gba _git_branch
__git_complete gbdr _git_branch
__git_complete l _git_log


function git_main_branch() {
  def=`git remote show origin | sed -n '/HEAD branch/s/.*: //p'`
  echo $def
}

function git_current_branch() {
  local ref
  ref=$(__git_prompt_git symbolic-ref --quiet HEAD 2> /dev/null)
  local ret=$?
  if [[ $ret != 0 ]]; then
    [[ $ret == 128 ]] && return  # no git repo.
    ref=$(__git_prompt_git rev-parse --short HEAD 2> /dev/null) || return
  fi
  echo ${ref#refs/heads/}
}

function __git_prompt_git() {
  GIT_OPTIONAL_LOCKS=0 command git "$@"
}

SSH

  1. Install OpenSSH Client
  2. Enable SSH Authentication Agent
Ps.svg
# Configuring Git to Leverage the Windows SSH-Agent
git config --global core.sshCommand C:/Windows/System32/OpenSSH/ssh.exe

Filename too long

Ps.svg
git config --system core.longpaths true

SSL Certificate problem: unable to get local issuer certificate

Configure Git to use Secure Channel instead of OpenSSL. This means that it will use the Windows certificate storage mechanism.

Ps.svg
git config --global http.sslbackend schannel

Configuration

Fichiers

  • .git/config accès par défaut ou avec l'option --local
  • ~/.gitconfig accès avec l'option --global
  • /etc/gitconfig accès avec l'option --system
Bash.svg
# ouvre le fichier de configuration dans le éditeur de texte
git config --global --edit
git config --system --edit
git config --local --edit  # work only from a git repo

# display all the config by file
git config --list --show-origin

Commandes

Bash.svg
git config --global core.editor "nano -w"

git config --global user.name "Prénom Nom"
git config --global user.email "compte@email.com"

git config --global color.ui true

git config --global merge.tool meld

# autorise git à conserver le mot de passe pendant 15mn (valeur par défaut)
git config --global credential.helper cache
# autorise git à conserver le mot de passe pendant 1h
git config --global credential.helper 'cache --timeout=3600'

# stocke les informations d'identification dans le fichier ~/.git-credentials
git config --global credential.helper store

# LF - CRLF
# for Windows user: convert to LF while commiting and convert to CRLF while checking out
git config --global core.autocrlf true
# for Linux users: convert to LF while checking out in case there are unexpectedly
git config --global core.autocrlf input
# checkout et commit des fichiers tels quels
git config --global core.autocrlf false

# Gnome Keyring
# compilez le credential pour gnome-keyring
cd /usr/share/git/credential/gnome-keyring
sudo make
# configurez git
git config --global credential.helper /usr/share/git/credential/gnome-keyring/git-credential-gnome-keyring
~/.gitconfig
[core]
    editor = nano -w
    autocrlf = input  ; for GNU/Linux OS

[user]
    name = Prénom Nom
    email = compte@email.com

[color]
    ui = true ; get the color in the console

[merge]
    tool = meld
    tool = kdiff3
[mergetool "kdiff3"]
    path = C:/Program Files/KDiff3/kdiff3.exe
    trustExitCode = false

[credential]
    helper = cache | store

Les alias Git

Bash.svg
# permet de taper 'git unstage' au lieu de 'git reset HEAD --'
git config --global alias.unstage 'reset HEAD --'

# alias pour visualiser plus facilement le dernier commit
git config --global alias.last 'log -1 HEAD'

# permet de taper 'git ci' au lieu de 'git commit'
git config --global alias.ci commit
git config --global alias.co checkout
git config --global alias.br branch
git config --global alias.st status
~/.gitconfig
[alias]
	unstage = reset HEAD --
	last = log -1 HEAD
	ci = commit
	co = checkout
	br = branch
	st = status

git diff avec meld

meld

Bash.svg
# se placer dans le dossier git
meld .

difftool

Bash.svg
git difftool -y fichier.ext
# -y: no prompt

diff external

git-diff-meld.sh
#!/bin/bash
meld $2 $5
Bash.svg
git config --global diff.external /path/to/git-diff-meld.sh
~/.gitconfig
[diff]
    external = /path/to/git-diff-meld.sh

Normalizing Line Endings

.gitattributes
; at the source of your repo
; normalizes all line endings to LF when committing text files into your repo
; does not modify line endings in your working tree when checking-out
; equivalentb of autocrlf=input
* text=auto
Bash.svg
# after the creation or a modification of line endings setting in .gitattributes
# apply the change to the repo: updates all tracked files in your repo 
git add --renormalize .

# verifying Line Endings
git ls-files --eol
# i/lf: index (repo), LF
# w/crlf: working directory, CRLF
# i/mixed: index, mixed of LF and CRLF
# i/none: index, no line ending
# i/-text: index, binary file
core.autocrlf
Value checkout commit OS
input - LF GNU/Linux
true CRLF LF Windows OS
false - - -

git-filter-repo

Change the author of all the commits

mailmap
NewName <new@email.com> <old@email.com>
Bash.svg
cd MyProject
git filter-repo --mailmap ../mailmap --force

# Git filter-repo deletes the remote address repository to protect from accidental overwrites.
git remote add origin user@server:repo.git
git push --set-upstream origin main --force

Serveur Git

Bash.svg
# créer un dossier de stockage
cd /srv
mkdir git
chown git:git git

# créer un projet de test
cd /srv/git
git init project.git --bare --shared
# bare: dépôt vide
# shared: dépôt partagé rwxrwsr-x au lieu de rwxr-xr-x
# et le fichier config contient sharedrepository = 1 et denyNonFastforwards = true
chown -R git:git project.git
# ajouter le groupe git aux utilisateurs pour qu'ils puissent pousser leurs modifications

# ajouter le dépôt fraîchement créé à un dépôt local
git remote add origin user@server:/srv/git/projet.git
# envoyer les modifications locales vers le dépôt distant
git push origin master

# récupérer le projet depuis un client avec le protocole ssh
git clone user@server:/srv/git/projet.git

# démarrer le serveur Git. Seulement utile pour le protocole git
systemctl start git-daemon.socket

Protocoles

local le dépôt distant est un autre répertoire dans le système de fichiers
par exemple un répertoire partagé via NFS
git clone /srv/git/projet.git
ssh permet de cloner et de pousser git clone utilisateur@serveur:/srv/git/projet.git
git daemon écoute sur le port 9418
pas d'authentification, tous le monde peut cloner et pousser
http(s) permet de cloner mais pas de pousser git clone http://server/projetgit.git

Gitweb

Bash.svg
pacman -S perl-cgi fcgiwrap

# démarrer le service fcgiwrap
sc-start fcgiwrap.socket
/etc/nginx/nginx.conf
server {
    listen 80;
    server_name gitweb.myserver;

    location /gitweb.cgi {
        include fastcgi_params;
        gzip off;
        fastcgi_param   SCRIPT_FILENAME  /usr/share/gitweb/gitweb.cgi;
        fastcgi_param   GITWEB_CONFIG    /etc/gitweb.conf;
        fastcgi_pass    unix:/run/fcgiwrap.sock;
    }

    location / {
        root /usr/share/gitweb;
        index gitweb.cgi;
    }
}
/etc/gitweb.conf
# The directories where your projects are. Must not end with a slash.
our $projectroot = "/srv/git"; 

# Base URLs for links displayed in the web interface.
our @git_base_url_list = qw(git://myserver http://git@myserver);

# enable "blame" view
$feature{'blame'}{'default'} = [1];

# enable syntax highlighting (installer le package highlight)
$feature{'highlight'}{'default'} = [1];

Gitolite

Gogs