logo telecom ipp

UE Outils

Introduction

Le but de cette UE en ligne est de vous familiariser avec les outils informatiques que vous allez devoir utiliser au cours de l’année.

Ça commence par le terminal et la ligne de commande, puis SSH et la pratique du cryptage de vos communications, puis VPN et la connexion à distance sur les machines de TP, puis le gros morceau : git et la gestion de versions et gitlab.

Cette UE est minimaliste. L’intention est de vous donner le minimum vital pour naviguer. Vous aurez des compléments plus tard dans différentes UEs.

Cette UE est prévue pour rattraper un manque d’information sur ces sujets par certains élèves. Si vous savez déjà, survolez la section.

Cette UE est autoévaluée, mais soyons clairs : comprendre ces notions est obligatoire, sans quoi vous allez souffrir pendant les années à venir.

Auteur : Jean-Claude Dufourd, Télécom Paris

Chapitre 1 : Terminal

Terminal: Histoire

A l’origine, les ordinateurs n’ont pas de terminal, clavier, écran, mais un lecteur de ruban ou cartes perforées et une imprimante. Un programme est un paquet de cartes perforées ou un ruban qu’on met dans le lecteur, et quand l’ordinateur a fini le programme précédent, il lit le prochain paquet de cartes, exécute le programme et imprime les résultats. Le système d’exploitation est extrêmement simple.

A Télécom en 1985, j’ai déposé un paquet de cartes dans un casier du centre de calcul et j’ai récupéré le rapport le lendemain.

Le clavier est apparu pour taper des commandes dont le résultat était imprimé.

Les premiers écrans ressemblent aux radars dans les vieux films noir et blanc. Ils servent plus à afficher des informations graphiques qui ne passent pas sur des imprimantes de type « machines à écrire ».

Terminal: Histoire (suite)

Puis apparaissent les premiers terminaux avec un écran alphanumérique et un clavier. C’est à cette époque que se développe le système d’exploitation qui est à la base de ce que nous utilisons aujourd’hui : Unix.

A Télécom en 1985, les chercheurs avaient déjà des claviers, des écrans, mais pas de souris. Je possédais un PC avec 640Ko de RAM, avec un disque dur de 5Mo et une souris !

Sur un écran graphique actuel, une fenêtre alphanumérique remplace l’écran cathodique d’origine, et le clavier est temporairement attaché à cette fenêtre par un clic de la souris.

Le terminal vient donc du fonctionnement d’origine des ordinateurs. Il reste un outil précieux pour ce qui est administration de l’ordinateur.

Terminal: Principe

Le principe est le même que sur un terminal d’origine : vous tapez une commande, elle est exécutée, et le résultat est affiché sur l’écran en dessous de la commande au lieu de l’imprimante.

Selon le système d’exploitation, les commandes varient. MacOS et Linux, tous les deux basés sur Unix, ont un ensemble de commandes de base très proches. Windows a un terminal DOS avec des commandes très différentes et en fait très primitives, et aussi depuis peu un terminal dit PowerShell inspiré de Linux.

Le programme qui lit les commandes que vous tapez dans le terminal s’appelle le « shell ». Il lit la commande, la vérifie, va chercher le programme à exécuter, le lance, récupère le résultat et l’affiche. Il y a malheureusement beaucoup de variantes de shell.

Avant d’aller plus loin et de vous montrer des exemples, j’ai besoin de vous parler des fichiers et du système de fichiers.

Chapitre 1.1: Fichiers

Fichiers: Disques

Un disque est un appareil permettant de stocker des données informatiques. Originellement sous forme de disques magnétiques qui tournaient dans des boites sous vide, l’appellation disque est moins pertinente aujourd’hui avec les SSD qui sont de simples mémoires.

Un disque physique est organisé en « volumes » qui ne sont rien d’autres que des zones séparées du disque physique. Les données des fichiers sont organisées d’une certaine manière, c’est-à-dire leur format (HFS+, NTFS, FAT…). Certains formats sont plus faciles à lire sur certains systèmes mais dans le principe, ils rendent tous le même service : organiser les fichiers d’un volume en dossiers et sous-dossiers (directory ou folder en anglais) et gérer l’espace libre.

Un dossier est une liste de fichiers et de sous-dossiers. Il peut y avoir beaucoup de niveaux de sous-dossiers.

Fichiers

Un fichier est un paquet de données avec des caractéristiques diverses : un type de données (texte, image), une date de création, un auteur, un type d’encodage (US, FR, JP), un format (JPEG, PNG, Word), une localisation sur le disque, c’est-à-dire dans quel volume et quel dossier.

Pour naviguer un disque et trouver un fichier, vous pouvez utiliser Finder sur MacOS, Nautilus sur Linux et Explorer sur Windows, qui sont des logiciels graphiques pour consulter le contenu d’un volume.

Nous verrons des exemples dans les vidéos sur les terminaux mais une différence importante est la façon d’écrire les dossiers :

  • Sous Windows, un dossier se définit comme C:, avec C: pour le volume et pour le dossier et sous-dossier. Notez le back-slash comme séparateur.
  • Sous MacOS et Linux, un dossier se définit comme /Volumes/Large/Media/Movies. Notez le slash comme séparateur et le volume est un dossier presque comme un autre.

Note: vos fichiers à l’école

Vous disposez d’un espace de stockage de fichiers à l’école. Cet espace est sauvegardé. Il est disponible automatiquement sur toutes les machines de TP de l’école. Quand vous êtes connecté.e.s sur une de ces machines (Linux), le dossier home est votre espace.

Vous pouvez accéder à cet espace de stockage depuis un PC en vous connectant sur \samba.enst.fr_login

Vous pouvez accéder à cet espace de stockage depuis un Mac en vous connectant sur smb:\samba.enst.fr_login

Votre machine personnelle doit être connectée sur le wifi Campus-Télécom ou utiliser le VPN (voir plus loin).

Terminal: suite

Nous avons maintenant tous les éléments pour vous montrer des exemples d’utilisation des terminaux.

Choisissez votre système d’exploitation préféré pour voir la démo.

Mac OS

Linux

Windows

Terminal: Exécuter un programme

Pour exécuter un programme, vous devez soit connaitre sa localisation sur le disque, soit juste son nom si le programme est dans le chemin d’accès.

