Git, gestionnaire de version décentralisée
Utilisation de Git
Création d'un repository git
Il existe deux façons de créer un repository git. La première est la méthode "from scratch"
et la seconde en "clonant" un repository existant.
Pour la méthode "from scratch", il suffit d'utiliser la commande "git-init" de la manière
suivante :
- cd monprojet/
- git-init
- git-add .
- git-commit
La seconde méthode consiste a cloner un repository déjà existant.
- git-clone remote_url
Les branches
Par défaut, avec git, l'utilisateur travaille sur une branche nommée master. Une branche est
en fait un commit nommé. Pour le prouver, il suffit de consulter le contenu des fichiers de
branches.
alk@macbook PackageKit % git branch * master my_branch alk@macbook PackageKit % cat .git/refs/heads/master b2b3d9437efacc2f54ef5f92c1475735e37d1ed2 alk@macbook PackageKit % cat .git/refs/heads/my_branch 17dd94a15914a1222c7a06e51fa107b8152c7610
Nous avons ici deux branches dans notre repository : master et my_branch. On remarque bien que le contenu des fichiers de branches ne sont constitués que d'un SHA1, qui représente le dernier commit de la branche en question.

HEAD est un pointeur de branche. Il représente la branche actuelle de l'utilisateur.
alk@macbook PackageKit % cat .git/HEAD ref: refs/heads/master alk@macbook PackageKit % git checkout my_branch Switched to branch "my_branch" alk@macbook PackageKit % cat .git/HEAD ref: refs/heads/my_branch
Dans l'exemple précédent nous sommes passés à la branche my_branch. On constate bien sur le pointeur HEAD est changé.
Itération classique de travail
Voici un exemple d'itération classique de travail avec git :
- Modification du code source du projet
- Ajout des fichiers modifiés à l'index, via la commande git-add
- L'utilisateur consulte l'état de l'index via git-status
- Si les changements contenus dans l'index lui vont, alors il les commit via git-commit
- La branche courante est alors mise à jour, ainsi que le pointeur HEAD

Travail collaboratif
Le travail collaboratif de plusieurs personnes sur un même projet implique l'utilisation des branches. Il existe deux façons de réintégrer une branche dans la principale (master) :
- Le merge, qui crée un historique parallèle
- Le rebase, qui crée un historique en série
Le merge
Lors d'un merge de branches, on peut être confronté à deux situations :
- Le cas simple, sans conflit, appelé "fast-forward"
- Le cas avec conflits, qui nécessite une étape de résolution de ces derniers, puis commit des corrections
Prenons un exemple d'utilisation pour illustrer le merge.
- Créons une nouvelle branche via la commande git-checkout "git-checkout -b my_branch master" par exemple
- Effectuons des changements sur cette branche et committons les

Notre branche nous paraît stable, nous décidons alors de la merger avec la branche principale (master).
- git-checkout master pour repasser dans la branche master
- git merge my_branch merge la branch my_branch avec la branche actuelle, master dans notre cas
- git branch -d my_branch supprime la branche my_branch, devenue inutile puisque les changements ont été mergés dans la branche principale
Après ces changements, nous nous retrouvons dans cette situation :

Le rebase
Le rebase, lui, consiste à ré-écrire l'historique de la branche, de manière à ce qu'il
s'adapte à la dernière version de la branche sur laquelle on veut la merger.
Une fois l'historique ré-écrit, nous pouvons merger la branche, et aucun conflit ne peut
alors intervenir, puisque le rebase aura fait en sorte, au préalable, de s'adapter à la
dernière version de la branche destination.
Imaginons nous le cas suivant :

Nous allons utiliser le rebase pour que les commits de la branches my_branch s'adaptent à la dernière version de la branche master.
- git-rebase master my_branch lance l'opération de rebase
- Des conflits peuvent apparaître, il faut alors les corriger, ajouter les changements à l'index via git-add, puis relancer le rebase via git-rebase --continue

Nous pouvons maintenant tout simplement merger la branche my_branch dans master
- git-checkout master, on passe à la branche master
- git-merge my_branch, merge la branch. Aucun conflit possible (logique !)
