Cheat sheet Git

BRANCH
git branch
              Lister les branches locales.

              Pour avoir plus d'informations (le dernier commit, branche distante liée, label du dépôt distant etc...) rajouter -vv.
            
git branch -r
              Lister les branches distantes.
            
git branch -a
            Lister les branches locales et distantes.
            
git branch <branche>
              Créer une nouvelle branche.
            
git branch -d <branche>
              Supprimer la branche localement.

              Se positionner en dehors de celle-ci avant d'entrer la commande.
              Pour forcer la suppression, remplacer -d par -D. Ca sera nécessaire si la branche n'a pas été mergée.

                Pour supprimer une branche sur un dépôt distant, voir dans la partie #PUSH
            
git branch -m
              Renommer la branche sur laquelle on est positionné.
            
CHECKOUT
git checkout <branche>
                Changer de branche.
              
git checkout -b <branche>
                Créer une branche et basculer sur celle-ci.
              
git checkout <ref>
                Détacher HEAD et se placer sur le commit référencé.
              
COMMIT
git commit -am "<message>"
              Stage et commit tous les fichiers modifiés.

              -a va stage seulement les fichiers suivis. Il ne remplace pas un git add .  qui prendra aussi les nouveaux fichiers en compte.
            
git commit --amend
              Remplace le précédent commit.

              Le nouveau commit contiendra ce qu’on vient de stage et sera couplé à l’ancien commit. Cela recréé un nouveau commit et retire l’ancien. 
              
              Si on veut changer le nom du commit, ajouter -m "<message>". 

              Si on veut juste ajouter des changements en gardant l'ancien message de commit, ajouter --no-edit.
               
              Il est aussi possible de changer le nom du commit sans avoir stage de modifications.
            
DIFF
git diff
              Voir les modifications sur les fichiers suivis et pas encore stage entre le répertoire de travail et HEAD.
            
git diff --staged
              Voir les modifications entre les fichiers qui ont été stage et HEAD

              Autre notation : git diff --cached
            
git diff HEAD
              Voir les modifications entre les fichiers suivis (stage et non stage) et HEAD.
            
git diff <fichier1> <fichier2...>
              Voir les modifications seulement dans les fichiers indiqués.
            
git diff <branche1> <branche2>
              Voir les modifications entre 2 branches (sur leur dernier commmit respectif).

              Possibilité de faire la comparaison seulement sur certains fichiers en rajoutant leurs noms à la suite.

              Autre notation : git diff <branche1>..<branche2>
            
git diff <ref-1> <ref-2>
              Voir les modifications entre 2 commits reférencés.

              Possibilité de ne référencer qu'un seul commit, ce qui fera une comparaison entre celui-ci et HEAD. 

              Exemple, git diff HEAD~1. 
            
LOG
git log
              Afficher un log des commits présents dans notre branche.
            
git log --all
              Afficher un log de tous les commits.
            
git log --oneline
              Formater l'affichage des logs sur une ligne.
            
git log --graph
              Afficher une représentation graphique de l'historique des commits.
            
git log --<nombre>
              Limite le nombre de commits affichés.
            
git log <ref-b> <ref-a>
              Affiche le log des commits référencés sur l'intervalle donné.

              Préciser le commit le plus ancien des 2 en premier pour un affichage cohérent.
            
PUSH
git push <label-dist> <branche>
              Envoyer les modifications de la branche locale vers la branche distante.

              Si les 2 branches ne sont pas liées, rajouter l'argument -u. 

              Si le label du dépôt distant est nommé origin et que les branches locales et distantes sont liées, on peut juste écrire git push. 

              Quand on renseigne ni le label, ni la branche,  git utilisera origin comme label, et il pointera la branche distante qui à le même nom que la branche locale.

              Si on ajoute l'argument -f cela aura pour effet d'écraser l'historique de la branche distante par celui en local. 
              
              Une alternative plus douce est --force-with-lease qui fera le push seulement si la branche distante n'a pas été mise à jour entre temps. 
              
              Plus d'infos ici : #GÉRER LES PUSHS FORCÉS

              Pour lier les tags aux pushs de commits, voir ici : #FOLLOW-TAGS
            
git push <label-dist> -d <branche>
                Supprimer la branche du dépôt distant.

                -d peut aussi être noté --delete.
              
git push <label-dist> <tag>
                Envoyer le tag spécifié sur le dépôt distant.

                Lors d'un push de commit classique, les tags ne sont pas envoyés sur le dépôt distant.
                Si on veut envoyer tous les tags, remplacer <tag> par --tags.
              