Un programme est installé dans un dossier. Ce dossier peut être un dossier du système pour les programmes qui appartiennent au système d’exploitation. Ce dossier peut être un dossier particulier juste réservé à ce programme, surtout si ce programme a des ressources dont il a besoin. Dans ce dernier cas, l’installation du programme sur votre machine revient à créer le ou les dossiers dont ce programme a besoin sur votre machine et à y mettre toutes les ressources nécessaires, ce qui peut inclure des images, des polices, de la documentation, etc.

Le « shell » (programme qui lit vos commandes et les interprète) a un chemin d’accès où il va chercher les commandes. Le chemin d’accès est une liste de dossiers contenant des programmes. Le shell lit votre commande, isole le nom du programme, va voir dans tous les dossiers s’il trouve ce programme et le lance avec les arguments que vous avez donnés.

Voyons quelques exemples dans votre OS préféré.

Mac OS

Linux

Windows

Terminal: Très utile

Dans le terminal, vous avez un historique des commandes passées, accessible avec les touches curseur vers le haut et vers le bas. Avec les touches curseur vers la droite et vers la gauche, vous pouvez éditer une commande passée pour la modifier, puis appuyer sur retour chariot ou enter pour l’exécuter.

Toujours dans le terminal, la touche tab permet dans les shells modernes de compléter le mot courant : par exemple, vous voulez afficher un fichier texte du dossier courant dont le nom commence par a, tapez « cat a » puis appuyez sur tab qui complètera le nom du fichier s’il n’y a pas d’ambiguité.

Tout ceci a été démontré dans les vidéos précédentes, c’est rappelé ici pour insister.

Terminal: Commandes utiles

En plus de cd, pwd et ls:

  • mkdir x : créer un sous-dossier x
  • rm x : supprimer le fichier x
  • mv x y : renommer le fichier ou dossier x en y
  • rmdir x : supprimer le dossier x qui doit être vide
  • rm -r x : supprimer le dossier x et son contenu, l’argument -r signifiant “récursif”

Et en même temps, tout cela peut être fait dans l’outil graphique de consultation des fichiers de votre système d’exploitation.

Le prochain transparent montre une démo de tout cela sur Mac.

MacOS

Fichiers cachés, configuration

Il y a des fichiers qui sont « cachés ». Ce sont des fichiers qui servent à vos programmes, mais que vous n’avez normalement pas besoin de voir, sauf accident. Ce sont par exemple les fichiers dont le nom commence par un point. Pour les voir, il faut ajouter une option à ls

Terminal: difficultés

Les noms de fichier peuvent contenir des espaces. Dans ce cas, le shell prend le nom du fichier comme 2 (ou plus) noms séparés. Pour que le shell comprenne un nom de fichier avec espaces, il faut entourer le nom du fichier par des guillemets ou des apostrophes (” ou ’)

S’il manque un ” ou ’ dans une ligne, alors le shell attend le ” ou ’ manquant indéfiniment : faites controle-C pour en sortir.

. est le dossier courant, .. est le dossier parent, ~ est le dossier racine de l’utilisateur connecté

/home/dufourd/test/src est un chemin absolu, ~/test/src est le chemin équivalent relatif à mon dossier racine

cd (tout seul) me remet dans le dossier racine (sauf sur Windows)

Dans mon dossier racine, test/src est le chemin relatif équivalent au chemin absolu /home/dufourd/test/src

/home/dufourd/test/src fonctionne où que vous soyez, ~/test/src aussi, mais un chemin relatif dépend d’où vous êtes

Terminal: commandes diverses

  • date: affiche la date
  • whoami: affiche le nom du compte connecté
  • who: qui est connecté sur cette machine
  • hostname: affiche le nom de la machine
  • history: affiche l’historique des commandes shell
  • man x: affiche le manuel de la commande x
  • clear: efface le terminal
  • cat x: affiche le contenu du fichier x comme si c’était du texte (si c’est du binaire, alors ça fait n’importe quoi)
  • less x: affiche le contenu du fichier x comme si c’était du texte et page par page; espace pour avancer, et q pour sortir

Terminal: fichiers encore

En faisant ls -l vous pouvez voir les permissions des fichiers.

Pour changer les permissions: chmod <permission> <fichier>. Par exemple, changer un fichier de clef SSH qui est .rwxrwxrwx, faire chmod 700 id_ed25519

Les permissions sont: r=lecture w=écriture x=executable. Les premiers RWX sont pour l’utilisateur, puis le groupe, puis tout le monde. 700= RWX pour l’utilisateur, rien pour les autres. 777=RWX pour tout le monde. 640= RW utilisateur, R groupe, rien pour les autres. Le premier caractère des permissions est un d (pour un dossier) ou un . (pour un fichier)

Changer un fichier texte pour qu’il devienne executable: chmod +x script.sh. Faites man chmod pour connaitre les détails.

Pour savoir ce qui prend de la place sur votre compte, la commande du affiche la taille des fichiers et dossiers. Par défaut, l’unité est le bloc de 512 octets, donc ajoutez toujours l’option -k pour avoir des Ko.

  • du -k donne l’occupation du dossier courant et de tous les sous-dossiers
  • du -s -k donne juste l’occupation du dossier courant
  • du -s -k * donne l’occupation de tous les sous-dossiers (un par un)
  • ncdu est une application interactive plus sympa que du mais qui n’est pas toujours installée

Chapitre 2 : SSH

SSH: Histoire

Quand je me connecte à l’école depuis chez moi, je rentre dans un système où j’ai besoin de m’authentifier pour avoir accès à certaines données sensibles. Le moyen habituel d’authentification est le login et mot de passe. Quand je me connecte, mes informations de connexion transitent sur ma machine, sur la connexion réseau entre ma machine et celle de l’école et sur la machine de l’école. Si un pirate écoute ma machine, le réseau ou la machine de l’école, il peut se faire passer pour moi.

Je suppose que l’école est protégée contre les pirates par le travail de la DSI. Ma machine est protégée des pirates par divers logiciels. Par contre, le réseau entre chez moi et l’école est un espace que je ne contrôle pas. Il pourrait y avoir une machine qui écoute tout ce qui passe sur le réseau pour détecter ce qui ressemble à un login et mot de passe. Par exemple, il est facile de faire cela dans l’école en installant WireShark sur ma machine. Si pendant que j’écoute, quelqu’un se logge sans sécurité, je peux capturer son login et mot de passe.

