logo telecom ipp

GIT Niveau 1: INF103

Plan de la séance:

  • concept de copie de travail, "stage" et dépôt local (.git)
  • git init: créer un dépôt local
  • git status: quel est l'état du dépôt local
  • git log: voir des infos sur les commits
  • git add: ajouter un fichier à git, ou ajouter des changements au prochain commit
  • git commit: stocker dans git une nouvelle version

Démo (par le prof dans un terminal)

  • git checkout: changer la version présente dans la copie de travail
  • git remote add: connecter un dépôt distant au dépôt local
  • git push: mettre à jour le dépôt distant en fonction du dépôt local
  • git pull: mettre à jour le dépôt local en fonction du dépôt distant
    • merge: fusion de versions
  • git clone: cloner un dépôt distant dans un dossier local
  • .gitignore: liste des fichiers que git doit ignorer

Concepts

  • Le contrôle de versions, c'est sauver des versions et les documenter
  • Ca s'applique autant à du logiciel qu'à des documents en texte (ex: latex)
  • Il y a souvent un serveur distant et une copie de travail
  • Les systèmes libres/gratuits sont : CVS, puis SVN, maintenant GIT
  • Les éléments du système GIT sont:
    • vos fichiers en cours, à savoir la copie de travail
    • un index (ou stage en anglais) contenant les changements près à être mis dans le dépôt
    • un dépôt

Utilisation

La boucle de travail de base est:

  1. Changez vos programmes
  2. Ajoutez vos changements à l'index
  3. Commit = créez une copie dans le dépôt GIT avec un message de documentation

En images, fichiers et commits

Vocabulary

Dépôt

En anglais: repository.

Ce sont les données du système de contrôle de version, c'est à dire au moins toutes les versions de tous les fichiers (ou un moyen de les reconstituer). C'est aussi toutes les informations d'auteur, de temps, de dépendance, de branches...

Un dépôt GIT peut être assez gros.

  • dépôt local:
    • sur votre machine
    • pour pouvoir travailler sans connexion
    • dans un dossier .git
    • contient toute l'information du projet; vous pouvez recréer un dépôt distant à partir d'un dépôt local
    • ne changez jamais le contenu du dossier .git !!!
  • nous verrons plus tard les dépôts distants

Commit

Un commit décrit une version comme un ensemble de changements sur au moins un fichier. Un commit peut contenir beaucoup de changements sur beaucoup de fichiers, des changements de texte, de permission, de nom, de dossier... Un commit est identifié avec un code de hashage (SHA-1).

Un commit a aussi un message le décrivant, et il est important de mettre un message le plus clair et simple et cohérent possible.

commit

Copie de travail

La copie de travail, c'est une copie de la version courante du dépôt que vous pouvez éditer et modifier. La version courante est celle marquée "HEAD".

Vous ne pouvez pas changer la version de travail si votre copie de travail est modifiée

Si votre copie de travail est modifiée, c'est à dire différente de la version courante dans git, alors vous pouvez:

  • préparer (stage) vos changements pour le prochain commit puis commit
  • supprimez vos changements et revenir à la version courante dans git
  • stash sauver vos changements dans la pile de stash et revenir à la version courante dans git

Si votre copie de travail n'est pas modifiée, alors vous pouvez:

  • changer la version courante dans la copie de travail
  • récupérer des changements dans la pile de stash

L'état de la copie de travail est affiché par git status

Configuration de base GIT

Pour vous faciliter la vie, faites, dans un terminal:

git config --global core.pager ''
git config --global core.editor nano
git config --global user.name "votre nom"
git config --global user.email "votre@email"

La première ligne concerne git log. git log utilise par défaut un éditeur simplifié nommé "less", et cela force à taper q pour sortir de l'affichage d'une liste de commits.

La deuxième ligne concerne git commit. Si vous n'utilisez pas l'option -m, alors git commit lance l'antique éditeur de texte vi. nano est un peu plus moderne et facile à utiliser.

