Git, gestionnaire de version décentralisée

Fonctionnement de Git

Présentation de Git

Git est un gestionnaire de version décentralisée. Il a été créé par Linus Torvarlds également créateur du noyau Linux. Ce projet est sous licence GPL et est principalement développé en C avec également un peu de Shell et de Perl, notamment pour les "hook scripts".

Git est dès à présent utilisé par de nombreux projets. Certains d'entre eux ont migré vers Git récemment. Nous pouvoir par exemple citer :

Pourquoi Git ?

A l'origine, Linus Torvarlds à développé Git pour proposer une alternative libre a un gestionnaire de version décentralisée baptisé BitKeeper. Git s'est désormais imposé dans ce domaine pour plusieurs raisons :


Grâce a git, n'importe qui est en mesure de :
Parmi ses autres avantages, nous pouvons également citer :

Structure d'un repository git

Voici les différents objets stockés dans un repository git.


Nous avons donc : Afin de mieux comprendre le fonctionnement de ces objets, voici quelques illustration de leur utilisation. Mais avant tout, il faut savoir que chaque objet dispose d'un identifiant unique, sous forme de SHA1.

Recherchons dans un premier temps un commit sur lequel fonder notre exemple. Pour cela lançons la commande git-log qui nous affiche les commits du projet, choisissons en un par son identifiant SHA1.



Une fois notre commit exemple choisit, analysons sont contenu par le biais de la commande git-cat-file avec l'option "-p". Cette commande de git est en quelque sorte une commande de bas niveau, nous permettant d'analyser le contenu brut d'un objet git.



Dans le contenu de ce commit, nous pouvons dans un premier temps remarquer une référence à un commit parent, ce qui parait plutôt logique pour un gestionnaire de version. Et enfin ce qui nous intéresse le plus, la référence tree, qui est en fait une référence sur un répertoire contenant les objets de notre commit.
Affichons maintenant les informations sur le contenu de ce tree :



Ce tree contient bien entendu des blobs (fichiers), et également d'autre trees (répertoires), comme tout bon système de fichiers. Sélectionnons l'identifiant d'un blob, et affichons son contenu, toujours par le biais de la commande git-cat-file.



Nous avons maintenant le contenu du fichier. Il s'agit en fait du contenu du fichier "ChangeLog" dans son état au moment du commit que nous avons sélectionné. Affichons maintenant le contenu actuel du fichier, pour voir si des changements ont été effectués entre temps.



Le contenu actuel du fichier est similaire au contenu lors du commit sélectionné. Comme précisé précédemment, git utilise avec une grande efficacité la compression afin de limiter au maximum la taille de ses objets, et par conséquent la taille du repository. Lors de sa création, un fichier n'est pas compressé. Cependant, git se chargera de la compression lors de transferts. L'utilisateur peut aussi choisir d'effectuer une passe de compression de son repository via la commande git-repack. Cela ne présente pas d'avantage autre que celui de réduire la consommation d'espace disque, puisque pour les transferts entre repository, la compression est utilisée par défaut, comme précisé précédemment.

Le répertoire .git

Dans le répertoire .git nous trouvons les fichiers/répertoires suivants :

Le fichier index

Le fichier index représente le prochain commit de l'utilisateur. Lorsqu'un utilisateur modifie, ou ajoute un nouveau fichier, il faut qu'il l'ajoute à l'index pour qu'il soit commité.

Pour une meilleure compréhension, voici un exemple d'utilisation du fichier d'index. Nous avons donc notre repository, sur lequel nous n'avons pas encore fait de modifications non commitées. Nous pouvons le vérifier par le biais de la commande "git-status" :

alk@macbook PackageKit % git status
# On branch master
nothing to commit (working directory clean)
       


Effectuons maintenant des modifications sur les fichiers ChangeLog et AUTHORS, et consultons le retour de la commande git-status après ces modifications.

alk@macbook PackageKit % vim ChangeLog
alk@macbook PackageKit % vim AUTHORS
alk@macbook PackageKit % git status
# On branch master
# Changed but not updated:
#   (use "git add ..." to update what will be committed)
#
#       modified:   AUTHORS
#       modified:   ChangeLog
#
no changes added to commit (use "git add" and/or "git commit -a")
       


Nous pouvons constater que git s'est bien rendu compte que les fichiers avaient été modifiés. Cependant, il prévient l'utilisateur que ces changements ne seront pas commité lors du prochain git-commit tant qu'ils n'auront pas été ajoutés à l'index.
Pour tester, ajoutons un des deux fichiers à l'index.

alk@macbook PackageKit % git add ChangeLog
alk@macbook PackageKit % git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD ..." to unstage)
#
#       modified:   ChangeLog
#
# Changed but not updated:
#   (use "git add ..." to update what will be committed)
#
#       modified:   AUTHORS
#
       


Nous avons ajouté le fichier ChangeLog à l'index. Cela signifie que tous les changements apportés à ce fichier seront commités lors du prochain git-commit, alors que ceux apportés au fichier AUTHORS (non ajouté à l'index) ne seront pas pris en compte.