SSH est un moyen de sécuriser ses communications.

SSH: Principe

Je vais laisser les explications techniques à une UE réseau future. Ce que vous avez besoin de savoir sur SSH est :

  • C’est un moyen d’établir une connexion sécurisée entre deux machines
  • Même si un écouteur reçoit tous les paquets y compris lors de la connexion initiale, il ne peut rien en faire
  • Cette sécurité est fondée sur une clef secrète qui ne doit jamais quitter votre machine et qui doit être en lecture seule pour votre compte et non lisible par les autres comptes de votre machine s’il y en a. Il ne faut pas échanger cette clef secrète même par une clef USB pour la mettre sur plusieurs machines.
  • Vous avez une clef publique, qui va avec la clef secrète, et que vous installerez sur toutes les machines où vous voulez vous connecter depuis votre machine.

SSH: Installation

Pour installer une communication SSH, il faut donc :

  • Créer une paire de clefs, clef privée et clef publique
  • Déposer la clef privée dans votre dossier .ssh avec les bonnes permissions
  • Ajouter la clef publique dans le fichier .ssh/authorized_keys sur toutes les machines où vous voulez vous connecter
  • Sur votre machine, faire ssh suivi de l’adresse de la machine cible
  • Et voilà.

SSH: Clefs

Pour créer une paire de clefs, la meilleure option est ED25519 (pas DSA, pas RSA, pas ECDSA). La clef obtenue est plus courte et beaucoup plus solide.

Lors de la création de la clef, vous avez le choix de mettre un mot de passe sur la clef privée. Je vous recommande de mettre un mot de passe, même si ce n’est pas obligatoire. Si votre machine est volée ou piratée, sans mot de passe, le pirate peut se connecter partout.

Quand vous ajoutez une clef publique dans le fichier authorized_keys, attention à ne pas ajouter de ligne vide avant ou après votre clef publique, à coller une clef publique entière et rien d’autre… Si le fichier authorized_keys n’est plus de la bonne forme, la connexion ssh ne fonctionnera plus sur cette machine.

SSH Mac

SSH Windows

SSH Linux

Commande

Dans tous les cas la commande est :

ssh-keygen -o -a 100 -t ed25519 -f .ssh/id_ed25519 -C "you@telecom-paris.fr"

Dans la vidéo, j’utilise le nom de fichier ed qui n’est pas un des noms par défaut, ce qui est moins pratique (merci à Marc pour la remarque)

Par rapport au mot de passe de la clef:

  • pour une clef utilisée pour toutes vos connexions, mettez un mot de passe!
  • pour une clef utilisée seulement pour git, alors vous pouvez vous passer de mot de passe;

N’utilisez pas putty qui génère des fichiers dans un autre format.

Lancez la commande ci-dessus directement au bon endroit, à savoir votre dossier .ssh.

SSH: Se connecter

Pour se connecter à une machine, par exemple ssh.enst.fr, il faut exécuter dans le terminal, avec nom-23 votre login ecole (il y a parfois la première lettre de votre prénom devant votre nom ou votre nom peut être abrégé) :

ssh nom-23@ssh.enst.fr

Dans ce cas, il vous demande votre mot de passe. La premiere fois, vous devez utiliser le mot de passe.

Si vous installez votre clef publique dans .ssh/authorized_keys sur la machine sur laquelle vous vous connectez (raspberry PI), alors la prochaine fois, vous pourrez faire :

ssh -i .ssh/id_ed25519 nom-23@ssh.enst.fr

Cette instruction dit à ssh d’aller chercher la clef privée dans .ssh/id_ed25529, à remplacer par le nom de votre clef privée. Dans ce cas, il ne demande pas votre mot de passe du compte et vous connecte directement. Si vous avez mis un mot de passe sur la clef privée, il vous demande votre mot de passe pour la clef.

Pour quitter une session ssh, faites logout ou tapez controle-D

SSH: Fluidifier

Il est possible de grandement fluidifier l’usage de ssh en ajoutant un fichier texte nommé config dans le dossier .ssh.

Contenu du fichier config :

Host *
  AddKeysToAgent yes
  IdentitiesOnly yes

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

Ce fichier dit:

  • de demander le mot de passe de la clef la premiere fois qu’elle est utilisée puis de la conserver dans le ssh-agent
  • pour gitlab.enst.fr, utiliser la clef privée citée

Donc au premier clone, push ou pull, ça vous demande le mot de passe, puis plus jamais jusqu’au prochain reboot de votre machine.

ForwardAgent

Pour utiliser vos clefs depuis une machine distante à laquelle vous vous connectez avec ssh, vous avez le choix:

  • de créer une paire de clefs sur cette machine distante et de refaire le process précédent
  • de configurer le ForwardAgent

Si vous ajoutez au fichier config dans votre dossier .ssh sur votre machine les lignes :

Host robotpi-XX.enst.fr
     ForwardAgent yes

Alors, quand vous êtes connecté sur robotpi-XX.enst.fr depuis votre machine configurée comme cela, alors la machine robotpi-XX.enst.fr fonctionne comme si elle était configurée en SSH comme votre machine. git clone ... ou git pull vont fonctionner comme si depuis votre machine.

Chapitre 3 : VPN

VPN

VPN: Trouver une machine de TP

Ces URLs ne sont visibles que dans l’école ou avec le VPN connecté:

  • https://dsi.wp.imt.fr/tableau-de-bord-des-services/
  • https://tp.telecom-paris.fr/

Si vous n’avez pas encore le VPN installé/connecté, prenez le temps de suivre les instructions de la DSI montrées dans le transparent précédent

VPN: Remote Desktop

Une fois connecté avec le VPN, puis ayant trouvé une machine disponible, je peux utiliser l’application Microsoft Remote Desktop (disponible sur Windows, MacOS, iOS, Android) pour me connecter sur la machine.

Sur Ubuntu Linux, ouvrez un terminal, installez Remmina :

sudo apt install remmina

Puis executez remmina après connexion au VPN de l’école, et choisissez une machine pour vous connecter.

Ajoutez .enst.fr au nom de la machine que vous trouvez sur tp.telecom-paris.fr .

VPN: Remote Desktop sur Mac

VPN: Remote Desktop sur Linux

VPN: Remote Desktop sur Windows

Attention, sous windows, la souris est décalée vers la droite (de la taille d’un bouton standard) alors que c’est OK sous linux.

VPN: Alternative SSH

Le VPN connecté fait virtuellement migrer votre machine dans l’école, ce qui peut vous empêcher de vous servir de certains services normalement accessibles depuis chez vous, mais interdits par l’école.

Une solution est d’utiliser un tunnel SSH depuis l’extérieur pour vous connecter à une machine interne à l’école, par exemple :

ssh -J dufourd@ssh.enst.fr ubuntu@labgrader.r2.enst.fr

Avec cette instruction, j’ouvre un terminal sur la machine labgrader.r2.enst.fr qui est une machine virtuelle d’INFRES, dont le port SSH n’est pas visible de l’extérieur, en passant par la machine ssh.enst.fr qui est faite pour les tunnels.

Parenthèse sur les types de connexion

Prenons un peu de recul sur tout ce que vous venez de voir.

Un terminal sur votre machine

Vous avez ouvert un terminal sur votre machine :

  • vous pouvez lancer des commandes textuelles sur votre machine
  • vous pouvez agir sur vos fichiers locaux
  • vous pouvez en parallèle du terminal lancer des applications graphiques sur votre machine, pour faire des commandes par le biais d’une interface graphique

Connexion SSH sur une autre machine

Vous avez ouvert un terminal sur votre machine, puis lancé une connexion SSH sur une autre machine

  • vous pouvez lancer des commandes textuelles sur l’autre machine
  • vous pouvez agir sur les fichiers sur l’autre machine
  • vous ne pouvez pas lancer d’application graphique sur l’autre machine, vous devez trouver les équivalents texte de toutes les commandes que vous voulez faire

Connexion “remote desktop” sur une autre machine

Vous avez lancé dans une fenêtre graphique un remote desktop: c’est comme si vous étiez sur l’autre machine, vous pouvez tout faire comme en local.

Note: vous ne pouvez pas faire cela sur une Raspberry PI, vous pouvez seulement faire une connexion SSH/terminal

Une autre solution: sshfs

Vous avez sur votre machine tout le confort d’édition auquel vous avez l’habitude.

Dans un terminal, vous n’avez que des éditeurs de texte frustes.

Pour éditer des fichiers sur votre machine à exécuter sur une autre machine, vous avez deux solutions :

  • soit vous utilisez git sur votre machine et sur l’autre machine (voir plus loin), et vous faites des suites de git pushet git pull
  • soit vous utilisez sshfs qui vous permet de partager un disque de donnée à distance : vous connectez le disque de l’autre machine à votre machine locale avec le logiciel sshfs. Les données sur Raspberry PI apparaissent alors comme si elles étaient sur une clef USB sur votre machine, vous pouvez les éditer dans votre environnement et les modifications sont visibles de suite sur la Raspberry.

sshfs : comment faire

Sur mac :

  • installez macFuse et sshfs depuis https://osxfuse.github.io/
  • créez le dossier /Volumes/distant
  • tapez: sudo sshfs username@machine:/remote/directory /Volumes/distant (machine est le nom de l’autre machine, username est le nom de l’utilisateur sur l’autre machine)
  • vous voyez alors les fichiers locaux de l’autre machine dans le dossier /Volumes/distant

sshfs : comment faire

Sur Linux :

  • installez sshfs avec sudo apt install sshfs
  • créez le dossier /media/distant
  • tapez: sudo sshfs -o allow_other,default_permissions username@machine:/remote/directory /media/distant
  • vous voyez alors les fichiers locaux de l’autre machine dans le dossier /media/distant

sshfs : comment faire

Sur Windows :

En résumé

résumé

Chapitre 4 : GIT

Git/Gitlab/Github

Git est un outil incontournable pour l’ingénieur, même non informaticien. Que ce soit pour des logiciels ou des documents issus d’une collaboration, Git s’est imposé comme la norme.

Gitlab/Github sont des serveurs Git qui gèrent le stockage, le partage entre utilisateurs, les autorisations d’accès et puis toute une couche d’outils supplémentaires qui complexifient énormément leur interface. La partie de l’interface juste pour faire du Git est “assez” simple.

Il est important de réaliser que si vous êtes bloqués en git pour quelque raison que ce soit, vous devez consacrer du temps à vous débloquer, en demandant de l’aide, en continuant à vous former, car l’impasse sur git n’est pas possible.

Git: Histoire

Git est la version la plus utilisée de logiciel de contrôle de version.

Qu’est-ce que le contrôle de version ? Il s’agit de stocker toutes les versions de tous les fichiers dans un projet, avec pour chaque version, des commentaires, dates et auteur.

GIT: Pourquoi

  • Vous travaillez en groupe et un collègue a tout cassé la dernière version et vous devez faire une démo dans une heure : en un clic, vous revenez à la version précédente qui marche
  • On vient vous voir pour un comportement qui a changé entre la v2 et la v3. Vous en êtes à la v7 et toute l’équipe a changé depuis. Vous reconstruisez la v2. Vous reconstruisez la v3. En comparant les journaux de fonctionnement, vous isolez le fichier fautif, et avec les commentaires de chaque version, vous retrouvez la raison des changements et le défaut de logique.
  • Vous avez travaillé pendant trois mois sur votre machine sans sauvegarde et votre disque crashe la veille du rendu (histoire vraie arrivée à un de mes étudiants).
  • Vous avez travaillé sur un projet seul pendant un an, vous trouvez un bug et vous n’avez aucune idée d’où ça vient. Vous testez les versions par dichotomie et vous trouvez rapidement le commit qui introduit le bug.
  • Même chose sur un projet d’équipe, et là, vous avez le nom de l’auteur du commit et vous pouvez aller lui demander.

Git est le logiciel à la mode, mais il y a eu d’autres logiciels de contrôle de version : CVS, SVN, SourceSafe, ClearCase, Mercurial, etc.

Git: Principe

Contrairement aux logiciels précédents, qui stockaient les différences entre les versions, Git stocke les versions entières. Le dépôt Git est donc un peu plus gros. Il se trouve dans un dossier .git qui est dans le dossier racine du projet. Il ne faut jamais modifier ce dossier .git ou son contenu.

Les éléments de Git sont :

  • Un dossier de travail contenant une version du projet
  • Un dossier .git qui contient le dépôt local avec toutes les versions
  • En général, un dépôt distant hébergé par un serveur du type GitLab

Les opérations courantes sont :

  • Cloner un dépôt distant : récupérer un dépôt local copie d’un dépôt distant, par exemple celui d’un logiciel libre disponible sur github,
  • Initier un dépôt dans le dossier projet pour un projet qui démarre
  • Faire des modifs sur un projet, et créer un commit en local
  • Push : Envoyer un commit local vers un dépôt distant
  • Pull : récupérer des modifs d’un collègue sous la forme de commits contenant des nouvelles versions, et peut être gérer les conflits

GIT: Installation

GIT: Transparents Git 1

GIT UE Outils

Suivent les transparents vus dans la video précédente

  • 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

Concepts

  • Il y a un dossier projet
  • Dans ce dossier il y a une copie de travail
  • Dans ce dossier, il y a un sous-dossier caché .git (dépôt local)
  • Il y a une liste ou index (ou stage en anglais) contenant les changements prêts à être mis dans le dépôt
  • Git s’applique autant à du logiciel qu’à des documents en texte (ex: latex)
  • Il y a souvent un serveur distant
  • Les systèmes libres/gratuits sont : CVS, puis SVN, maintenant GIT

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

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.

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

GIT: Exemple Initier un dépôt

GIT: Transparents Dépots distants

GIT: Transparents Dépots distants

Suivent les transparents de la vidéo précédente.

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 local peut être connecté à un dépôt distant sur un serveur Git: le serveur distant a 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

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, mais ne sont pas toujours synchronisés
  • 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 main
  • 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 ‘main’ 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

Chapitre 5 : Gitlab

GitLab est un logiciel qui combine un serveur GIT et un serveur Web et plein d’autres outils utiles.

Le serveur GIT répond aux demandes push, pull, clone, etc…

Le serveur Web vous montre des informations sur les dépôts existants et leur contenu, vous permet de configurer votre profil et vos actions, et vous permet d’accéder à plusieurs types d’outils complémentaires :

  • Configurer votre communication avec SSH
  • Donner des accès à vos projets à d’autres personnes
  • Consulter l’activité sur vos projets
  • Suivre votre projet avec des outils comme les issues, deadlines, milestones, sprints, merge requests qui sont des mots clefs en développement logiciel que vous verrez plus tard.
  • Automatiser des processus sur vos projets, comme par exemple, à chaque commit ou push sur une branche :
    • Lancer un processus de test, et si les tests échouent, refuser le commit ou le push
    • Lancer une installation de la nouvelle version du logiciel
    • Une combinaison des deux, sur plusieurs machines d’architectures différentes

GIT: Gitlab

GIT: Préparer l’environnement Gitlab/SSH

GIT: Connexion SSH à Gitlab

Une première étape clef dans votre communication avec gitlab est de configurer la communication par SSH.

En général, il est possible de se connecter à gitlab/github de plusieurs façons, dont par login et mot de passe. A Télécom, seule la connexion par SSH est confortable à utiliser, mais délicate à configurer.

Je suppose que vous avez déjà une paire de clefs SSH privée et publique. Personnellement, j’ai créé une autre paire de clefs SSH spécialement pour mes communications GitLab et GitHub.

Dans votre navigateur, allez sur Gitlab. En haut à droite, cliquez sur votre compte.

Choisissez « préférences », puis « clefs SSH »

Ouvrez dans un terminal et affichez votre clef publique : recopiez la dans le presse-papiers (contrôle-C ou command-C).

Collez la clef dans la zone adéquate. Mettez un titre à votre clef, et des paramètres pertinents.

Puis « ajoutez la clef ». Voici pour la partie du gitlab.

GIT: Exemple Cloner un dépôt distant

GIT: Connecter un dépôt local à un dépôt distant

GIT: Exemple commit, push, pull

GIT: Avoir deux espaces de travail synchronisés entre maison et école

  • 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 main pour connecter la branche locale main avec la branche distante main 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

GIT: Exemple pratique de fusion

Clonez le dépôt: git@gitlab.enst.fr:jean-claude.dufourd/learning-merge.git

Il y a plusieurs branches à merger dans main, avec tous les cas entre merge auto, merge simple et merge qui force l’édition à la main.

Les branches sont:

  • initial: la branche de départ, ne pas toucher
  • initial_ignore: la branche dans laquelle j’ai ajouté un fichier .gitignore
  • main: une copie de initial_ignore avec laquelle vous allez travailler
  • pretty: initial avec une fonction pretty en plus et un peu de test de pretty
  • comment_test: initial avec des commentaires et plus de test
  • refac_no_comma: initial refactorée pour enlever les virgules qui pourraient troubler un débutant en python

GIT: Exemple pratique de fusion (suite)

Si vous executez test.py, ça doit toujours marcher. C’est donc le test pour vous assurer que les fusions se sont bien passées.

Les fusions à tester sont :

  • git checkout main puis git merge pretty : ça devrait être automatique, le commit est souvent automatique
  • sur cette branche main modifiée, git merge comment_test: avec un outil graphique de fusion (celui que vous préférez) choisissez les modifs à appliquer (à droite ou à gauche), et là, il faut faire commit une fois que c’est fini.
  • sur cette branche main modifiée, git merge refac_no_comma: avec un outil graphique de fusion, vous pouvez faire une partie de la fusion automatiquement, et vous devez editer la partie centrale si vous voulez vraiment conserver les changements des deux versions.

L’opération complète est montrée dans la prochaine vidéo.

GIT: TP Merge

GIT: TP Merge (suite)

Il est important que vous vous fassiez la main en faisant, avec les outils que vous choisissez, ces fusions sur ce dépot exemple.

GIT: Merge request ou pull request

Merge request et pull request sont des synonymes.

Ca ne marche pas pareil selon que c’est au sein d’un même projet ou si vous proposez une correction sur un projet dont vous n’êtes pas un des gérants.

Parfois, les dépôts sont initialisés avec la branche main “protégée”. Cela veut dire que seuls les intégrateurs, qui ont des droits supplémentaires (maintainer), peuvent faire commit sur la branche main. Si c’est le cas et que vous n’êtes pas intégrateurs (juste developer), alors vous devez passer par une merge request pour publier votre travail sur main. Par contre, vous pouvez commit sur toutes les branches non protégées.

GIT: Merge Request au sein d’un projet

Vous êtes plusieurs à travailler sur un projet. Vous travaillez chacun sur votre branche. A la fin du projet, l’un de vous est chargé de l’intégration du projet, c’est-à-dire de vérifier que tous les bouts du logiciel développés séparément fonctionnent ensemble.

Vous avez fini votre travail sur la branche X. Il ne reste plus qu’à fusionner la branche X avec la branche main pour intégrer votre partie. La bonne façon de faire est de créer une merge request.

Sur gitlab, dans votre projet, barre de gauche, “Merge Requests”, et dans cette page, New Merge Request

La video sur le transparent suivant vous montre ce processus en pratique.

GIT: Merge Request au sein d’un projet (video)

GIT: Fork et Merge Request

Je vous propose d’expérimenter en pratique une merge request, ou pull request. C’est une façon de dire au développeur d’un dépôt que vous avez fait une modification que vous pensez utile dans votre dépôt qui est une copie du sien, et vous lui dites où aller chercher la modification.

Faire une copie d’un dépôt s’appelle faire un fork. Le dépôt copie a le même nom que le dépôt de départ, donc il doit être dans un autre espace de nom. Suite à diverses limitations, nous devons faire cette expérimentation sur github et pas notre gitlab de Télécom.

Le scénario est :

  1. vous allez vous créer un compte sur github.com si vous n’en avez pas déjà un
  2. sur github, j’ai un dépot ueo_mergereq, https://github.com/jcdufourd/ueo_mergereq
  3. vous allez faire une copie de ce dépôt sur votre compte par fork, que j’appellerai D1 et il va être à l’URL https://github.com/votrelogingithub/ueo_mergereq
  4. vous allez créer une autre organisation avec vous seul.e comme participant.e, par exemple votrelogingithuborg, ceci pour créer un second espace de nommage
  5. vous allez faire un fork de votre fork de mon dépôt, que j’appelerai D2 et il va être à l’URL https://github.com/orgs/votrelogingithuborg/ueo_mergereq

GIT: Fork et Merge Request 2

Vous allez d’abord créer une merge request :

  1. cloner D2
  2. faire des modifications
  3. commit
  4. push
  5. aller dans l’interface github de D2 pour générer une merge request pour ce commit

Puis vous allez gérer la merge request :

  1. aller dans l’interface github de D1 pour voir et traiter cette merge request

Maintenant, vous comprenez sans doute pourquoi je vous ai fait faire 2 forks : il faut que vous ayez des droits sur D1 pour pouvoir gérer la merge request, et je ne peux pas vous donner les droits d’accès au dépôt d’origine.

Note: vous pourriez faire tout ceci avec un autre dépôt que le mien comme origine.

GIT: Fork et Merge Request

TP Git informel

C’est une bonne idée de pratiquer vous-même pour faire entrer les concepts, même si c’est pour refaire exactement ce que vous avez vu dans les transparents. Ca ancre les choses dans votre mémoire, ça vous challenge si ça ne marche pas tout à fait de la même façon chez vous, ça vous force à demander de l’aide si ça ne marche pas du tout.

Tout ça, c’est bon pour vos apprentissages, même si pas forcément confortable.

TP externe

https://learngitbranching.js.org/?locale=fr_FR

Faire les 4 niveaux de main (séquence d’introduction) et les 8 niveaux de remote (push et pull)

TP interne

Refaites sur votre machine tous les exemples faits dans les transparents et les videos :

  • ouvrir et tester un terminal, lancer quelques commandes, se déplacer, voir le contenu d’un dossier
  • créer une paire de clefs SSH et configurer les accès
  • configurer le VPN école et se connecter depuis l’extérieur pour utiliser des ressources internes
  • trouver une machine de TP et se connecter à distance dessus pour lancer une commande
  • créer un dépot git local et ajouter/commiter quelques fichiers, regarder les logs
  • faire l’exemple simple de fusion
  • se connecter à gitlab et configurer votre compte pour un accès SSH
  • faire l’exemple de fusion sur le dépot learning-merge

N’hésitez pas à demander de l’aide à vos enseignants ou à moi

GIT Cheat Sheet

Ce chapitre complète l’enseignement GIT en donnant des indices ou des corrections pour tous les problèmes entendus en séance de TP et en projet.

A priori, ce chapitre est plutôt là pour vous aider à résoudre des problèmes plus tard. Sa lecture avant d’avoir expérimenté (et fait des erreurs) avec git n’est pas utile.

Attention, smartgit

smartgit est un logiciel disponible sur les plateformes habituelles et qui était utilisé dans un enseignement Java. Il y a quelques écrans de smartgit dans ces transparents, mais le même type de fonction existe dans tous les logiciels auxquels vous aurez accès: eclipse, intelliJ, visual code…

GIT ET LES FICHIERS

GIT gère des fichiers et leur évolution au cours du temps. Quand vous modifiez un fichier, GIT retient l’information suivante:

  • quel fichier est modifié
  • l’état du fichier avant et après la modification
  • qui a fait la modification
  • quand

Tout fichier peut être mis dans GIT. Mais tous les types de fichier ne font pas sens. Par exemple, un fichier compilé à partir d’un fichier source n’a pas sa place dans GIT si le fichier source y est déjà car il peut être recréé à partir du fichier source. Donc pour vos projets Java, ne mettez pas vos fichiers .class dans GIT. Dans vos projets en C, ne mettez pas les .o dans GIT.

Pour un fichier texte, GIT va vous indiquer les différences entre deux versions, les lignes ajoutées, retirées, modifiées. Pour un fichier binaire, GIT va juste dire que le fichier a changé, et les différences n’ont pas de sens. En ce sens, il n’est pas souvent pertinent de mettre un fichier binaire dans GIT.

GIT ET LES FICHIERS 2

GIT vous permet de consigner dans un fichier la liste des fichiers dont l’inclusion dans GIT ne fait pas sens. Ce fichier s’appelle .gitignore. Il peut y avoir un fichier .gitignore dans tous les dossiers, mais l’important est celui du dossier principal.