Les deux dernières lignes simplifient les messages affichés par commit.

git init

Cette commande crée un dépot local dans le dossier courant.

Si tout va bien, il n'y a pas de message. Tout message signale une erreur et doit être lu.

git status

Cette commande donne des informations sur l'état du dépot git dans le dossier courant:

  • branche courante
  • fichiers modifiés ou non suivis par Git (en rouge)
  • fichiers modifiés dans l'index (en vert)

git add

Cette commande permet d'ajouter un fichier ou tous les fichiers d'un dossier dans l'index.

git add src/tp01/Main.java ajoute src/tp01/Main.java à l'index, c'est à dire au prochain commit.

git add src ajoute tous les fichiers dans le dossier src à l'index.

Si tout va bien, il n'y a pas de message. Tout message signale une erreur et doit être lu.

git commit

Cette commande crée un commit à partir de tous les fichiers placés dans l'index.

git commit crée un commit et ouvre un éditeur de texte pour vous forcer à écrire un message de commit.

git commit -m "message" crée un commit avec le message donné.

Si tout va bien, il n'y a pas de message. Tout message signale une erreur et doit être lu.

git log

Cette commande affiche des informations sur les précédents commits.

git log affiche tous les commits

git log --stat affiche tous les commits y compris les informations sur les fichiers inclus dans chaque commit.

Scenarios d'utilisation courante

Créer un nouveau dépôt:

  • créez un dossier et faites cd dans ce dossier
  • git init
  • créez ou copiez des fichiers dans le dossier
  • git add
  • git commit ...

Questions de base: comment faire ?

  • créer un dépôt local ? git init
  • savoir si la copie de travail est modifiée ? git status
  • ajouter un nouveau fichier à git ? git add file
  • ajouter des modifications d'un fichier au prochain commit ? git add file
  • voir des infos sur les commits ? git log
  • faire un commit sur des changements ? git commit -m "message"
  • savoir si des changements sont dans le stage ? git status et les fichiers du stage sont en vert

=> demo de comment tout ça marche en pratique

Dépôts distants

Pour échanger avec d'autres personnes/machines, you avez besoin d'accéder à leur dépôt et eux ont besoin d'accéder au vôtre (ou à une copie).

GIT vous permet de transférer tout ou partie d'un dépôt vers un autre dépôt.

Un dépôt Git peut être placé dans un serveur Git: il a alors une URL d'accès.

Scenario 2

Télécharger un logiciel libre et l'adapter:

  • git clone URL pour créer un dépôt local depuis le dépôt distant dans URL
  • git checkout BRANCH pour mettre dans la copie de travail la branche qui vous concerne
  • faites des changements, testez, git add, git commit
  • git push pour envoyer les changements sur le dépôt distant

Utilisation avancée

La boucle de travail plus large est:

  1. Pull récupérez les changements du dépôt distant (par ex: de vos collègues)
  2. Faites des modifications, testez, commit, etc... (c'est la boucle initiale)
  3. Push envoyez les nouveaux commits dans le dépôt distant

En images, dépôts et actions

GIT

Scénario 3

  • Avoir deux espaces de travail synchronisés entre maison et boulot :
    • la première fois:
      • mêmes instructions que "créer un nouveau dépôt"
      • git remote add distant URL pour ajouter URL comme dépôt distant
      • git push --set-upstream distant master pour connecter la branche locale master avec la branche distante master et envoyer l'information
      • à la maison: git clone URL
    • les fois suivantes:
      • d'un coté, faites des changements, commit et git push
      • de l'autre, git pull récupère ce qui a été poussé et fait la fusion si nécessaire
      • résolvez les conflits éventuels
      • git commit

Travailler avec les dépôts distants

  • sans un dépôt distant, vous ne pouvez pas échanger d'information par git avec une autre machine/personne
  • un dépôt distant et un dépôt local contiennent la même chose
  • si un dépôt a été créé par git init, il n'a pas de "remote"
    • pour ajouter un lien vers un dépôt distant :
      git remote add distant URL
    • pour ajouter un lien entre une branche locale et le dépôt distant:
      git push --set-upstream distant master
  • si un dépôt local est créé par git clone, un lien vers le dépôt distant existe avec le nom "origin"
  • git push envoie l'état de la branche courante vers le premier dépôt distant
  • git push remoteName envoie l'état de la branche courante vers le dépôt distant nommé remoteName
  • git fetch est l'opposé de git push, il recopie l'information de la branche distante dans la branche locale; la copie de travail n'est pas modifiée
  • git pull est la combinaison de git fetch et git merge
    • s'il y a une erreur de connexion, c'est fetch
    • s'il y a une erreur de fusion, c'est merge qui a créé un conflit que vous devez résoudre avant de continuer

Votre première fusion

Prenons un exemple:

public class Toto {
    public Toto() {}
}

Ce fichier est dans la copie de travail chez vous et au travail.

Vous ajoutez un paramètre au constructeur chez vous :

public class Toto {
    public Toto(int i) {}
}

Vous faites commit, puis push, puis vous travaillez sur autre chose pendant une semaine.

Vous êtes maintenant au travail. Vous refaites la même chose, mais un peu différemment:

public class Toto {
    public Toto(int var) {}
}

Première fusion - 2

Vous faites commit et push. GIT répond que votre dépôt local est en retard sur le dépôt distant. Ce retard est du à la modification poussée la semaine dernière. Comme le suggère GIT, vous faites git pull. Conflit!

Voici le contenu de votre fichier:

public class Toto {
<<<<<<< HEAD
    public Toto(int var) {}
=======
    public Toto(int i) {}
>>>>>>> other
}

GIT a reconnu les parties identiques, et vous montre les deux versions des parties différentes.

Pour résoudre les conflits, vous devez:

  • éditer le fichier
  • choisir l'une des deux versions ou un mix des deux
  • sauver le fichier
  • git add et git commit

Fusion

  • Fusionner des fichiers binaires ne fonctionne pas et n'a pas de sens.
  • S'il y a des changements qui concernent des parties différentes du texte, alors git sait fusionner automatiquement.
  • Il y a de bons outils graphiques pour vous assister dans le travail de fusion, utilisez celui qui vous va le mieux. J'aime la vue fusion de smartGit.
  • Il y a une version plus compliquée de merge, rebase, à éviter pour l'instant.

Clone

git clone URL

  • crée un dépôt local
  • copie toutes les données du dépôt distant URL dans le dépôt local
  • enregistre URL comme dépôt distant (remote) de nom 'origin'
  • fait un checkout de la branche 'master' dans la copie de travail

.gitignore

  • par défaut, tous les fichiers de la copie de travail seront suivis par GIT
  • suivre les binaires et les fichiers générés automatiquement n'a pas de sens
  • .gitignore contient le nom des fichiers qui ne doivent pas être suivis par GIT, un par ligne
    • *.class = ne pas suivre les fichiers avec extension .class
    • bin/ = ne pas suivre le dossier bin
    • file.txt = ne pas suivre le fichier file.txt, même si c'est du texte
  • vous pouvez mettre un .gitignore dans n'importe quel sous-dossier de la copie de travail
  • il faut suivre les fichiers .gitignore dans GIT

Recommandations

  • Créez beaucoup de petits commits cohérents
  • Faites commit quand vous vous arrêtez, même si le programme ne marche pas encore
  • Par contre, ne poussez que du code testé qui marche dans un dépôt partagé
  • Si vous avez des problèmes, regardez cette page d'aide

Cette ressource en anglais est une référence, très complète et d'accès ardu: git-scm.org

Gitlab

  • Gitlab est un outil pour une organisation, comme Telecom Paris, pour fournir des dépôts distants
  • Gitlab est un serveur Git emballé dans un serveur web: toute l'interface est dans votre navigateur
  1. Mise en place d'une connexion sécurisée
  2. Cloner un dépôt qui contient un bel exemple de merge
  3. Créer un dépôt

Gitlab connexion sécurisée

  1. Créez une paire de clefs SSH chez vous
    1. Ouvrez un terminal dans votre dossier racine (PowerShell sous Windows)
    2. Allez dans le dossier .ssh, créez le s'il n'existe pas
    3. Si vous avez déjà une paire clef publique - clef privée, vous pouvez utiliser la clef privée (fichier .pub),
    4. Sinon exécutez la commande ssh-keygen -t ed25519 et répondez aux questions
    5. Utilisez le fichier .pub pour la prochaine étape (ouvrez le dans un editeur de texte et copiez tout le contenu)
    6. Dans ce dossier .ssh, créez ou éditez le fichier config et ajoutez les lignes indiquées plus bas
  2. Mettez la clef publique dans votre compte Gitlab
    1. Connectez vous à Gitlab
    2. Tout en haut à droite cliquez sur votre icone avec la fleche pour faire apparaitre le menu et choisissez "préférences"
    3. Choisissez dans la barre de gauche "Clefs SSH"
    4. Cliquez dans la zone prévue et collez le contenu du fichier .pub
    5. Mettez un titre puis cliquez sur le bouton "ajoutez la clef"

Ajout dans le fichier config:

Host gitlab.enst.fr
  PreferredAuthentications publickey
  IdentityFile ~/.ssh/<le nom de votre clef privée>
  IdentitiesOnly yes

Gitlab connexion sécurisée 2

Testez la connexion sécurisée à Gitlab en faisant une opération git clone ou push ou pull sur un dépôt non public depuis la ligne de commande : il ne vous demandera plus votre mot de passe pour vous connecter à Gitlab

Si vous devez travailler avec plusieurs ordinateurs, il peut falloir faire cette operation sur chacun. Les ordinateurs de l'école partagent tous votre dossier racine, donc le faire sur un seul suffit. Par contre, il faudra le refaire sur votre ordinateur portable.

Il vaut mieux avoir une paire de clefs SSH différente sur chaque ordinateur. Si vous voulez utiliser la même clef, recopiez la clef privée et le fichier config, dans le dossier .ssh du nouvel ordinateur.

Demo

Cloner un dépôt pour merge

Clonez le dépôt: git@gitlab.enst.fr:slr201-git-adv/learning-merge.git

Il y a deux branches à merger dans master. Aucune des deux branches ne permet un merge automatique.

  • refac1 permet de faire un merge avec juste des choix
    • sur Complex.java, il faut choisir le coté refac1 en entier
    • sur FFT.java, il faut choisir les commentaires ET les refactorings
  • refactor rend obligatoire la retouche manuelle du code, car les modifs des deux cotés touchent les mêmes lignes.

Demo

Créer un dépôt

Gitlab, dans sa version Telecom Paris, ne vous permet pas de créer des dépôts sauf dans des groupes qu'un enseignant a créé. Pour créer un dépôt en dehors de tout groupe, faites un ticket.

Vous pouvez créer un dépôt dans le groupe Gitlab correspondant à votre groupe de TP INF103: https://gitlab.telecom-paris.fr/2021INF103/gr5tp

Demo

Attention

  • Si vous n'arrivez pas à vous connecter, demandez-moi, ça doit être résolu avant fin octobre.
  • Ne pas utiliser Gitlab pour changer des fichiers et faire des commits dans le navigateur.
  • Il y a plein de commandes compliquées et d'interfaces pour des outils autres, à ignorer.

Credits

J'utilise des images CC3 BY-NC-SA de:

Les autres cours de cette série sont:

Ce cours a été conçu par Jean-Claude Dufourd et James Eagan, et mis à disposition en Creative Commons 3, BY-NC-SA (attribution, non commercial, partage à l'identique)