Pourquoi Git ?

L’intérêt de Git réside dans son fonctionnement distribué et décentralisé.

Le dossier Git contient à lui tout seul l’historique du projet et peut donc être transféré à un collègue qui obtiendra tout votre travail et tout l’historique.

Les collaborateurs du projet s’échangent des versions différentes du projet et ensuite mettent à jour leur travail sur un serveur distant.

Les collaborateurs peuvent donc récupérer en fonction de leur besoin la branche qui leur convient comme le montre le schéma ci-dessous.

1- Working Directory/ Index

Le Working Directory est le répertoire de travail sur lequel on effectue les modifications. Elles doivent être intégrées à l’index afin d’être prises en compte pour le prochain commit.

L’index est un fichier contenant la liste de tous les blobs/trees présents dans les précédents commits et représente tous les fichiers qui seront enregistrés lors de la prochaine action de commit.

Le Blob(Binary Large Object) représente un fichier.

Le Tree représente un répertoire ou un dossier de votre application.

 

2- Branches

Les branches permettent d’avoir un historique non linéaire et permettent de travailler pendant un moment sur une fonctionnalité particulière sans impacter la branche origin.

Elles peuvent servir pour travailler sur des fonctions particulières mais aussi être utilisées pour garder une bonne organisation avec des branches qui correspondent aux différents environnements (master, developpement, bugfix,…).

Lorsque l’on travaille dans un cadre collaboratif, on doit définir le serveur distant ou remote.

Pour cela, il existe la ligne de commande ‘git clone’.

Voici la procédure à réaliser lorsque l’on travaille en collaboratif:

  1. Créer un lien avec le serveur distant avec ‘git clone’
  2. Création d’une branche dérivée à partir de la branche actuelle ‘git checkout -b<nom de la branche>’
  3. Faire ses modifications en local
  4. Ajouter ses modifications au fichier index, avec la commande ‘git add’
  5. Réaliser un commit qui va sauvegarder les modifications avec ‘git commit’
  6. Retourner sur la branche précédente (la branche destination) ‘git checkout <nom de la branche>’
  7. Se mettre à jour sur la branche (destination) sur laquelle on vient de se positionner en réalisant un ‘git pull’
  8. Se repositionner sur sa branche en local et faire un rebase ‘git rebase <nom de la branche’ (branche de destination)
  9. Faire un ‘git push‘ pour pousser sa branche locale sur le serveur
  10. Demander un merge request pour une validation de code
  11. Une fois le merge request accepté, on fusionne les 2 branches avec la commande ‘git merge’
  12. Régler les conflits si nécessaire
  13. Envoyer les modifications au serveur avec la commande ‘git push

3 – Modification d’un commit

Il est possible que l’on crée des commits en ayant oublié des informations.

Avec git, on peut modifier un commit existant.

Pour modifier un commit, on a soit la ligne de commande ‘git commit -amend’ ou bien la ligne de commande git commit -m ‘…’

La première ligne de commande (git commit -amend) va ajouter les modifications de l’index au commit précédent et par conséquent aucun commit ne sera créé.

Pour modifier l’historique de plusieurs commits, on a ceci:

git rebase -interactive <commit>

Avec ceci, on est plus restreint au dernier commit comme vu précédemment.

Si on veut éditer les 4 derniers commits, il faut exécuter la ligne de commande:

git rebase -interactive HEAD ~4

Le  HEAD ~4 désigne le quatrième commit ancêtre de la HEAD.

Une fois la ligne de commande exécutée, voici ce que l’on peut obtenir à l’écran :

pick 01d1124 Add unit Test

pick 6340aaa Fix css

pick ebfd367 new feature

pick 30e0ccb Changed the tagline in the binary, too. (last commit)

On a la possibilité de :

  • supprimer la ligne donc le commit
  • changer l’ordre de l’application des commits
  • remplacer pick par edit afin de pouvoir modifier le commit
  • remplacer pick par squash afin de merger le commit pour n’en créer qu’un seul
  • remplacer pick par reword pour modifier le message de commit

 

4- Revert

Le revert permet d’inverser un commit. Cette commande va annuler ce qui avait été fait au moment du commit en recréant un commit. L’historique ne va pas être modifié mais va ajouter un nouveau commit d’inversion (les lignes ajoutées seront supprimées et les fichiers supprimés seront recréés).

5- Merge et Rebase

Quand utiliser un merge ?

