Pense bête sur git

  • Auteur/autrice de la publication :
  • Post category:Pense bête

Configurer git

Activer la couleur dans git:

git config --global color.diff auto
git config --global color.status auto
git config --global color.branch auto

Configurer son nom ou pseudo:

git config --global user.name "votre_pseudo"

Configurer son e-mail:

git config --global user.email moi@email.com

On peut aussi éditer le fichier de configuration de git dans ~/.gitconfig:

[color]
diff = auto
status = auto
branch = auto
[user]
name = votre_pseudo
email = moi@email.com
[alias]
ci = commit
co = checkout
st = status
br = branch

Créer un nouveau dépôt

Créer un dossier, se rendre dans ce dossier, taper la commande:

git init

Cloner un dépôt existant

git clone

Le dossier .git

Situé à la racine du projet, il contient l’historique des modifications des fichiers et la configuration git pour ce projet.

Créer un dépôt qui servira de serveur

Depuis le serveur faire :

git init --bare
ou
git clone --bare

Cela créera un dépôt qui contiendra uniquement le dossier .git représentant l’historique des changements

Se connecter en SSH au serveur

git clone ssh://user@serveurname.domain.com/path/

Connaître les fichiers que l’on a modifiés

git status ==> liste tous les fichiers qui ont changé sur le disque (ajouts, suppressions, renommages)
git diff ==> voir concrètement ce qu’on a changé
git diff src/fichier.kt ==> affiche seulement les changements d’un fichier précis

Effectuer un commit des changements

1ère solution:

git add nomfichier1 nomfichier2 ==> Ajoute les fichiers à la liste de ceux devant faire l’objet d’un commit

git commit

Si on fait un git status après un git add, on verra les fichiers ajoutés en vert

2ème solution:

git commit -a ==> commit tous les fichiers qui étaient listés dans le « git status » dans les colonnes « changes to be committed et « changed but not updated » qu’ils soient en vert ou en rouge

3ème solution:

git commit nomfichier1 nomfichier2 ==> indique lors du commit quels fichiers doivent être commités

Lorsque la commande commit est lancée, l’éditeur par défaut s’ouvre et on doit taper sur la première ligne un message qui décrit à quoi correspondent nos changements

Annuler un commit

git log ==> on voit les commit qui ont été effectués
git log -p ==> pour voir les détails des lignes qui ont été ajoutées
git log --stat ==> pour avoir un résumé plus court des commits

git commit --amend ==> modifier le dernier message de commit

git reset HEAD^ ==> annule de dernier commit et revient à l’avant-dernier

Pour indiquer à quel commit on souhaite revenir:

HEAD ==> dernier commit
HEAD^ ==> avant-dernier commit
HEAD^^ ==> avant-avant_dernier commit
HEAD~2 => avant-avant-dernier commit
d6d98923868578a7f38dea79833b56d0326fcba1 ==> indique un numéro de commit précis
d6d9892 ==> indique un numéro de commit précis (écrire les premiers chiffres est suffisant)

git reset --hard HEAD^ ==> annule le dernier commit et les changements effectués dans les fichiers

git checkout nomfichier ==> annule les modifications d’un fichier avant un commit (restaure le fichier tel qu’il était au dernier commit)
git reset HEAD -- fichier_a_supprimer ==> annuler un git add

Télécharger les nouveautés

git pull

Envoyer les commits

git push ==> envoyer mes commits

Il est conseillé de faire un git pull avant de faire un git push

Annuler un commit publié

On doit créer un nouveau commit qui effectue l’inverse des modifications

git revert 6261cc2 ==> créé un commit inverse qui annule le commit 6261cc2
git push ==> pour publier le commit d’annulation

Les branches

Les branches locales

git branch ==> liste toutes mes branches

git branch ==> créer une nouvelle branche

git checkout ==> changer de branche

Fusionner le contenu de la branche dans la branche principale master:

1) on se rend dans la branche master
git checkout master
2) fusionner les changements
git merge

Tous les commits de la branche se retrouvent maintenant dans « master »

Pour info: git pull = git fetch (télécharge les nouveaux commits) + git merge (fusionne les commits téléchargés issus de la branche du serveur dans la branche de votre ordinateur)

Supprimer une branche:

git branch -d ==> supprime la branche une fois qu’elle a été fusionné dans « master »

git branch -D ==> supprime la branche même si elle contient des changements que vous n’avez pas fusionnés

Mettre de côté le travail en cours avant de changer de branche:

Si on a des changements non commités et qu’on change de branche, les fichiers modifiés resteront comme ils étaient dans la nouvelle branche

Pour éviter cela, on tape la commande suivante:
git stash

Les fichiers modifiés seront sauvegardés et mis de côté.

On peut alors changer de branche, faire les modifications, committer, puis revenir sur la branche initiale:

git checkout master
git commit -a
git checkout

Pour récupérer les changements qu’on a mis de côté dans mabranche, taper la commande suivante:

git stash apply

Les fichiers seront alors restaurés et retrouveront donc l’état dans lequel ils étaient avant le git stash

Les branches partagées

Pour travailler à plusieurs sur une même branche

git branch -r ==> lister toutes les branches que le serveur connait

origin est le nom du serveur depuis lequel on a cloné le dépôt

Si le serveur possède une autre branche sur laquelle on veut travailler, il faut créer une copie de cette branche en local:
git branch --track branchelocale origin/brancheserveur

Ajouter ou supprimer une branche sur le serveur:

git push origin origin:refs/heads/ ==> ajouter une branche sur le serveur

git push origin :heads/ ==> supprimer une branche sur le serveur

Les remote tracking branches ne seront pas automatiquement supprimées chez les autres clients, il faut qu’ils les suppriment manuellement à l’aide de la commande suivante:

git branch -r -d origin/

Autres fonctionnalités

git tag ==> ajoute un tag sur un commit

ex: git tag v1.3 2f7c8b3428aca535fdc970feeb4c09efa33d809e

Un tag n’est pas envoyé lors d’un push, il faut préciser l’option --tags pour que ce soit le cas:

git push --tags ==> envoie les tag lors d’un push

git tag -d ==> Supprimer un tag créé

Rechercher dans les fichiers sources:

git grep "" ==> connaître les noms des fichiers qui contiennent un texte

git grep -n "" ==> connaître le numéros des lignes qui contiennent le mot qu’on recherche

Demander à git d’ignorer des fichiers:

Créer un fichier .gitignore à la racine et y indiquer le nom des fichiers à ignorer

ex:

$ cat .gitignore
project.xml
dossier/temp.txt
.tmp cache/

Faire un rebase avant de merger avec master

git merge ==> va poser master au dessus de la branche
git rebase ==> va poser la branche au dessus de master

On se met sur la branche master et on télécharge les nouveaux commit:
git checkout master
git pull

On se met sur sa branche, puis on fait le rebase, puis on met à jour la branche distante:
git checkout feature/ma_branche
git rebase master
git push --force

S’il n’y a pas de conflit, on peut merger la branche avec master

squasher ses commits

L’intérêt principal du squash de commits est de conserver un historique propre malgré les nombreux commits qui ont été faits auparavant. On va ainsi pouvoir les regrouper tous en un seul commit contenant la totalité des modifications. Notre PR sera ainsi plus simple et plus claire.

Tout d’abord, il faut déterminer le sha1 du commit à la base de notre branche. Pour cela, on utilise un git merge-base :

git merge-base ma_branche master

On effectue ensuite notre squash:

git rebase -i 12e70fef8ee24bfaa99defcaf68b29c378008380

Vous remarquerez ici qu’on ne voit pas les commits du merge de master apparaître, grâce au sha1 que l’on a récupéré précédemment ; on travaille uniquement sur les commits de notre branche.

On entre alors en mode interactif (on utilise l’éditeur de git). Les commits sont affichés du plus ancien au plus récent:

pick fbde9fd Add Readme.md
pick 70aaed5 Update Readme
pick ccf2779 Update Readme again
pick 8c706b5 Update Readme again and again

Le premier commit correspond à celui de base, celui que l’on souhaite conserver ; on laisse donc l’instruction “pick” devant. On souhaite squasher tous les commits suivants, on met donc l’instruction “squash” devant. (vous pouvez aussi utiliser l’alias “s” à la place de “squash”)

On obtient alors :

