Introduction à Git

Information

  • Auteurs : Mathieu Loiseau, LIDILEM, Univ. Grenoble Alpes, doc. adapté par Philippe Dessus, Espé & LaRAC, Univ. Grenoble Alpes.
  • Date de création : Janvier 2019.
  • Date de modification : 25 août 2020.
  • Statut du document : Terminé.
  • Résumé : Ce document explique l’essentiel du fonctionnement du système Git, qui se retrouve dans GitHub ou GitLab, qui est à la base du serveur Sphinx de ReFlexPro. Il contient aussi quelques travaux pratiques pour s’initier à son maniement. Si la lecture de ce document n’est pas absolument nécessaire pour avoir une utilisation basique du serveur, elle apportera une bonne connaissance des fonctions et mécanismes de Git.
  • Licence : Document placé sous licence Creative Commons : BY-NC-SA.
  • Voir aussi : Le Document gitlab-rtd est un tutoriel pour comprendre le fonctionnement des serveurs sur lesquels ces documents sont produits.

Introduction

Le présent document vise à montrer en contexte des fonctionnalités de base de Git, en les intégrant dans la pratique — de manière un peu artificielle, certes... Un premier panorama des commandes de git peut être trouvé ici https://try.github.io/. Beaucoup d’informations proviennent de https://www.atlassian.com/git/tutorials/.

Conventions : Dans le document suivant, les lignes de commande shell seront indiqués de la manière suivante (avec les mots-clés notés ainsi). Des chevrons seront utilisés pour différencier les paramètres où vous pouvez mettre la valeur de votre choix de ceux qui ont une sémantique propre (comme des noms d’utilisateur, de fichier, de répertoire). Il n’est pas opportun de recopier les chevrons en question.

Exemple : Alain Connu, pour exécuter la commande git config user.name "<nom>", saisira git config user.name "Alain Connu".

1. Débuter avec Git

Git est un logiciel open source et peut être obtenu ici : http://git-scm.com/downloads. Il permet de gérer les versions et évolutions de code source (et par extension de tout fichier texte). Pour ce faire, pour chaque modification significative du code (ajout de fonctionnalités, correction de bugs, etc.), on pourra faire un commit, c’est-à-dire sauvegarder une version du code. Git stocke les versions successives d’un dossier. Une fois « surveillé » par Git, un dossier est un repository ou « repo ». En français on parlera de « dépôt ». Git permet également de travailler à plusieurs. Afin de savoir qui fait quoi, Git permet de stocker les informations à apposer à chaque commit de l’utilisateur.

  • git config user.name "<nom>" : tous les commits effectués sur ce dépôt sont crédités à l’utilisateur appelé <nom> ;
  • git config --global user.name "<nom>" : tous les commits effectués à partir de ce compte utilisateur (quel que soit le dépôt) sont crédités à l’utilisateur appelé <nom> ;
  • git config --global user.email "<email>" : le courriel de l’utilisateur est <email> ;

Exercice d’application

Note : cet exercice n’est pas utile dans la perspective d’une utilisation avec Sphinx, puisque l’adresse courriel aura déjà été configurée par l’administrateur vous invitant sur la plate-forme.

Nous allons voir ici quelques uns des effets de ces commandes. Cet exercice et les suivants se réalise via un terminal, mais il faut savoir qu’il existe des logiciels clients Git (tels que Git Desktop), et qu’on peut aussi réaliser la plupart des commandes via le serveur Git en ligne ; il existe même des logiciels de traitement de texte intégrant les commandes Git (Netbeans).

  1. Installer Git ;
  2. Définir son nom pour l’usage de git sur la machine utilisée git config --global user.name "John Doe" ;
  3. Dans le dossier utilisateur (sous Linux C:\Users\NomDUtilisateur sous Windows), ouvrir le fichier .gitconfig. Que remarquez-vous ? (Note : Le nom de l’utilisateur est indiqué.) ;
  4. Modifier l’adresse de courrier électronique associée à l’utilisateur git config --global user.email ;
  5. Que s’est-il passé dans le fichier de configuration ? (Note : L’adresse e-mail a été ajoutée.).

Beaucoup d’autres choses peuvent être configurées, du logiciel utilisé pour éditer les fichiers à celui pour traiter les cas de conflits entre les versions. En effet, il peut arriver que deux versions entrent en conflit, dans ce cas l’utilisateur devra décider de la version à conserver. Plutôt que de manipuler ces différentes version à la main (Git annote le code entrant en conflit) un logiciel de comparaison de fichiers peut être utilisé. Voir par exemple :

2. Créer un dossier un dépôt Git