git push <label-dist> -d <tag>
                Supprimer le tag du dépôt distant.

                -d peut aussi être noté --delete.

                Si le nom du tag est exactement celui d'une branche existante, on peut spécifier :refs/tags/<tag> à la place de <tag>. Cela fera directement référence au nom du tag pointé dans le dossier .git.

                Exemple : git push origin -d :refs/tags/release
              
git push --follow-tags
                Envoyer les modifications de la branche locale vers la branche distante ainsi que les tags annotés ET atteignables par les commits pushés.

                Cette commande, en plus de faire 2 choses à la fois permet de faire un push safe des tags.
               
                Si on a une branche locale avec des commits non push et disposant de tags, ils ne seront pas envoyés sur le dépôt distant.

                Il est possible de configurer git pour que git push inclue systématiquement l'argument --follow-tags avec la commande :

                git config --global push.followTags true
              
REBASE
git rebase <branche>
              Prendre les commits de notre branche n’étant pas présent dans la branche visée et les ré-appliquer par dessus son dernier commit.

              Voir schémas : #Schémas REBASE
            
git rebase -i <ref>
              Rebaser les commits de notre branche en commençant à la référence spécifiée
            
REFLOG
git reflog
              Afficher l'historique des changements de références pour HEAD.
                
              Pour afficher autre chose que l'historique sur HEAD, rajouter  <pointeur>
              
              Exemple:  git reflog main va nous montrer tous les changements de référence pour la branche main.
              yes
              
REMOTE
git remote
              Voir le label des dépôts distants liés à notre dépôt local.

              Pour voir les url, rajouter -v.
            
git remote add <label><repo-url>
              Lier un dépôt distant avec un dépôt local.

              La plupart du temps origin sera utilisé comme label. On peut utiliser n'importe quel nom à la place c'est juste une convention. Git nous facilitera la tâche sur certaines commandes si on met origin.

              Quand on clone un dépôt distant, le label associé à l'url du dépôt cloné sera nommé origin automatiquement.
              
              Si on a pas les droits sur le dépôt distant, la convention est de nommer le label upstream Lors d'un fork par exemple, pour contribuer à des projets externes.
              
git remote rename <label> <nouveau-label>
              Renommer le label d'un dépôt distant.
            
git remote remove <label>
              Supprimer une liaison avec un dépôt distant.
            
RESET
git reset <commit>
              Déplacer HEAD sur une référence en préservant les modifications effectuées (stage ou non) dans le répertoire de travail.

              Si on ne veut pas conserver les modifications, rajouter --hard. Cependant les fichiers non suivis ne seront pas supprimés.
              Voir #GIT CLEAN
            
RESTORE
git restore <fichier(s)>
              Restaurer le contenu d'un ou plusieurs fichier à l'état dans lequel ils sont sur HEAD.
            
git restore --source <ref> <fichier(s)>
              Restaurer le contenu d'un ou plusieurs fichier dans le répertoire de travail en fonction de la référence spécifiée.

              Ne modifie pas l'historique des commits.
            
git restore --staged <fichier(s)>
              Retirer un ou plusieurs fichier stage.
            
REVERT
git revert <ref>
              Effectuer un nouveau commit qui ne contiendra pas les modifications induites par le commit référencé, sans supprimer ce dernier.
            
git revert <commit-b> <commit-a>
              Même procédure mais va répéter l'opération sur tous les autres commits ciblés. Pour chaque commit parcouru, un nouveau sera fait.

              Pour ne pas commit les modifications, ajouter --no-commit
            
STASH
git stash
              Retirer les modifications effectuées sur les fichiers suivis (stage ou pas) et les ajoute au stash.

              Pour y ajouter également les fichiers non suivis, ajouter -u.
              Pour ajouter un nom à la sauvegarde, rajouter -m "<nom>"
            
git stash list
              Voir la liste des sauvegardes faites dans le stash avec leur id.
            
git stash pop
              Appliquer le contenu de la dernière sauvegarde présente dans le stash sur notre répertoire de travail.

              Pour appliquer une autre sauvegarde que la dernière, indiquer son id.

              La sauvegarde sera ensuite supprimée du stash.
            
git stash apply
              Même chose que pop sauf que la sauvegarde sera conservée dans le stash.
            
git stash drop <id>
              Supprimer la sauvegarde avec l'id pointée du stash.
            
git stash clear
              Supprimer toutes les sauvegardes présentes dans le stash.
            
git stash show <id>
              Liste les fichiers modifés dans une sauvegarde.

              Pour afficher un diff, rajouter -p. Si on ne renseigne pas de numéro, la dernière sauvegarde sera choisie.
            
SWITCH
git switch <branche>
              Changer de branche.
            
git switch -c <branche>
              	Créer une branche et basculer sur celle-ci.
            
