Avec les anciens systèmes de gestion de versions, l’opération standard pour obtenir des fichiers est le checkout. Vous obtenez un ensemble de fichiers correspondant à un état particulier précédemment enregistré.
Avec Git et d’autres systèmes distribués de gestion de versions, le clonage est l’opération standard. Pour obtenir des fichiers, on crée un clone du dépôt entier. En d’autres termes, il s’agit de faire un miroir du serveur central. Tout ce qui peut se faire sur le dépôt central peut être fait sur le vôtre.
Je peux imaginer faire des archives tar ou utiliser rsync pour des sauvegardes ou une synchronisation simple. Mais parfois j'édite sur mon portable, d’autres fois sur mon fixe, et les deux peuvent ne pas avoir communiqué entre temps.
Initialisez un dépôt Git et faites un commit de vos fichiers depuis une machine. Ensuite sur l’autre :
$ git clone autre.ordinateur:/chemin/vers/les/fichiers
pour créer une deuxième copie de ces fichiers et du dépôt Git.
À partir de ce moment,
$ git commit -a $ git pull autre.ordinateur:/chemin/vers/les/fichiers HEAD
ira chercher l'état des fichiers sur l’autre ordinateur pour mettre à jour celui sur lequel vous travaillez. Si récemment vous avez fait des modifications d’un même fichier en conflit entre elles, Git vous le signalera et vous devrez répéter à nouveau le commit après avoir résolu ces conflits.
Initialisez le dépôt Git de vos fichiers :
$ git init $ git add . $ git commit -m "Commit initial"
Sur le serveur central, initialisez un dépôt nu (bare dans la terminologie Git) dans un dossier quelconque :
$ mkdir proj.git $ cd proj.git $ git init --bare $ # variante en une ligne : GIT_DIR=proj.git git init
Si besoin, démarrez le démon (service) :
$ git daemon --detach # peut être tourne-t-il déjà
Pour les services d’hébergement en ligne, suivez les instructions fournies pour mettre en place le dépôt Git initialement vide. En général il s’agit de remplir un formulaire sur une page web.
Poussez votre projet vers le serveur central en utilisant :
$ git push git://serveur.central/chemin/du/proj.git HEAD
Pour obtenir les sources, un développeur saisit :
$ git clone git://serveur.central/chemin/du/proj.git
Après avoir fait des modifications, le développeur les enregistre en local :
$ git commit -a
Pour se mettre à jour par rapport à la dernière version :
$ git pull
Tout conflit lors de la fusion doit être résolu puis validé :
$ git commit -a
Pour envoyer les modifications locales vers le dépôt central :
$ git push
Si le serveur principal a de nouvelles modifications dues à d’autres développeurs, l’envoi échoue et le développeur doit se mettre à jour de la dernière version, résoudre les éventuels conflits de fusion, puis essayer à nouveau.
Un dépôt nu (bare
repository) est nommé ainsi car il n’a pas de
dossier de travail : il ne contient que des fichiers qui sont
normalement cachés dans le sous dossier .git
. En d’autres termes, il ne conserve que
l’historique d’un projet et ne contient jamais le rendu d’une
version donnée.
Un dépôt nu joue un rôle similaire à celui du serveur principal dans un système de gestion de versions centralisé : le réceptacle de vos projets. Les développeurs clonent vos projets à partir de celui-ci et y poussent les dernières modifications officielles. En général il est placé sur un serveur qui ne fait quasiment que ce travail de distribution de l’information. Le développement s’opère sur les clones de sorte que le dépôt principal peut se passer d’un dossier de travail.
Beaucoup des commandes de Git échouent sur un dépôt nu
tant que la variable d’environnement GIT_DIR
n’est pas renseignée avec le chemin
vers le dépôt ou que l’option --bare
n’est pas utilisée.
Pourquoi a-t-on introduit la commande push
(pousser ou envoyer) au lieu de se contenter
de la commande pull
(tirer ou rapatrier) plus familière ?
Premièrement, la commande pull
échoue sur un dépôt nu : il faut y utiliser la commande
fetch
dont nous parlerons plus
tard. Mais même si nous conservions un dépôt standard sur le
serveur central, y rapatrier les modifications serait peu
pratique. Nous devrions d’abord nous connecter au serveur et
donner en argument à la commande pull
l’adresse de la machine depuis laquelle
nous souhaitons rapatrier des modifications. Des pare-feux
peuvent éventuellement nous embêter, et comment faire si nous
n’avons pas d’accès shell
au
serveur ?
Quoi qu’il en soit, ce cas mis à part, nous décourageons l’envoi ( en comparaison du rapatriement ) parce que cela peut entraîner des confusions lorsque la destination possède un dossier de travail.
En résumé, pendant votre phase d’apprentissage de Git, n’utilisez l’envoi ( push ) que lorsque la destination est un dépôt nu ; sinon rapatriez ( pull ).
Vous en avez marre de la manière dont est géré un projet ? Vous pensez pouvoir faire mieux ? Dans ce cas, sur votre serveur :
$ git clone git://serveur.principal/chemin/vers/les/fichiers
Ensuite, informez tout le monde du fork de ce projet sur votre serveur.
Par la suite, vous pouvez fusionner les modifications venant du projet originel grâce à :
$ git pull
Vous voulez des archives redondantes et géographiquement distribuées, permettant de faire face à un désastre ? Si votre projet a beaucoup de développeurs, ne faites rien ! Chaque clone de votre code est de fait une sauvegarde. Non seulement de l'état actuel, mais de l’historique complet. Grâce aux empreintes cryptographiques, si le clone de quelqu’un est corrompu, il sera repéré dès qu’il tentera de communiquer avec d’autres.
Si votre projet n’est pas si populaire, trouvez autant de serveurs que possible afin d’héberger vos clones.
Le vrai paranoïaque devrait toujours noter la dernière empreinte SHA1 de 20 octets du HEAD dans un endroit sûr. Ce doit être sûr, pas privé. Par exemple, la publier dans un quotidien marcherait bien, parce qu’il est difficile de réaliser une attaque modifiant l’ensemble des exemplaires d’un journal.
Imaginons que vous souhaitiez travailler sur plusieurs
fonctionnalités en parallèle. Dans ce cas validez
(commit
) votre projet et
lancez :
$ git clone . /un/nouveau/dossier
Grâce aux liens matériels, les clones locaux sont créés plus rapidement et occupent moins de place que de simples copies.
Vous pouvez maintenant travailler simultanément sur deux
fonctionnalités indépendantes. Par exemple vous pouvez
modifier l’un des clones pendant que l’autre est en cours de
compilation. À tout moment vous pouvez valider (commit
) vos modifications puis rapatrier
(pull
) les modifications depuis
l’autre clone.
$ git pull /mon/autre/clone HEAD
Alors que vous travaillez sur un projet qui utilise un autre système de gestion de versions, Git vous manque ? Dans ce cas, initialisez un dépôt Git dans votre dossier de travail.
$ git init $ git add . $ git commit -m "Commit initial"
puis clonez-le :
$ git clone . /un/nouveau/dossier
Allez ensuite dans le nouveau dossier et travaillez plutôt là, utilisant Git comme vous le voulez. De temps à autre, quand vous voulez vous synchroniser avec les autres, rendez-vous dans le dossier de départ, synchronisez-le en utilisant l’autre système de gestion de version, puis saisissez :
$ git add . $ git commit -m "Synchro avec les autres"
Ensuite allez dans le nouveau dossier et lancez :
$ git commit -a -m "Description de mes modifications" $ git pull
La procédure pour partager vos modifications avec les autres dépend de l’autre système de gestion de versions. Le nouveau dossier contient les fichiers avec vos modifications. Lancez toute commande de l’autre système de gestion de versions nécessaire pour les envoyer au dépôt central.
Subversion, qui est peut être le meilleur système de gestion de versions centralisé est utilisé par d’innombrables projets. La commande git svn automatise la procédure ci-dessus pour les dépôts Subversion, et peut aussi être utilisée pour exporter un projet Git vers un dépôt Subversion.
Mercurial est un système de gestion de versions similaire
qui peut travailler quasiment sans heurt avec Git. Avec le
plugin hg-git
un utilisateur de
Mercurial peut, sans rien perdre, envoyer (push) vers ou
rapatrier (pull) depuis un dossier Git.
Téléchargez le plugin hg-git
avec Git :
$ git clone git://github.com/schacon/hg-git.git
ou Mercurial:
$ hg clone http://bitbucket.org/durin42/hg-git/
Malheureusement, il ne semble pas y avoir de plugin
analogue pour Git. Pour cette raison, il semble préférable
d’utiliser Git plutôt que Mercurial pour le dépôt principal.
Avec un dépôt Mercurial, il faut généralement un volontaire
qui maintienne un dépôt Git en parallèle alors que, grâce au
plugin hg-git
, un dépôt Git fait
l’affaire même pour les utilisateurs de Mercurial.
Bien que ce plugin puisse convertir un dépôt Mercurial en
un dépôt Git en le poussant dans un dépôt vide, cette tâche
est plus simple avec le script hg-fast-export-git
, disponible
via :
$ git clone git://repo.or.cz/fast-export.git
Pour faire une conversion, dans un nouveau dossier :
$ git init $ hg-fast-export.sh -r /depot/hg
ceci après avoir ajouté le script à votre $PATH
.
Nous allons rapidement évoquer Bazaar parce que c’est le système de gestion de versions distribué libre le plus populaire après Git et Mercurial.
Bazaar à l’avantage d’avoir plus de recul, étant donné qu’il est relativement jeune ; ses concepteurs ont pu tirer les leçons du passé et éviter des petits écueils historiques. De plus ses développeurs ont le souci de la portabilité et de l’interopérabilité avec les autres systèmes de gestion de versions.
Un plugin bzr-git
permet aux
utilisateurs de Bazaar de travailler avec les dépôts Git dans
une certaine mesure, et permet de le faire de manière
incrémentale, tandis que bzr-fast-export
est fait pour les
conversions uniques.
Au départ j’ai choisi Git parce que j’ai entendu qu’il gérait l’inimaginablement ingérable source du noyaux Linux. Je n’ai jamais ressenti le besoin d’en changer. Git m’a rendu de fiers services et je ne me suis toujours pas heurté à ses limites. Comme j’utilise surtout Linux, les éventuels problèmes sur d’autres plateformes n’entrent pas en ligne de compte.
De plus je préfère les programmes C et les scripts bash aux exécutables comme les scripts Pythons : il y a moins de dépendances et je suis accro aux temps d’exécution rapides.
J’ai réfléchi à la manière d’améliorer Git, allant jusqu'à écrire mes propres outils de type Git, mais uniquement à des fins de recherche. Même si j’avais terminé ce projet j’aurais tout de même continué avec Git vu que les avantages sont trop peu significatifs pour justifier l’utilisation d’un système farfelu.
Bien sur, vos besoins et envies diffèrent sûrement et vous pouvez très bien vous trouver mieux avec un autre système. Néanmoins vous ne pouvez pas faire une grosse erreur en choisissant Git.