Pour créer un dépôt Git vous pouvez utiliser le Terminal pour deux possibilités :

  1. prendre n’importe quel répertoire de votre ordinateur et l’initialiser en tapant git init si vous êtes dans le dossier ou git init <dossier> ;
  2. cloner un dépôt Git (c’est-à-dire, recopier à l’identique un dépôt distant) existant avec git clone <dépôt> <directory> (si <directory> n’est pas spécifié, c’est dans le répertoire courant que le dépôt sera cloné).

Soit utiliser l’interface web de Git (exemple donné avec GitLab) :

  • cliquer sur le bouton “Projects“ : la liste des projets existants s’affiche ;
  • cliquer ensuite sur le bouton vert “New Project“.

Ensuite, deux possibilités existent, identiques aux 2 précédentes : soit on veut téléverser dans ce projet un répertoire existant sur son ordinateur :

cd <répertoire_existant> git init git remote add origin <http://espe-gitlab-reflexpro.u-ga.fr/pdessus/nom_de_projet.git> git add . git commit -m "Initial commit" git push -u origin master

Soit on veut cloner un dépôt existant :

cd <dépôt_existant> git remote rename origin old-origin git remote add origin <http://espe-gitlab-reflexpro.u-ga.fr/pdessus/nom_de_projet.git> git push -u origin --all git push -u origin –tags`

Exercice d’application

Pour l’exercice suivant vous allez vous contenter de créer un dossier (en ligne de commande) dans un dossier existant. Vous ferez ensuite de ce dossier votre dépôt Git.

  1. Ouvrir la console.
  2. Se déplacer jusqu’à votre dossier de travail en utilisant ls et cd (ou dir et cd sous Windows).
  3. Créer un dossier au nom de votre projet.
  4. Aller dans le dossier ainsi créé.
  5. Faire de ce dossier un dépôt Git. (*Note : En étant dans le bon dossier, il suffit de saisir : git init).

3. Effectuer un “commit

Le flux de travail de base de Git consiste en le fait d’effectuer des modifications puis de les grouper en ensemble cohérent avant de les stocker dans un état du code. On appelle l’action de créer une version du code un commit.

  • La (sous-)commande add permet d’ajouter le ou les fichiers ainsi sélectionnés au prochain commit :
    • git add <fichier> : ajoute <fichier> au prochain commit ;
    • git add <dossier> : ajoute tout le contenu de <dossier> au prochain commit ;
    • git add : ajoute tous les changements au prochain commit ;
    • git add --all <fichier> : ajoute tous les changements à <fichier> (y compris la suppression) pour le prochain commit ;
    • git reset <fichier> : retirer les modifications à <fichier> de la sélection pour le prochain commit.
    • git status : permet d’avoir la liste des fichiers modifiés et leur situation par rapport au prochain commit ;
    • git log : permet d’avoir la liste des commits pour la branche courante ;
  • La (sous-)commande commit permet de créer une nouvelle version du code (pour toujours bien savoir ce qu’on fait, il est conseillé d’utiliser git status avant tout commit) :
    • git commit : ouvre un éditeur de texte pour spécifier les informations du commit, qui est effectué à la fermeture de l’éditeur de texte ;
    • git commit -m "<message>" : effectue le commit avec comme informations <message> ;
    • git commit -a : ajoute au commit suivant toutes les modifications effectuées sur des fichiers préalablement inclus dans un commit (les créations de fichiers ne sont pas ajoutées au commit) ;
    • git commit --amend : met à jour le dernier commit avec les changements sélectionnés. Attention : cette commande est à utiliser avec parcimonie, surtout quand vous avez plusieurs dépôts pour le même projet. git commit --amend « réécrit l’historique », et ne doit être utilisé que si le commit précédent n’a pas été publié ou utilisé par ailleurs.