Pour ignorer un fichier, mettez son nom dans une ligne du .gitignore. Par exemple, sous Mac, il y a un fichier qui s’appelle .DS_Store, qui sert à Mac OSX.

Dans .gitignore, ajoutez la ligne avec .DS_Store

Pour ignorer un dossier complet, même chose, ajouter le nom du dossier suivi de /

Pour ignorer tous les fichiers .class, ajoutez une ligne avec *.class

Un fichier ignoré n’est pas stocké dans le dépot. S’il est modifié ou détruit, GIT l’ignore. Les fichiers ignorés ne sont donc pas présents dans le résultat d’un git clone.

FICHIERS A IGNORER

Il est parfois difficile au début de savoir s’il faut ignorer un fichier ou pas. Je vais traiter le cas d’Eclipse, Intellij, node.js et d’Android Studio

Pour Android Studio, ne faites rien: Android Studio crée automatiquement un fichier .gitignore qui est très bien. Utilisez le tel quel.

Pour IntelliJ, il faut ignorer les dossiers .idea/ et out/.

Si vous utilisez node.js, alors il faut ignorer le dossier node_modules/.

FICHIERS A IGNORER 2

Pour Eclipse, la question qui se pose est: dois-je mettre dans le dépot GIT les fichiers de description du projet, à savoir le .project et le .classpath. Ces deux fichiers dépendent de la configuration de votre machine et pourront perturber vos collaborateurs, surtout si vous avez un mélange de machines Windows, Mac et Linux dans le projet. Ignorez ces deux fichiers.

Cela veut dire que quand vous récupérerez la première fois un dossier où il y a un projet eclipse, eclipse ne le verra pas comme un projet et il faudra que vous l’importiez par “Importer depuis des sources existants”.

CORRIGER LES IGNORES

Comment faire si vous avez ajouté des fichiers dans un dépot, et vous découvrez qu’il aurait fallu les ignorer.

Etape 1: ajoutez le nom des fichiers à ignorer dans .gitignore

Etape 2: faites git rm --cached sur les fichiers

Etape 3: faites git commit et vérifiez

Dans le screencast, je traite un exemple avec un projet eclipse dont tout a été commit sans .gitignore.

Voir le screencast

DOSSIERS ET DEPOTS

Avec GIT, tout tourne autour des dépots.

Un dépot est un dossier contenant un ensemble de dossiers et de fichiers qui ont une cohérence pour vous.

Faire git init dans un dossier déclare ce dossier comme le dossier principal de votre dépot. Il faut faire git init dans le dossier eclipse qui contient les fichiers .project et .classpath, pour votre projet Java.

Il ne faut pas faire git init dans le dossier workspace ou eclipse-workspace, ni dans votre dossier racine, ni dans le dossier src de votre projet Java.

Le dossier principal de votre dépot GIT contient deux choses:

  • le sous-dossier .git, souvent non visible dans l’Explorer/Finder, qui contient les données privées du logiciel GIT.
  • votre copie de travail de vos fichiers, c’est à dire la branche sur laquelle vous avez fait git checkout avec les modifications en cours.

DOSSIERS ET DEPOTS 2

Si vous avez le choix, vous pouvez faire autant de dépots séparés que vous voulez. Mais si le nombre de dépot est imposé, par exemple si votre entreprise doit payer le service GIT au nombre de dépots que vous créez, ou si dans PACT, nous vous donnons accès à un seul dépot pour nous faciliter le travail, alors vous pouvez facilement travailler dans un seul dépot avec plusieurs sous-projets.

Créez un dossier principal qui sera le support du dépot.

Créez un dossier par sous-projet et une branche ou plus par sous-projet.

Voilà: il n’y aura pas d’interférence entre les sous-projets si chacun travaille dans sa branche et dans son dossier.

RECUPERER DES ERREURS DE DOSSIERS

Vous avez créé votre dépot dans le dossier du fichier .project, mais votre collègue a créé son dépot dans un autre dossier, soit le dossier src, soit son dossier racine ou workspace.

Vous avez tou.te.s les deux poussé dans un dépot distant commun, et vous découvrez le problème en essayant de faire un merge. Vous vous attendez à un merge très difficile, or il ne se passe rien. Vous retrouvez après le merge vos deux projets dans des dossiers différents

Que faire ?

Etape 1: revenir à un état avec vos fichiers dans une branche et les fichiers de l’autre dans une autre branche.

Soit vous revenez en arrière parce que cet état existe déjà dans votre dépot, car vous aviez déjà des branches séparées.

RECUPERER DES ERREURS DE DOSSIERS 2

Soit vous n’aviez pas encore de branches, vous avez tout fait sous master, et il faut reconstituer deux branches séparées.

  1. Créez deux branches moi et autre à partir de la branche master où il y a tous les fichiers.
  2. git checkout moi
  3. Vous voyez tous les fichiers
  4. Dans la branche moi, détruisez tous les fichiers de votre collègue par git rm.
  5. Il peut rester des fichiers qui sont ignorés et des dossiers vides que git ne gère pas, à supprimer manuellement.
  6. Vous ne voyez plus que vos fichiers
  7. git commit -a -m "message pertinent"
  8. git checkout autre
  9. Vous voyez de nouveau tous les fichiers
  10. Dans la branche autre, détruisez tous vos fichiers par git rm.
  11. Il peut rester des fichiers qui sont ignorés et des dossiers vides que git ne gère pas, à supprimer manuellement.
  12. Vous ne voyez plus que les fichiers de votre collègue.
  13. git commit -a -m "message pertinent"

RECUPERER DES ERREURS DE DOSSIERS 3

Vous êtes maintenant revenu.e.s à l’état où nous pouvons faire le déplacement des fichiers dans une des deux branches.

Le but est donc de déplacer les fichiers d’une branche pour que les deux branches aient des fichiers avec les mêmes noms dans les mêmes dossiers.

Choisissez celle des deux branches dont vous voulez garder la structure de dossier, par exemple c’est la branche moi qui a les bons dossiers.

Mettez vous dans la branche autre, par git checkout autre. Faites git mv sur tous les fichiers et dossiers jusqu’à obtenir la même structure que dans la branche moi. Faites git commit quand la structure est la même.