git switch -
            Revenir sur la branche précédente.
          
TAG
git tag
                Lister les tags.
                
git tag -l "<pattern>"
                Lister les tags selon un pattern donné.

                Exemple: git tag -l "16*" Va récupérer tous les tags commençants par 16.
                
                Plus d'infos sur les patterns: tldp.org 
              
git tag <tag>
                Créer un tag léger référençant HEAD.

                Un tag léger représente un tag comportant seulement un nom.

                Pour tout ce qui concerne le push des tags sur un dépôt distant, voir ici : #PUSH DES TAGS
                
git tag -a <tag>
                Créer un tag annoté référençant HEAD.

                Un tag annoté contiendra en plus du nom un message, la date de création et les informations de l'auteur.
                Ces informations seront visible via un git show <tag>.

                Une fois la commande rentrée, une nouvelle fenêtre s'ouvrira pour nous inviter à saisir un message. 
                
                Si on veut directement saisir le message sans passer par cette étape, ajouter -m "<message>"
                
git tag <tag> <ref>
                Créer un tag sur la référence spécifiée.

                Reprends le même principe que les commandes au dessus, mais pour une autre référence que HEAD.

                On peut toujours rajouter des options.
                
                Exemple: git tag -a v1.0.0 552c380 -m "first major release" 
                screenshot d'un git log sur vscode qui montre un tag assigné au commit 552c380
                
git tag -f <tag>
                Remplacer un tag existant.

                Si on veut également référencer un autre commit, préciser <ref>
              
git tag -d <tag>
                Supprimer un tag.
                
                Pour tout ce qui concerne la suppression d'un tag d'un dépôt distant, voir ici : #SUPPRIMER LE TAG DU DEPOT DISTANT
              
AUTRES
git clean -f -d
                Supprimer les fichiers et dossiers non suivis. 

                Par défaut si on ne passe aucun argument, la commande refusera de s'éxécuter.

                Pour lister les fichiers qui seront supprimés sans passer à l'action, remplacer -f par -n
              

PLUS

MERGE FAST FORWARD

MERGE COMMIT

REBASE

UTILISER ~ ET ^ pour pointer un commit

Supprimer le(s) fichier(s) et dossier(s) du dépôt distant en les conservant localement.

          Parfois on push sur un dépôt distant sans le vouloir des fichiers qui ne devraient pas l'être. On en a besoin en local mais on ne veut pas qu'ils soient présents sur un dépôt distant.

          1: git rm -r --cached <élément(s)>
          2: git commit -m "<message>"
          3: git push origin
        

GÉRER LES PUSHS FORCÉS

          Lors d'une tentative de push, si la branche distante n'est pas en mesure de faire un fast-forward pour rattraper notre commit, le push échouera. Dans la majorité des cas, ça sera car un ou plusieurs commits ont été effectués sur celle-ci et qu'on ne les possède pas en local. Il suffira donc de faire un git pull, qui aura pour effet de télécharger les mises à jour, et d'effectuer un merge (ou un rebase si on rajoute --rebase). Ensuite nous pourrons push.

          Certaines situations peuvent nécessiter de forcer un push. Si on décide de rebase des commits déjà présents sur un dépôt distant, ça va en créer de nouveaux, supprimer les anciens de notre branche locale, mais pas de la branche distante. Pour pallier à ça, on peut forcer le push avec -f ou --force. Cela aura pour effet d'écraser les commits présents sur la branche distante par ceux en local. Si on est seul à travailler sur notre branche et qu'on est sûr que personne d'autre va interagir dessus ça peut être une solution.  

          Dans le cas où plusieurs personnes travailleraient sur cette branche, utiliser --force serait risqué car on pourrait écraser des commits effectués par des collègues en pensant que la seule raison du refus de push est le rebase qu'on a effectué.
          
          Une solution plus douce existe : --force-with-lease. Cette commande va dans un premier temps comparer la référence du dernier commit effectué sur la branche du dépôt distant, et la comparer avec la dernière référence de la branche distante que l'on possède. Si par exemple la branche distante feature a pour dernier commit af43d00, et qu'en local, notre origin/feature pointe sur un commit différent, cela voudrait dire que la branche distante à été mise à jour entre temps. Le push avec --force-with-lease ne sera pas effectué et on sera invité à faire un pull pour récupérer les dernières mises à jour avant de d'essayer à nouveau. Un --force aurait permis de push et aurait écrasé le commit af43d00 ainsi que tout ceux n'ayant pas été fetch.
          
          Cette technique comporte aussi une faille dans le cas où la personne aurait fetch la branche distante avant de push avec --force-with-lease. Dans ce cas git ne verra pas de différences et on pourra quand même écraser le travail de notre collègue.