Comme son nom l’indique, merge réalise une fusion. On souhaite faire avancer la branche courante de sorte qu’elle incorpore le travail d’une autre branche. La branche peut par exemple représenter un sprint ou une story en méthodologie agile, ou encore un ticket d’incident (issue ou bug).

Il est alors préférable, voire impératif, que l’étendue de cette branche demeure visible dans le graphe de l’historique.

Ce sera le cas, si la branche master a avancé depuis que la branche a fusionné mais si master est restée inactive,

la branche à fusionner en est un descendant direct. Il faudra alors empêcher Git  de recourir automatiquement au fast-forward

Pour empêcher git de faire un fast-forward, on utilise la ligne de commande :

git merge –no-ff

Voici un exemple montrant la différence lorsque l’on fait le git merge et le git merge –no-ff

 

 

Quand utiliser le rebase ?

Comme son nom l’indique, rebase est là pour changer la  «base » d’une branche, c’est à dire son point de départ. Elle rejoue une série de commits à partir d’une nouvelle base de travail.

Ce besoin survient principalement quand un travail local (une série de commits) est considéré comme partant d’une base obsolète.

Voici un exemple qui contient des commits sur la branche master et d’autres provenant de la branche origin master

 

Dans le cas du merge, un commit de merge est créé (G) et l’historique ressemble à ceci:

Lorsque l’on utilise le rebase, les commits qui n’existent que sur une des branches (master) sont supprimés et ré-appliqués à la suite des commits de la branche origin master. E’ et F’ sont des nouveaux commits, c’est pour cela qu’il ne faut pas faire un rebase sur des commits qui sont déjà présents sur un dépôt partagé.

 

 

6- Reset

Lorsque l’on utilise le git reset, il faut faire attention car ceci altère l’historique, voire supprime l’historique (git reset hard).

La commande « git reset <fichier> » supprime la zone de staging ou appelée zone d’index, mais ne supprime pas les modifications qui sont faites.

La commande « git reset  » supprime tous les fichiers de la zone de staging, sans supprimer les modifications.

La commande « git reset -hard » est à utiliser avec précaution, car elle renvoie le dossier de travail au niveau du dernier commit. Toutes les modifications en local non commitées seront perdues.

La commande  « git reset <commit> –hard  » permet de revenir au commit spécifié et réinitialise la zone de staging avec le dossier de travail.

La commande reset ne devra jamais être utilisée après avoir publié (push) vos modifications.

En revanche, elle peut être utile pour nettoyer votre historique local avant de l’envoyer en ligne.

7- Git Log et Ref Log

Git Log permet de lister les commits du repository. 

Pour y accéder, on tape la ligne de commande « git lg « .

Un certain nombre d’options pratiques de git log sont à mentionner :

  • git lg –all permet d’afficher les commits de toutes les branches, avec un graphe
  • git lg –author=’xxx@xxx’ permet de filtrer les log en fonction de l’auteur
  • git lg -N limite le nombre de logs affichés aux N derniers
  • git log -p donne le patch de chaque commit

Enfin, il est possible de rechercher dans les logs avec une expression régulière pour trouver un commit donné:

git lg -E-i–grep=’regexp

Le paramètre -E permet d’utiliser, une expression régulière et le paramètre -I permet de dire que l’on est insensible à la casse.

Le git reflog affiche l’historique de position du « HEAD », ce qui permet de retrouver n’importe quel commit, y compris si plus rien ne pointe dessus.

Exemple d’un retour en arrière:

$ git reflog

32ccd84 HEAD@{0}: revert: Revert « avec dependances »

cfab469 HEAD@{1}: commit (amend): avec dependances

fd0dd8c HEAD@{2}: commit: avec dependances

a0bdf47 HEAD@{3}: rebase -i (reword): rien a voir

$ git reset –hard cfab469

HEAD is now at cfab469 avec dependances

$ git reflog

cfab469 HEAD@{0}: cfab469: updating HEAD

32ccd84 HEAD@{1}: revert: Revert « avec dependances »

cfab469 HEAD@{2}: commit (amend): avec dependances

fd0dd8c HEAD@{3}: commit: avec dependances

a0bdf47 HEAD@{4}: rebase -i (reword): rien à voir

 

On voit que le commit 32ccd84 qui n’apparaît plus dans le log continue à être référencé dans le reflog où on peut encore aller le chercher en cas de besoin.

 

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *