Séminaire Git

2 - Collaborer avec Git et Gitlab

Adrien Krähenbühl Équipe IMAGeS - ICube

Résumé de la première séance

Git



  • Git est un outil de versionnement de fichiers qui permet de sauvegarder les états successifs d’un répertoire.
  • Un état sauvegardé d’un répertoire s’appelle un commit.
  • L’ensemble des commits constitue un arbre.

En un schéma

Les commandes d’état

git init
Initialise un dépôt Git sur mon ordinateur.
git config
Pour consulter/modifier la configuration de git.
git status
État de mon répertoire Git et des fichiers qu’il contient.
git log
Historique des commits de mon répertoire Git.
git diff
Différence entre l’état actuel de mes fichiers et le dernier commit.
gitk
Logiciel de visualisation graphique de l’état d’un répertoire Git.

Les doubles commandes

git checkout
  1. Supprime les modification locales de mon fichier
    \(\rightarrow\) retour à l’état du dernier commit
  2. Transpose le répertoire Git à l’état d’un autre commit.
    \(\rightarrow\) nécessite de n’avoir aucun changement local
git add
  1. Ajoute un fichier au système de versionnement Git
  2. Ajoute le(s) fichier(s) à la zone de transit
    \(\rightarrow\) si des modifications sont apportées à un fichier de la zone de transit avant un commit, elle ne seront pas prise en compte.

Gitlab

Gitlab à ICube

Gitlab est une plateforme d’hébergement de dépôts Git.
Il y a deux instances Gitlab institutionnelles :

Avantage ICube :
Possibilité de collaborer avec des personnes extérieures qui possèdent un compte Github.

Créer et cloner un dépôt Gitlab

  1. Sur Gitlab, créez un nouveau projet GitlabBase.
  2. Clonez le 1\(^{ier}\) dépôt Git dans le répertoire de cette séance :
$ cd TutoGit/
$ git clone [URL]
  1. Observez le répertoire créé :
$ cd GitlabBase/
$ ls -a
$ git status

Gérer un dépôt distant seul

Les remotes

Remote
  • Un remote est un dépôt distant du même projet, synchronisé avec le répertoire local.
  • Lorsqu’on clone un dépôt distant, il est ajouté comme remote du répertoire local et nommé origin.
  • Le nombre de remote n’est pas limité.

  1. Affichez les remotes du répertoire GitlabBase :
$ git remote [-v]
  1. Affichez les détails du remote origin :
$ git remote show origin

Pousser vers un remote

  1. Créez un fichier README.md avec au moins 1 ligne de texte :
$ echo "Projet de test de la séance 2." > README.md
  1. Ajoutez le fichier à la zone de transit et commitez :
$ git add README.md
$ git commit -m "Ajout du fichier README.md"
  1. Poussez votre commit vers le dépôt origin :
$ git push [origin [master]]
  1. Dans votre navigateur web, rechargez la page du dépôt GitlabBase.

Tirer depuis un remote

  1. Éditez le fichier README.md depuis le Gitlab du labo.
  1. Récupérez localement le graphe du remote origin :
$ git fetch [origin [master]]
$ git status
$ git log
$ gitk # Modifier la vue
  1. Fusionnez le graphe du remote avec le graphe local :
$ git merge [origin/master]
$ git status
$ git log
$ gitk
Note :
Dans 95% das cas, on utilise git pull \(=\) git fetch \(+\) git merge

Créer et résoudre un conflit

Histoire divergente

  1. Sur Gitlab, ajoutez une 3\(^{ème}\) ligne au fichier README.md.
  2. Dans votre clone local, ajoutez une 3\(^{ème}\) ligne au fichier README.md et commitez :
$ echo "3ème ligne ajoutée depuis le clone." >> README.md
$ git commit -am "Troisième ligne ajoutée à README.md"
  1. Poussez votre commit sur le dépôt distant :
$ git push

Message d’erreur :

To icube-forge.unistra.fr:[LOGIN]/GitlabBase
 ! [rejected]        master -> master (fetch first)
error: failed to push some refs to 'git@icube-forge.unistra.fr:[LOGIN]/GitlabBase'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

Histoire divergente

  1. Récupérez localement le graphe du remote origin :
$ git fetch origin
$ git status
$ gitk
  1. Fusionnez le graphe du remote origin avec votre graphe local :
$ git merge [origin/master]
$ git status
$ gitk

Message d’erreur :

Auto-merging README.md
CONFLICT (content): Merge conflict in README.md
Automatic merge failed; fix conflicts and then commit the result.

Résolution par un commit de fusion

  1. Éditez le fichier en conflit avec, au choix, un éditeur de texte (nano, vim, atom, etc.) ou un outils dédié (voir git mergetool --tool-help)
  1. Ajoutez le fichier à la zone de transit et commitez :
$ git add README.md
$ git commit
  1. Poussez votre commit sur le remote origin :
$ git push origin master

Pour abandonner la fusion à tout moment :

$ git merge --abort

Les branches

Pourquoi les branches ?

Une branche
Une branche permet de construire une histoire parallèle à l’histoire principale. Concrètement, c’est un pointeur nommé vers un commit.
Philosophie :
  • La branche principale d’un dépôt est nommée master par défaut.
  • Toutes les branches sont vouées à être fusionnées avec master.
  • Travailler sur une branche permet d’intervenir sur plusieurs aspects du projet en parallèle.

Créer et travailler sur une branche

  1. Créez une branche locale Feature1 :
$ git branch Feature1
  1. Déplacez-vous sur cette branche :
$ git checkout Feature1
  1. Ajoutez un fichier main.tex et commitez :
$ echo "\documentclass{minimal}\begin{document}Mon document\end{document}" > main.tex
$ git add main.tex
$ git commit -m "Ajout de main.tex"

Le pointeur HEAD


1. État initial du clone local.


2. Création de la branche Feature1

$ git branch Feature1


3. Déplacement sur la branche Feature1

$ git checkout Feature1


4. Commit depuis le marqueur HEAD

$ git commit -m "Aj..."

Note : Les étapes 2 et 3 peuvent être combinées en 1 commande :
git checkout -b X = git branch X + git checkout X

Fusionner sa branche avec master

La procédure ci-dessous utilise le mécanisme de “Merge request” de Gitlab mais elle pourrait aussi être réalisée manuellement.

  1. Modifiez README.md sur la branche master via Gitlab.
  2. Poussez votre branche sur le remote origin
$ git push origin Feature1
  1. Créez un “Merge Request” sur Gitlab
  2. Réalisez le merge sur Gitlab

Récupérer le master de Gitlab

Sur votre clone, vous pouvez récupérez la version courante du master :

  1. Déplacez-vous sur la branche master
$ git checkout master
  1. Fusionnez le graphe local avec celui du remote origin
$ git pull origin master

Bonnes pratiques

Général

  • Toujours préciser le remote et la branche dans les commandes Git
  • Faire des petits commit réguliers avec des messages explicites.

Les branches

  • Ne jamais travailler sur la branche master
  • Toujours mettre à jour le master avant de démarrer une branche

Astuces

  1. Si j’ai commencé à modifier le master mais pas encore commité, je peux tout transposer sur une branche.
$ git checkout -b MaBranche
  1. Pour supprimer des commits non poussés sur un remote :
$ git reset --hard HEAD^

Quelques points pour aller plus loin

En vrac :

  • Ajouter une clé SSH sur Gitlab
  • Ajouter un fichier .gitignore
  • Utiliser la pile avec git stash
  • Utiliser plusieurs remotes : git remote rename/add
  • Plutôt que de fusionner, on peut rebaser avec git rebase
  • On peut réaliser des commit qui réalise l’inverse de précédents commit avec git revert