Git est couvert
Par Jean-Seb le mercredi 23 avril 2008, 21:53 - Coding - Lien permanent
Les projets prennent de l'ampleur. Les équipes
s'agrandissent.
Premier réflexe: CVS ou SVN. Un vieux truc lent et centralisé,
donc.
Intéressez-vous à Git, le gestionnaire de versions de
Linus Torvalds.
Réalisé avec les explications de Frédéric
Jolliton.
MàJ : 25 avril 2008 : corrections
mineures.
MàJ : 16 août 2009 : corrections d'erreurs et du
plan du billet.
MàJ : 17 août 2009 : ajout d'un cas plus concret
(connexion ssh directe).
MàJ : 19 août 2009 : relecture, précisions et
correction d'erreurs
CoGITons
Contrairement à CVS et SVN, Git ne repose pas sur un serveur centralisé.
Le principe de fonctionnement est celui d'un serveur de versions, soit suivre l'évolution du contenu d'une arborescence.
Git ne procède pas à un diff , l'intégralité de chaque source modifiée est sauvegardée.
Rassurez-vous, cette sauvegarde se fait dans un blob compressé, et la taille prise sur le disque augmente très lentement.
Git a été conçu comme un système de fichiers, et offre de très bonnes performances.
Comme tout serveur de données, on peut l'utiliser pour stocker tout type de fichiers. Voici une comparaison de Git avec Subversion et Mercurial.
Windows: bien aGITer avant emploi.
- Je ne traite pas de l'installation Linux, car elle ne présente pas de
problèmes.
- Les utilisateurs de Linux peuvent aller directement ici : site officiel
- Sous Windows, c'est un peu plus délicat, mais les développeurs ont quand
même pensé à vous.
- Normalement, seul Cygwin est supporté.
- Il existe cependant un projet pour le faire tourner avec MSys.
- Cet installeur contient un shell MSys avec tous les outils nécessaires.
- Rien ne vous empêche de continuer à utiliser votre propre shell, en ajoutant le path bin du shell de Git.
- L'installeur est ici :
- Lancer l'installation.
- Surtout ne cherchez pas à l'installer dans votre arborescence MSys si vous en avez déja une.
- Depuis la version 1.5.5, les fins de lignes sont converties en CRLF dans le répertoire source, et en LF dans l'arbre Git. C'est une chose bonne et souhaitable, et vous ne devriez pas chercher à changer ce comportement par défaut.
- J'ai choisi de ne pas modifier les variables d'environnement (
Use Git Bash only
), car pour ma part, j'ai modifié le path de mon MSys déja installé, pour inclure le répertoire bin de Msys-Git. - Et voila, c'est installé. Tout est linké en statique, ça prend un peu plus de 100mo. C'est mieux que les moutures précédentes qui prenaient plus de 600mo! Encore un petit effort et ça sera parfait.
- Un peu de personnalisation
- pour ceux qui ont déja un shell, ajouter ${msysgit}/bin dans le ${PATH} de celui-ci.
- modifier ${msysgit}/bin/vi , et mettre gvim à la place de l'appel de vi.
- Juste pour vérifier
~$ git --version git version 1.5.5.1015.g9d258
Configuration
- Utiliser
git configavec les clés de configuration à modifier.
- Emplacement des fichiers de configuration
- La configuration générale est stockée ici: $HOME/.gitconfig
- La configuration locale est stockée dans le répertoire du projet
- Les Unixiens ont également une config pour tous les utilisateurs du système dans /etc/gitconfig
- Une bonne idée est de donner quelques informations sur la machine et l'unité carbone qui l'utilise.
- Les deux commandes ci-dessous vont modifier $HOME/.git/config (et le créer
si il n'existe pas)
git config --global user.name "Jean Seb"git config --global user.email "johannsebaztian@finiderire.com"
- Plutôt que de lancer les commandes ci-dessus, vous pouvez éditer
directement le fichier $HOME/.gitconfig
- A titre d'exemple, voici le mien
[color] ui=auto branch=false #pas de couleur pour les commandes de visu de branche [user] name=jseb email=jseb@finiderre.com
- Pour des modifications au coup par coup,vous pouvez modifier
$VOTRE_PROJET/.git/config
- Liste des clés de configuration:
git config --help
- Liste des clés de configuration:
- Pour voir la clé de configuration global
git config --global --list
- On ne voit que la configuration globale (/etc/gitconfig et $HOME/.git/config)
- On veut tout voir (et rien payer)
git config --list
- Si nous nous trouvons dans un repository git au moment de lancer cette commande, les options de configuration du projet sont affichées, en plus de la configuration globale.
Commandes de base
- Création d'un repository Git
- se mettre dans un répertoire (peuplé ou pas), puis:
git init - par défaut, la branche créée se nomme master.
- se mettre dans un répertoire (peuplé ou pas), puis:
- Ajouter et enlever des fichiers au dépot
- ajouter les fichier avec
git add fichier(on peut utiliser des jokers) - pour ajouter tous les fichiers , utiliser un
point :
git add . - on peut enlever ce qui ne sert plus avec
git rm fichier(on peut aussi utiliser les jokers) - plutot que d'ajouter en masse puis enlever les fichiers au cas par cas, on spécifiera dans exclude les fichiers à ne pas intégrer au projet.
- ajouter les fichier avec
- Commiter
- pour voir ce qui va être commité :
git diff --cached - pour commiter les changements:
git commit
- pour voir ce qui va être commité :
- Première récupération d'un repository distant
- Git est un serveur décentralisé , on obtient donc des copies des projets.
- je prends un projet au hasard sur gitorious.org , qui est un hébergeur gratuit de repositories Git.
- pour créer le projet, utiliser clone :
git clone git://gitorious.org/interstellar/mainline.git
- Lister les modifications
- tout lister :
git log(ougit log -ppour avoir le diff complet pour chaque étape) - lister une modification particulière :
git log -p XXXXX(avec XXXX le début du SHA1 correspondant à la modif.) - il semble que
git show XXXXXXfait la même chose que la commande précédente.
- tout lister :
- Rechercher dans les fichiers
- nous disposons d'un vrai grep :
git grep [Ii]rrlicht
- nous disposons d'un vrai grep :
- Pour avoir des informations sur les commandes
git --helpvous rappelle les principales commandes.git commande --helpinvoque le man de la commande concernée dans votre navigateur.
Maintenance et suivi du dépôt
- reset : en cas de pépin
git reset --hard- à réserver aux cas difficiles (problèmes de changement de branches par exemple).
- gc : pour nettoyer et reconstruire le dépot (à faire
de temps en temps sur les gros projets)
git gc
- fsck : pour vérifier l'intégrité du dépôt
git fsck
- count-objects : pour avoir des stats sur les objets
git count-objects
Les branches
- pour voir la branche dans laquelle on se trouve:
git branch - pour créer une branche :
git branch nouvelle_branche - pour voir les branches locales:
git branch - pour voir les branches distantes (remote) :
git branch -r - pour voir toutes les branches :
git branch -a
jseb@localhost ~/toto/ $ git branch -r origin/HEAD -> origin/master origin/master origin/mmap
- La flèche
origin/HEAD -> origin/master
signifie que HEAD pointe sur origin/master
.
- pour changer de branche, utiliser checkout :
git checkout nom_branche- Voir le paragraphe suivant sur checkout pour plus de précisions.
- pour fusionner deux branches: merge
- Si on se trouve dans main et que l'on veut fusionner le contenu de
experimental :
git merge experimental
- Si on se trouve dans main et que l'on veut fusionner le contenu de
experimental :
- pour effacer une branche :
branch -d experimental- la commande précédente vérifie que les changements faits dans la branche
experimental
ont été intégrés. Pour forcer la destruction :branch -D experimental
- la commande précédente vérifie que les changements faits dans la branche
Utilisation de checkout
Changement de branche avec checkout
- Comme nous l'avons vu dans la partie sur les branches, pour changer de
branche :
git checkout nom_branche- quand on change de branche, les fichiers sont modifiés en rapport (si un fichier n'est pas utilisé dans la nouvelle branche, il disparaitra).
- un changement réussi de branche se solde par un Switched to branch
nom_de_la_branche
- pour retourner dans une branche précédente, utiliser une nouvelle fois
checkout :
git checkout ancienne_branche
Récupération d'un fichier non commité
- avec checkout, on peut récupérer la dernière version d'un
fichier (si on regrette ses modifications et qu'on n'a pas encore commité)
- Exemple: j'ai effacé par erreur foo.c , sans commiter le changement.
git checkout foo.c
Récupération d'un fichier commité
- Si on a effacé un fichier, et qu'on a commité le changement, il faut
remonter dans l'historique.
- Exemple: récupérer le fichier foo.c commité auparavant.
git log: pour compter les niveaux. On voit que le niveau 3 est le plus ancien.git checkout HEAD^3 foo.c
Récupération d'un fichier depuis une autre branche
- Reprendre le fichier toto.c depuis la branche foo (alors
que la branche active est bar)
git checkout foo toto.c
- un dépôt n'est jamais modifiable, sauf en ajout. On ne peut pas modifier un
fichier commité (il faut refaire un commit, et donc ajouter une couche).
- pour annuler un commit, le seul moyen est donc de faire soi-même les modifications inverses sur les objets, puis de commiter à nouveau.
commit , fetch , pull , push
- Le commit est local.
- Avant un commit, Git demande d'ajouter un commentaire. La première ligne est le résumé des modifications. Toutes les lignes commençant par un dièse sont ignorées, et il faut obligatoirement une ligne qui ne commence pas par un dièse.
- On peut aussi rentrer directement la description :
git commit -m "Cette fois, ça va marcher!"
- Le pull (download) permet de récupérer des modifications
distantes (fetch) et d'appliquer la fusion
(merge) des objets.
- Ci dessus,
modifications distantes
s'applique aux fichiers sur un autre ordinateur, ou sur un autre dépot du même ordinateur. - récupérer la branche master du dépôt project :
- Ci dessus,
git pull /home/toto/project master
- Le fetch est un simple download, sans la
fusion des objets (il faut faire soi-même un
git merge ...)
$~ git remote add fred /home/fred/project $~ git fetch fred $~ git log -p master..fred/master $~ git merge fred/master
- Le push (upload) permet d'envoyer des fichiers à distance. Il permet également d'envoyer des modifications dans une autre branche.
git push git://serveur.git.org/projet.git
Cas pratique avec accès direct par ssh
- C'est la mise en oeuvre la plus simple de git sur des ordinateurs
différents.
- On ne va pas utiliser de dépôt public qui servirait d'intermédiaire entre les utilisateurs, les connexions seront directes.
- L'inconvénient est qu'il faut que chaque utilisateur ait des droits d'accès sur les machines distantes.
- jseb a besoin de créer son profil dans le fichier de
config de git.
- Voici le profil minimum.
- Bien entendu, cela ne sera à faire qu'une seule fois.
$ git config --global user.email "jseb@finiderre.com" $ git config --global user.name "jseb"
- Si les commandes ont réussi, un fichier .gitconfig doit apparaître dans votre home.
- jseb copie les fichiers du projet foo
depuis le home de toto (et le projet est renommé en
foo_jseb
) :git clone ssh://username@serveur/home/toto/src/foo foo_jseb
- Notez la création d'un sous-répertoire .git qui contient
les fichiers nécessaires au bon fonctionnement de git.
- Exemple:
.git/configstockera le nom d'utilisateur distant, et la façon d'y accéder, pour les pull / push ultérieurs.
- Exemple:
- .git/config va contenir ici la chaine de connexion ssh.
- Il n'y a donc plus besoin de spécifier cette chaine par la suite, le mode d'accès devient transparent.
Cas pratique avec deux repositories publics
- L'intêret de Git est de supprimer le côté centralisé de CVS et SVN. Mais encore ?
- Dans le cas précédent, il fallait des droits d'accès sur chaque machine.
- Avec un dépot public, on supprime la nécessité d'avoir des droits spécifiques sur chaque machine.
- Soit deux utilisateurs: jseb et fred.
- Ces deux utilisateurs utilisent chacun un repository, plus deux
repositories
publics
(hébergés chez fred) pour partager leurs modifications.- Il y a donc deux dépôts privés (un chez jseb, un chez fred) et deux dépôts public (hébergés chez fred, mais ils pourraient être n'importe où).
- Les modifications de jseb et fred ne vont toucher que leurs dépôts publics respectifs (principe de décentralisation de Git, que n'ont pas SVN ou CVS). Il appartient à jseb et à fred de faire le pull qui ramènera les modifications publiques vers leur dépôt privé.
- Côté fred :
- création d'un alias vers son dépôt public :
git remote add fred git://publicgit.domaine.org/jseb.git - création d'un alias vers le dépôt public de jseb :
git remote add jseb git://publicgit.domaine.org/jseb.git - git remote add ne fait qu'ajouter un alias dans .git/config et n'a pas d'autre effet que de simplifier les opérations ultérieures.
- fred récupère les données du dépôt public (pour l'instant vide) vers son
dépôt privé :
git pull jseb - la commande précédente est équivalente à
git pull git://publicgit.domaine.org/jseb.git
- création d'un alias vers son dépôt public :
- Côté jseb :
- jseb veut envoyer les données de son dépôt irrlicht dans le repository public jseb (celui-ci a été créé sur le serveur par fred qui est l'hébergeur).
- fred a créé le dépôt public fred.git où il placera ses modifications, afin que jseb puisse y accéder
- jseb va donc créer un alias fred.git pour récupérer les
modifications de fred :
git remote add fred git://publicgit.domaine.org/jseb.git - jseb va également créer un alias jseb pour pouvoir envoyer les données modifiées vers son dépôt public.
- jseb envoie ses sources dans le dépôt public (ici, décomposé en deux temps pour la démonstration)
- 1er temps: partie
accès local
git initgit add .. Notez le point pour tout envoyer, sauf ce qui est défini dans .git/info/exclude (objets et les préfixes d'exécutables)git commit
- 2ème temps: partie
accès vers le serveur public distant
git remote add jseb git://publicgit.domaine.org/jseb.gitgit push jseb- ( note: pour un premier envoi de jseb dans la branche
master :
git push git://publicgit.domaine.org/jseb.git/ master)
- fred récupère sur son dépôt privé les modifications de jseb
git clone git://publicgit.domaine.org/jseb.git irrlicht-jseb(l'argument irrlicht-jseb est le nom à donner au répertoire)- fred fait ensuite quelques modifs dans les sources.
- jseb peut récupérer les modifications de fred
git pull fred
- le processus se répète indéfiniment jusqu'à satisfaction des deux parties, grosse fête, banquet, clameurs de liesse et couronnement des champions.
Bonus : l'interface Tk
- Pour suivre une arborescence bien compliquée, rien ne vaut un petit dessin.
- Git est livré avec deux interfaces Tcl/Tk
- gitk : interface canal historique.
- Placez vous dans un repository.
gitk- si la commande précédente ne fonctionne pas:
$~ wish $(type -p gitk) - pour voir toutes les branches :
$~ wish $(type -p gitk) --all
- git-gui : interface simplifiée pour les opérations
courantes.
- lancer
git-gui(si ça ne fonctionne pas, même remarque que pour gitk).
- lancer
Trouver un GITe
Liens divers
L'aGITé du bocal
- En anglais,
git
signifieconnard
.
- L. Torvalds dit avoir choisi le nom en assumant son côté d'incurable
égocentrique:
je nomme tous mes projets d'après ma personne. D'abord Linux, maintenant Git
.- Il ne faut donc voir aucun rapport avec le contexte qui a engendré ce projet.
- Source: quel déconneur ce Linus !