C’est fini. Vous pouvez maintenant faire un merge pertinent entre les deux branches.

Voir le screencast

UNRELATED HISTORIES

Vous voulez faire un merge avec la branche de votre binome, et git vous envoie un message contenant ‘unrelated histories’ et refuse de faire le merge.

Que se passe-t-il ?

Dans le TP, nous vous avons dit de faire comme suit:

  • l’un de vous, A, fait git init
  • A fait un premier git commit puis git push sur le dépot distant
  • B fait git clone du dépot distant
  • puis A et B créent chacun une branche et travaillent dans leur branche

Si vous avez suivi ce processus, alors vos deux historiques GIT sont liées par le partage du premier commit de A, récupéré par B lors du git clone

UNRELATED HISTORIES 2

Qu’avez-vous vraiment fait ?

  • vous avez tous les deux fait git init
  • vous avez tous les deux fait un premier git commit puis git push sur le dépot distant

Vous avez donc créé deux commits non liés entre eux et poussé deux points de départ de branche sur le dépot distant. Dans la fenetre log de smartgit, vous voyez deux lignes séparées.

UNRELATED HISTORIES 3

Si vous n’avez pas créé de branche avant de pousser, alors le second qui a poussé a dû créer une autre branche que master pour pousser. Dans l’image, ma second branche est master2. J’ai essayé de faire un merge et le message est “refusing to merge unrelated histories”.

Vous pouvez forcer git à faire un merge. Commencez par vérifier que les structures de dossier sont les mêmes des deux cotés, et que les fichiers ont le même nom s’ils doivent être fusionnés.

Puis faites la commande:

git merge master2 --allow-unrelated-histories

UNRELATED HISTORIES 4

Comme vous pouvez imaginer, cette option a un gros potentiel de confusion si vous l’utilisez n’importe comment. Donc faites bien les vérifications. Voici le résultat dans smargit, vue log:

Voir le screencast

DOSSIER GIT DANS DOSSIER GIT

Vous avez fait git init dans un dossier puis git init ou git clone dans un sous-dossier et vous ne savez plus quoi faire.

Mettez vous dans le dossier qui est dans l’autre dossier. Faites git status. S’il y a des modifications, voyez si elles doivent être sauvagardées.

Si le dossier interne contient des modifications et est un clone, alors il a un dépot distant. Commencez par déplacer le dossier interne en dehors du dossier externe. Puis les modifications peuvent être commit et push.

DOSSIER GIT DANS DOSSIER GIT 2

Si le dossier interne contient des modifications et n’a pas de dépot distant (remote), alors il faut sauver ces modifications d’une manière autre (copie du dossier, zip…).

Puis vous supprimez le dossier interne ou vous le déplacez en dehors de l’autre dossier.

Si vous aviez ajouté le dossier interne dans le GIT du dossier externe, alors il faut commit la suppression du dossier interne dans le GIT du dossier externe.

LES BRANCHES GIT: POURQUOI

A quoi servent les branches Git ?

Que se passe-t-il sans branches ?

  • Tout est fait dans la branche par défaut “master”
  • Vous pouvez créer un dossier par module, et quand vous faites des commits, push et pull dans des dossiers différents, il n’y a jamais de problème de merge conflicts (conflits de fusion) avec les autres binômes.
  • Par contre, chaque fois que vous faites un push, un autre membre du groupe en a fait un depuis votre dernier pull, et le push est refusé tant que vous n’avez pas fait un pull. Même si ce nouveau pull n’engendre pas de conflits de fusion, il faut quand même faire un pull.

Avec une branche et des dossiers séparés, vous êtes complètement indépendants des autres modules, vous développez sans être perturbé.e.s par le travail des autres.

Vous pouvez même faire une branche par personne, si vous travaillez sur des parties clairement séparées de celle de votre binôme.

Quand vous êtes prêt.e.s à partager votre travail avec d’autres, vous leur dites de fusionner votre branche avec la leur. C’est le principe de la “merge request”. Les fusions dans “master” sont plutôt à faire par les intégrateurs.

SE SERVIR DES BRANCHES GIT

Comment je peux me servir des branches Git ?

Je crée une branche à partir d’une autre

  1. Je suis dans une branche “tata” (à vérifier par git status)
  2. Je fais git branch toto pour créer la branche “toto” (je suis toujours dans la branche “tata”, “toto” et “tata” sont pour l’instant identiques)
  3. Je fais git checkout toto pour passer de “tata” à “toto”
  4. Si je fais maintenant des git commit, alors ils sont ajoutés dans la branche “toto” qui change par rapport à “tata”

Je fais git branch -v pour savoir quelles sont les branches existantes en local

Je fais git checkout tata pour passer d’une branche à la branche “tata”

Quand je fais git clone, seule la branche “main” ou “master” est importée dans le dépôt local par défaut.

  1. Quand je fais git checkout tata la première fois, git importe tous les commits de la branche “tata” dans mon dépôt local
  2. Si je veux importer dans mon dépôt local toutes les branches qui existent sur le dépot distant, je fais git fetch —all

PARTAGER DES BRANCHES GIT

Pour partager mon travail qui se trouve dans une branche GIT, deux possibilités

  1. Je propose une fusion simple
  • Je me mets dans la branche de destination
  • Je fais git merge source où source est la branche source des commits à partager
  • Je résous les éventuels conflits
    • J’édite le fichier pour supprimer les indications de conflits
    • Je fais git add sur le fichier que je viens d’éditer
    • Je fais git commit quand tous les conflits sont résolus
  1. Je propose une fusion de type “rebase”
  • Je me mets dans la branche source des commits à partager
  • Je fais git rebase destination où destination est la branche qui va recevoir les commits partagés
  • Je résous les éventuels conflits
    • J’édite le fichier pour supprimer les indications de conflits
    • Je fais git add sur le fichier que je viens d’éditer
    • Je fais git commit quand tous les conflits sont résolus

La fusion simple est plus facile à comprendre mais crée un historique GIT plus compliqué.

AUTRES

Si vous avez un problème qui n’a pas de solution décrite ici, dites le à un de vos enseignants, je rajouterai une video.

Fin

Ceci est la fin de ce cours en ligne.

Tous les retours sont bienvenus par email