Exercice d’application

  1. Dans le dépôt, créer un fichier texte appelé <README.md>.
  2. Dans ce fichier indiquer le nom de votre projet en titre. Vous pouvez utiliser pour cela la syntaxe Markdown (*Note : pour indiquer le titre d’un projet en titre du document <README.md> : # Titre du document.
  3. Toujours dans le dépôt, créer un fichier texte appelé LICENSE.
  4. Ajouter dans ce fichier, le contenu de la licence MIT, que vous copierez et collerez (http://opensource.org/licenses/MIT).
  5. Exécuter la commande git status. Quelle est la situation ? (Note : Aucun des deux fichiers créés n’est « suivi » (ajouté à la liste des modification pour le prochain commit).

16. Préparer un commit pour stocker dans une nouvelle version l’ajout de la licence, puis regarder le statut. git add LICENSE git status (Note : La création de LICENCE est ajoutée pour le prochain commit). 17. Effectuer le commit. git commit -m "ajout de licence" 18. Ajouter une section contributeurs dans votre fichier <README.md>, y inclure votre nom (Note : Avec la syntaxe Markdown, une possibilité, écrire)

## Contributors
* Alain Connu
  1. Effectuer un commit pour cette modification git commit -m "ajout du README"

20. Vous avez oublié d’ajouter vos informations de contact : mettre à jour le <README> et amendez le commit précédent pour qu’il intègre votre modification. (Pour bien voir ce qu’il se passe, vous pouvez utiliser git status et git log). (Note : Modification du texte : <Prénom Nom> -> <Prénom Nom <prenom.nom@monmail.org>> git commit --amend -m "ajout du README")

4 Gérer des branches

Git permet également d’expérimenter, de faire des tests sans affecter le code stable. Pour ce faire, on va avoir recours à ce que l’on appelle des « branches », qui permettront de scinder le projet en différente version. Dans la Figure 1, 4 branches sont représentées simultanément (il est à noté qu’elles sont nommées).

images/images/git-branches.png

Figure 1 – Représentation graphique (gitg) de différentes branches d’un projet.

  • git branch : lister toutes les branches du dépôt ;
  • git branch <nomBranche> : créer la branche <nomBranche> (pas d’espace dans les noms de branche) ;
  • git checkout <nomBranche> passer sur la branche <nomBranche> (elle doit exister : git checkout -b <nomBranche> permet de basculer sur la branche <nomBranche>, après l’avoir créée si elle n’existait pas) (Note : On peut également s’en servir pour voir un commit passé. Chaque commit a un identifiant unique (accessible avec git log), qui peut être passé en paramètre de ``git checkout`.) ;
  • git merge <nomDUneBrancheNonManipulée> : Fusionne la branche courante avec le contenu de la branche <nomDUneBrancheNonManipulée>;

NB : Il n’est pas possible de changer de branche tant que toutes les modifications n’ont pas été, soit annulées soit « commitées ». Pour traiter ce genre de problématique la commande git stash (description) existe, mais dépasse le cadre de ce document. Il est bon de savoir qu’elle existe, malgré tout. De plus, fusionner des branches, peut créer des conflits, dans ce cas, il peut être bien pratique d’avoir un outil de fusion (merge tool) correctement configuré (cf. 1. Débuter avec Git).

Exercice d’application

Note : Un Document aussi court ne permet pas de montrer à quel point c’est pratique, on se contentera ici de montrer comment ça marche...

  1. Comment s’appelle la branche principale par défaut ? Comment l’avez-vous trouvée ? (*Note : La branche principale s’appelle <master> par défaut. Dans votre projet « monobranche », vous l’obtenez en tapant : git branch qui renverra :
_images/git-branch.png

22. Créer une branche <testInstall> et l’afficher (vérifier que vous êtes bien sur la bonne branche avec git branch) git branch testInstall git checkout testInstall ou bien git checkout -b testInstall

  1. Une fois dans la branche « testInstall », créer un fichier <INSTALL.md>, qui contiendra quelques informations (du genre « nécessite un serveur Apache avec php 5 »). Vous en profiterez pour ajouter à <README.md> un paragraphe « install » indiquant de se référer au document que vous venez de créer.
  2. « Commiter » ces changements sur la branche <testInstall>.
  3. Retourner effectivement sur la branche master. Que remarquez-vous ? (Note : Le fichier <INSTALL.md> disparait quand on passe sur la branche master).
  4. Vérifier que vous n’avez rien perdu en retournant sur la branche testInstall. (Note: C’est bon, il revient, comme de rien...).
  5. Dans la branche <master>, modifier le fichier <README.md>, pour y inclure une section « Install ». Et faire un commit des changements.
  6. Passer d’une branche à l’autre pour vérifier que <README.md> est effectivement différent selon la branche.
  7. Finalement, cela vous semble préférable d’avoir un fichier séparé pour l’installation, nous allons récupérer les modification faites dans la branche testInstall et les insérer dans la branche master. Se mettre dans la branche master et appeler la commande merge avec la branche testInstall. Que se passe-t-il? (Note : La fusion a échoué, du fait d’un conflit...).
  8. Pour corriger ce problème, il va falloir résoudre le conflit manuellement en modifiant <README.md>, avant de l’ajouter aux modifications à venir, puis faire le commit. (Note : L’arborescence réalisée dans ce TD ressemblera à la Figure 2.)
_images/git-exo.png

Figure 2 – Représentation graphique du projet réalisé jusqu’à la fin de la Section 4.

5 Travailler à plusieurs avec Git

Les manipulations effectuées ici sont possibles directement de l’interface GitLab (pour le projet ReFlexPro). Il est nécessaire d’avoir été déclaré comme utilisateur par l’administrateur du serveur.

5.1 Gestion de dépôt distant

Les commandes données ci-dessous peuvent être approfondies dans le document : Les bases de Git : Travailler avec des dépôts distants

  • git remote -v : liste les dépôts distants ;
  • git remote add <nomDepotDistant> <urlDepot> : ajoute le dépôt distant <urlDepot> et lui donne le nom <nomDepotDistant> (court si possible, il sera réutilisé, et Git permet de renommer un dépôt distant avec git remote rename <ancienNom> <nouveauNom> ;
  • git fetch <nomDepotDistant> : récupérer le contenu du dépôt distant (les branches obtenues peuvent alors être fusionées avec la commande merge (cf. 4 Gérer des branches) ;
_images/Gitlab-new_project.png _images/Gitlab-collaborators.png

Figure 3 – Interface de création d’un dépôt sur Gitlab (cf. bouton « New project »). Ajout d’un collaborateur à un dépôt (settings -> members).

  • git pull <nomDepotDistant> <brancheARecuperer> : récupére la branche <brancheARecuperer> du dépôt distant <nomDepotDistant> et la fusionne avec la branche courante.

Le paramètre <brancheARecuperer> est optionnel, s’il n’est pas spécifié, les fusions sont faites en fonction des paramètres par défaut. En général, on créera en premier lieu le dépôt en ligne avant de le cloner sur sa machine. Ce faisant des associations par défaut sont faites automatiquement entre les branches ainsi créées. Mais si l’on veut définir manuellement ces associations, voir ce fil de discussion <https://stackoverflow.com/questions/4847101/git-which-is-the-default-configured-remote-for-branch#answer-4847136>`_` ; * git push <nomDepotDistant> <nomBranche> : ajoute à la branche <nomBranche> du dépôt distant <nomDepotDistant> les modifications nouvelles de la branche <nomBranche> du dépôt local.

5.2 Exercice d’application

Dans cet exercice, deux rôles (A et B) doivent être joués. Tout l’exercice peut être fait indépendamment (néanmoins de manière synchrone). À partir de la question 36, A peut assister B pour ses tâches et vice-versa, pour bien comprendre ce qui se passe.

  1. S’assurer que tout le monde est collaborateur du dépôt de travail distant.
  2. Ajouter le dépôt distant à votre dépôt local. Pour ce faire récupérer l’url du dépôt distant à partir de sa page Github, cf. Figure 4. (Si on veut nommer le dépôt distant « proj » et que son url est https://github.com/utilisateur/depot.git, la commande sera : ``git remote add proj https://github.com/utilisateur/depot.git``).

35. Récupérer la branche master du dépôt distant et la fusionner avec la branche master locale git checkout master git pull proj master ou bien git checkout master git fetch proj git merge proj/master

  1. A envoie les modifications faites dans les questions précédentes au dépôt distant. Vérifier depuis la page github que le projet a bien évolué. git push proj master
  2. B modifie le fichier <INSTALL.md> et y ajoute une section « Pré-requis techniques » et commit ses changements ;
  3. A modifie le fichier <INSTALL.md> et y ajoute une section « Procédure d’installation » et commit ses changements ;

39. B envoie ses modifications au serveur distant. Que se passe-t-il ? Comment résoudre le problème ? (Note : En lisant bien le message d’erreur. Un message d’erreur s’affiche “error : impossible de pousser des références vers https ://github.com/utilisateur/depot.git.” Astuce : Les mises à jour ont été rejetées car la branche distante contient du travail que vous n’avez pas en local. Cela est généralement causé par un autre dépôt poussé vers la même référence. Vous pourriez intégrer d’abord les changements distants (par exemple ``git pull ...``) avant de pousser à nouveau. Voir la “Note à propos des avances rapides” dans l’aide ``git push –help`` pour plus d’information. ») Il suffit de suivre la procédure proposée. ``git pull proj master`` Puis, si nécessaire résoudre les conflits avant de faire un *commit. Et enfin : git push proj master

  1. A envoie ses modifications au serveur distant. Que se passe-t-il ? Comment résoudre le problème ? Là aussi, il est conseillé de bien lire le message d’erreur. (Note : Cf. la correction de la question 39).
  2. Que reste-t-il à faire pour que tous les dépôts (locaux et distants) aient le même contenu ? (Note : B doit récupérer l’état du dépôt distant.)