Git de base
L’objectif de cette page est d’être une introduction rapide à l’utilisation de Git et non un cours détaillé sur son fonctionnement.
Dans ce document, nous utilisons Git pour créer un entrepôt ou collaborer sur un entrepôt existant. Nous nous concentrons ici sur l’utilisation basique c’est-à-dire que l’on suppose que tous les utilisateurs travaillent sur la même version de référence (dans un entrepôt central) et que les conflits (modifications en parallèle sur un même fichier) sont réduits au minimum grâce à la gestion de projet (on évite de travailler sur le même fichier). Chaque utilisateur pourra donc directement récupérer les modifications des autres et propager les siennes. L’historique de l’ensemble du développement sera conservé et commenté.
Dans ce cas d’utilisation, les seules commandes à utiliser sont celles indiquées dans le résumé ci-dessous (boite jaune).
La page Git Avancé présente des aspects plus avancés, comme le travail simultané sur des variantes du code source (branches), le contrôle de ce qui est ajouté dans l’entrepôt (pull request) ou la duplication d’un projet (fork).
Introduction
Git (http://git-scm.com/) est un logiciel de gestion de version de troisième génération. A la différence de ceux de seconde génération (comme SVN), il est décentralisé. Il n’y a pas obligatoirement d’entrepôt central qui contient seul la base de données des modifications. Il n’y a pas non plus de notion de working copies. Il n’y a que des entrepôts. Les modifications sont validées dans une base de données locale (commit local). Les entrepôts peuvent récupérer les modifications d’autre entrepôts (pull) et en envoyer à d’autres (push).
Dans un premier temps ou dans les cas simples, il est possible de choisir un fonctionnement similaire à la seconde génération (mais ce n’est qu’une possibilité) en créant un entrepôt initial que chaque développeur va cloner. Chaque développeur réalise des modifications qu’il valide localement (commit). Il peut ensuite les propager dans l’entrepôt initial (push), les modifications dans l’entrepôt initial peuvent aussi être récupérées et appliquées localement (pull).
Installation
Pour commencer à utilise git, il suffit d’installer le logiciel (un simple paquet sous linux). Les échanges entre les entrepôts se font le plus souvent au dessus de ssh (parfois http/https).
Paramétrage de ssh
Le contrôle d’accès aux entrepôt est réalisé avec les clés publiques des utilisateurs. Si ce n’est pas déjà fait, chaque utilisateur doit donc créer une paire de clés avec la commande ssh-keygen
.Il est conseillé de laisser la réponse par défaut à la première question (les clés seront réalisées en utilisant rsa, stockée dans ~/.ssh
, la clé publique sera id_rsa.pub
et la clé privée id_rsa
), la passphrase est utilisée pour sécurisé la clé privée.
Si vous disposez d’un système de gestion des entrepôts (github, redmine, …) votre clé publique peut maintenant être utilisée pour vous authentifier. Par exemple en l’ajoutant profil utilisateur.
Attention, des clés devront être disponibles sur toutes les machines que vous allez utiliser. Il faut donc soit les copier (les deux), soit en générer pour chaque machine.
Paramétrage de Git
Git a besoin au minimum de connaitre le nom et l’email à associer aux commit. Pour cela, exécutez les commandes suivantes (sur chaque machine utilisée) en changeant vos noms et email. La troisième commande définit le comportement par défaut du push.
Utilisation de base
Créer ou cloner un entrepôt
Pour utiliser un entrepôt il y a deux possibilité soit en créer un directement soit en cloner un existant.
Pour créer un entrepôt, on utilise la commande git init
:
Ici nous avons créé un répertoire vide mais il peut s’agit d’un répertoire déjà existant même si il a déjà du contenu.
Pour cloner un repository existant (dont on connait l’adresse) on utilise la commande git clone
.
Par exemple, ce projet github (https://github.com/dptinfoutln/m120192020_helloworld) possède un dépôt Git. La page d’accueil du projet indique l’adresse de l’entrepôt (dans le bouton clone) :
- en ssh pour un projet privé si votre clé à été ajoutée git@github.com:dptinfoutln/m120192020_helloworld.git.
- en http sinon https://github.com/dptinfoutln/m120192020_helloworld.git
Pour le cloner :
le répertoire sandboxm1
contient maintenant une copie de l’entrepôt.
Lors de la première connexion sur un serveur il est normal que ssh vous demande d’accepter son fingerprint (celui de github aura une autre empreinte).
The authenticity of host 'lsis.univ-tln.fr (193.49.96.32)' can't be established. RSA key fingerprint is 5f:aa:42:17:37:45:31:05:3d:a4:b0:06:fb:20:dc:82. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added 'lsis.univ-tln.fr,193.49.96.32' (RSA) to the list of known hosts.
Si vous êtes sûr que c’est le bon serveur, répondez yes.
Si la commande vous demande la passphrase,
Enter passphrase for key '/home/test/.ssh/id_rsa':
c’est bon, mais normalement, elle devrait être déjà stockée en mémoire dans l’agent ssh. Vous pouvez utiliser la commande ssh-add
pour l’y ajouter manuellement.
Si la commande vous demande un mot de passe (et non la passphrase de votre clé) c’est que vous avez mal paramétré l’accès au serveur avec votre clé publique.
Quand un entrepôt est créé avec la commande clone
, un lien vers l’entrepôt d’origine est conservé. Pour obtenir la liste des entrepôts distants associés à un entrepôt on utilise la commande git remote
.
Commandes courantes
git status
indique très précisément les changements depuis le dernier commit et conseille les commandes à utiliser. A utiliser systématiquement .git add <filename>
si le fichier dont le nom estfilename
n’est pas encore sous le contrôle de git, il est ajouté. S’il l’est déjàadd
indique d’accepter les modifications (pas encore committées). Il existe aussigit rm
etgit mv
respectivement pour indiquer une suppression ou un déplacement.git commit -m “message”
valide les modifications précédentes dans l’entrepôt local. L’option-m
indique le message décrivant le commit. Il est très utile donc obligatoire, si l’option est omise un éditeur de texte s’ouvrira avant le commit. L’option '-a’ permet d’accepter les changements dans tous les fichiers (elle évite ungit add
sur chacun), à utiliser avec prudence. L’option '-a’ n’ajoute, ni ne déplace ni ne supprime.git pull
est un raccourci pour deux commandesgit fetch
qui télécharge les changements depuis un serveur distant etgit merge
qui applique les changements en attente à l’entrepôt local.git push
propage les modifications vers un serveur distant.
L’exemple suivant illustre une utilisation classique : l’utilisateur test va créer un fichier test.txt
(echo
), le placer sous la surveillance de l’entrepôt (add
), valider l’ajout (commit
)). Notez le détail des réponses de git status
.
A ce moment, les modifications sont validées mais locales. Il est possible de consulter le journal des modifications avec git log
.
On peut vérifier ce qui a changé à distance (git remote update
puis git status
) :
Dans ce cas rien n’a changé, et l’on voit bien qu’il y a un commit à pousser.
Nous allons maintenant modifier le fichier test.txt
en ajoutant du texte (echo
), accepter la modification (add
) et la valider (commit
). Ensuite, avant de pousser les modifications sur le serveur distant (git push
), nous allons vérifier si des changement sont intervenus et éventuellement mettre à jour la copie locale (git pull
).
En résumé faire :
- une fois
git init
ougit clone
pour créer un entrepôt. git add
pour un accepter nouveau fichier ou des modifications ougit rm
ougit mv
.git remote update && git status
pour savoir ce qui a changé sur le serveur.git pull
pour récupérer et appliquer les modifications distantes.git push
pour pousser les modifications vers le serveur.
Quels fichiers versionner ?
Tous les fichiers ne doivent pas être déposé sur le système de gestion de version. Les détails sont donnés ici : http://bruno.univ-tln.fr/git/gitignore
Il est impératif de mettre en place un fichier .gitignore
(cf. ci-dessus) à la racine de votre projet AVANT le premier commit et surtout le premier push.
Naviguer dans l'historique
Comme nous l’avons déjà vu git log
permet de consulter le journal des modifications:
Nous voyons qu’à chaque commit est associé un haché (SHA-1), par exemple 53fa162ffda184e6fdf9fdaa93fc60ae8b24d58a pour le dernier commit.
Il est possible de voir ce qui s’est passé pour un commit donné :
A noter, qu’il est possible de n’utiliser qu’un préfixe du hash à condition qu’il soit non ambigu. Git est même capable de les calculer seul.
Il est aussi possible de voir ce qui a changé entre deux commit avec la commande git diff
soit en indiquant deux commit entre lesquels faire la différence soit un seul (l’état courant sera alors utilisé) :
Traitement de base des conflits
Dans cette section nous allons voir d’où viennent les conflits et comment les régler. Tous d’abord nous allons créer localement trois repositories : un central et deux clones.
Comme nous l’avons vu, un entrepôt Git contient à la fois la copie de travail et la base de données des modifications. Pour des raisons techniques, un entrepôt qui contient une copie de travail ne peut pas recevoir de push. Pour cela il faut un entrepôt bare
(sans copie de travail). Un entrepôt bare
peut être créé directement ou on peut faire un clone bare d’un entrepôt existant (seul la base de données des modifications sera clonée).
Les commandes suivantes permettent de créer un entrepôt monProjetCentral
de type bare et deux clone “Projet1” et “Projet2”.
On notera qu’ici on a cloné un entrepôt local, il aurait pu être distant cela ne change rien. On notera aussi qu’il est possible de changer le nom du répertoire contenant le clone. Nous avons donc trois entrepôts : monProjetCentral
, monProjet1
et monProjet2
. Le premier ne contient pas de copie de travail mais la base de données des changements. Les deux derniers sont des clones du premier (ils en gardent une référence), ils ont aussi chacun leur copie de travail.
Nous allons maintenant ajouter un fichier README dans monProjet1
, le pousser dans l’entrepôt central.
et mettre à jour monProjet2
.
Habituellement, il y a un cycle de add/commit/pull/push depuis monProjet1 et monProjet2. Un problème va apparaître si l’un deux tente de pousser une modification sur fichier qui a déjà été modifié.
Par exemple, on modifie le fichier README dans monProjet1 et on pousse la modification :
puis on modifie aussi README dans monProjet2 sans avoir mis à jour (donc sans faire de pull).
Nous avons modifié README à partir d’une version antérieure à celle sur le serveur et donc le push automatique n’est pas possible, il faut d’abord mettre à jour la copie locale. Dans ce cas, plusieurs situation peuvent se présenter soit les modifications peuvent être appliquée automatiquement soit il faut régler le problème manuellement.
Dans le cas le contenu du fichier en conflit est modifié par git pour indiquer les différences des versions :
Il faut éditer le fichier (ou utiliser un outils graphique de résolution de conflit) pour remettre le fichier dans un état cohérent c’est-à-dire : écraser la version locale par celle de l’entrepôt, faire le contraire ou fusionner en fonction de la situation.
Dans notre exemple, nous avons fusionné en utilisant un éditeurs de texte les modifications dans monProjet2. Puis il faut les valider, les pousser dans l’entrepôt monProjetCentral.
On peut alors éventuellement mettre à jour monProjet1.
Vous l’aurez compris traiter les conflits est en général pénible. En gérant votre projet de façon précise, essayez au maximum d’éviter de travailler sur les même fichiers pour ne pas provoquer de conflits. Cela sera d’autant plus simple que si projet est bien construit et pensé pour la maintenabilité et la réutilisabilité : force modularité et dépendance la plus faible possible entre les modules.
ScreenCast Git avec Redmine
Ce screencast présente la simplicité de la création et de l’utilisation d’un projet géré par Redmine et disposant d’un entrepôt Git.
https://www.youtube.com/watch?v=1GXIk-NxOXg
https://www.youtube.com/watch?v=fJelNt3W9rw
—- dataentry page —- type : Howto technologie_tags : Git theme_tags : VCS
~~DISCUSSION~~