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.

Nous avons un gagnant !


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.
  • 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 config avec 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


  • 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.
  • 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.
  • Commiter
    • pour voir ce qui va être commité : git diff --cached
    • pour commiter les changements: git 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 (ou git log -p pour 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 XXXXXX fait la même chose que la commande précédente.
  • Rechercher dans les fichiers
    • nous disposons d'un vrai grep : git grep [Ii]rrlicht
  • Pour avoir des informations sur les commandes
    • git --help vous rappelle les principales commandes.
    • git commande --help invoque 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
  • 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


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 :
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/config stockera le nom d'utilisateur distant, et la façon d'y accéder, pour les pull / push ultérieurs.
  • .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
  • 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 init
    • git 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.git
    • git 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).


Trouver un GITe


Liens divers


L'aGITé du bocal

  • En anglais, git signifie connard.
  • 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.