pick fbde9fd Add Readme.md
squash 70aaed5 Update Readme
squash ccf2779 Update Readme again
squash 8c706b5 Update Readme again and again

Concrètement, on dit à GIT de se baser sur le premier commit et on lui applique tous les suivants pour n’en faire qu’un seul.

Lorsque l’on valide le squash (on quitte le mode interactif), Git vas ré-appliquer les commits dans le même ordre qu’ils ont été configuré juste avant. On met alors un message de commit qui concerne le regroupement de nos commits et c’est tout.

On peut ensuite revérifier à l’aide de la commande git log que nos commits ont bien été squashés.

Il ne vous reste plus qu’a pousser vos modifications :

git push --force

Note: Pensez à bien utiliser l’option --force car le rebase doit écraser l’ancien historique des commits.
Attention, l’option –force ne doit être utilisée que sur votre propre fork !

Astuce: Si vous souhaitez faire un rebase depuis le tout premier commit de votre projet, vous devez utiliser l’option --root

Gestion des conflits

Première méthode: utiliser git mergetool

Pour commencer, taper les 3 commandes suivantes:
git config merge.tool vimdiff
git config merge.conflictstyle diff3
git config mergetool.prompt false

git config merge.tool vimdiff ==> Configurer mergetool pour utiliser l’éditeur vimdiff

git config merge.conflictstyle diff3 ==> Utiliser le style de conflit de fusion diff3 et configure l’éditeur pour afficher l’ancêtre commun BASE pendant que nous examinons quels changements sont dans LOCAL et REMOTE

La commande ci dessus produit des marqueurs de conflit comme ceci:

<<<<<<<
Changes made on the branch that is being merged into. In most cases, this is the branch that I have currently checked out (i.e. HEAD).
|||||||
The common ancestor version.
=======
Changes made on the branch that is being merged in. This is often a feature/topic branch. >>>>>>>

la partie centrale est ce à quoi ressemblait l’ancêtre commun.

git config mergetool.prompt false => Ne pas afficher avant de lancer l’outil de résolution de fusion

git mergetool --tool-help ==> Pour trouver quels éditeurs sont supportés par mergetool

Lorsqu’on exécute la commande suivante:
git mergetool

S’il y a des conflits, l’éditeur vimdiff sera affiché dans le format suivant:

+-----------------------+
| | | |
| LOCAL | BASE | REMOTE |
| | | |
+-----------------------+
| MERGED |
| |
+-----------------------+

LOCAL ==> C’est le fichier de la branche courante sur la machine qu’on utilise
BASE ==> C’est l’ancêtre commun, ce à quoi ressemblait le fichier avant les deux changements
REMOTE ==> Fichier de fusion dans notre branche, provenant d’un emplacement distant et qu’on essaye de fusionner dans la branche local
MERGED ==> Résultat de la fusion, c’est ce qui sera enregistré dans le nouveau commit

On peut naviguer parmi ces vues en utilisant ctrl+w

ctrl+w+h ==> Pour accéder directement à la vue LOCAL
ctrl+w+j ==> Pour accéder directement à la vue fusionnée (MERGED)
ctrl+w+k ==> Pour accéder directement à la vue BASE
ctrl+w+l ==> Pour accéder directement à la vue REMOTE

On peut apporter les changement en éditant manuellement la vue MERGED ou en utilisant les raccourcis Vim pour choisir le fichier qu’on garde:

:diffg RE ==> prendre le fichier REMOTE
:diffg BA ==> prendre le fichier BASE
:diffg LO ==> prendre le fichier LOCAL

:wqa ==> enregistrer et quitter vi

git commit -m "mesage_de_validation" ==> On commit les changements

git clean ==> supprimer les fichiers supplémentaires (ex: *.orig) créé par diff tool.

2ème méthode, si on veut conserver notre fichier ou bien celui avec lequel il rentre en conflit

git checkout --theirs path/file ==> Résoudre les changements en faveur de l’autre ou du dépôt principal, pour accepter l’autre version (celle du REMOTE), cela rejettera tout changement local qu’on a fait pour ce fichier (accepter leur version )

git checkout --ours path/file ==> Pour accepter notre version (celle du LOCAL), pour résoudre les changements en faveur de notre dépôt (accepter ma version)