Aller au contenu

TP pratique — GitLab en groupe : branches, merge requests, conflits et résolution avec IntelliJ

Objectif du TP

Ce TP va vous permettre de travailler en groupe 3 ou 4 sur un même dépôt GitLab afin de pratiquer :

Le TP est volontairement simple : les fichiers Java ne nécessitent pas de framework. L’objectif principal est de comprendre Git, GitLab et les conflits.


Table des matières

  1. Organisation du groupe
  2. Structure du dépôt fourni
  3. Préparation du dépôt GitLab
  4. Rôles des participants
  5. Partie 1 — Cloner le dépôt
  6. Partie 2 — Créer sa branche
  7. Partie 3 — Modifier les fichiers
  8. Partie 4 — Commit et push
  9. Partie 5 — Créer une merge request
  10. Partie 6 — Provoquer volontairement des conflits
  11. Partie 7 — Résoudre les conflits avec IntelliJ
  12. Corrections attendues par rôle
  13. Version finale attendue des fichiers
  14. Commandes Git utiles
  15. Bilan pédagogique

1. Organisation du groupe

Chaque groupe doit être composé de 3 à 4 personnes.

Un membre du groupe joue le rôle de mainteneur du dépôt. Les autres membres jouent le rôle de développeur.euse.s.

Participant Rôle Branche
Personne A Catalogue feature/personne-a-catalogue
Personne B Calculateur de prix feature/personne-b-calculateur
Personne C Client feature/personne-c-client
Personne D Messages feature/personne-d-message

2. Structure du dépôt fourni

depot-java-collaboratif/
├── README.md
└── src/
    └── main/
        └── java/
            └── fr/
                └── formation/
                    └── gitlabtp/
                        ├── Application.java
                        ├── CatalogueService.java
                        ├── CalculateurPrix.java
                        ├── ClientService.java
                        └── MessageService.java

Les fichiers Java contiennent volontairement du code simple, avec une ou deux imperfections. L’objectif n’est pas de faire une application métier complète, mais de provoquer des modifications concurrentes.


3. Préparation du dépôt GitLab

Étape 1 — Créer le projet GitLab

Le mainteneur crée un projet GitLab nommé :

tp-gitlab-conflits-groupe

Étape 2 — Ajouter les membres du groupe

Dans GitLab :

Project information > Members > Invite members

Attribuer les rôles suivants :

Profil Rôle GitLab conseillé
Formateur Maintainer
Chef de groupe Maintainer
Apprenants Developer

Étape 3 — Envoyer le dépôt initial

Depuis le dossier depot-java-collaboratif :

git init
git branch -M main
git add .
git commit -m "Initialisation du TP GitLab conflits"
git remote add origin URL_DU_DEPOT_GITLAB
git push -u origin main

4. Rôles des participants

Chaque participant modifie son fichier principal, mais plusieurs participants modifient aussi Application.java. Cette modification volontairement commune provoque les conflits.

Participant Fichier principal Fichier commun modifié
Personne A CatalogueService.java Application.java
Personne B CalculateurPrix.java Application.java
Personne C ClientService.java Application.java
Personne D MessageService.java Application.java

5. Partie 1 — Cloner le dépôt

Chaque participant clone le dépôt :

git clone URL_DU_DEPOT_GITLAB
cd tp-gitlab-conflits-groupe

Vérifier l’état :

git status

Résultat attendu :

On branch main
Your branch is up to date with 'origin/main'.
nothing to commit, working tree clean

Dans IntelliJ :

File > Open > choisir le dossier du projet

6. Partie 2 — Créer sa branche

Personne A

git checkout -b feature/personne-a-catalogue

Personne B

git checkout -b feature/personne-b-calculateur

Personne C

git checkout -b feature/personne-c-client

Personne D

git checkout -b feature/personne-d-message

Vérifier :

git branch

7. Partie 3 — Modifier les fichiers

Travail de la personne A

Modifier CatalogueService.java :

package fr.formation.gitlabtp;

import java.util.List;

public class CatalogueService {

    public String titreCatalogue() {
        return "Catalogue bancaire et loisirs";
    }

    public List<String> produitsDisponibles() {
        return List.of(
                "Compte courant",
                "Carte bancaire premium",
                "Assurance voyage",
                "Compte épargne loisirs"
        );
    }
}

Modifier aussi dans Application.java :

System.out.println("=== Application GitLab - Catalogue enrichi ===");

Travail de la personne B

Modifier CalculateurPrix.java :

package fr.formation.gitlabtp;

public class CalculateurPrix {

    public double calculerTotal(double prixUnitaire, int quantite) {
        if (prixUnitaire < 0 || quantite < 0) {
            throw new IllegalArgumentException("Le prix et la quantité doivent être positifs.");
        }
        return prixUnitaire * quantite;
    }

    public double appliquerRemise(double total, double tauxRemise) {
        if (tauxRemise < 0 || tauxRemise > 1) {
            throw new IllegalArgumentException("Le taux de remise doit être compris entre 0 et 1.");
        }
        return total * (1 - tauxRemise);
    }
}

Modifier aussi dans Application.java :

System.out.println("=== Application GitLab - Calculateur corrigé ===");

Travail de la personne C

Modifier ClientService.java :

package fr.formation.gitlabtp;

public class ClientService {

    public String formaterNomComplet(String prenom, String nom) {
        if (prenom == null || prenom.isBlank()) {
            throw new IllegalArgumentException("Le prénom est obligatoire.");
        }

        if (nom == null || nom.isBlank()) {
            throw new IllegalArgumentException("Le nom est obligatoire.");
        }

        return prenom.trim() + " " + nom.trim().toUpperCase();
    }
}

Modifier aussi dans Application.java :

System.out.println("=== Application GitLab - Client sécurisé ===");

Travail de la personne D

Modifier MessageService.java :

package fr.formation.gitlabtp;

public class MessageService {

    public String messageBienvenue(String nom) {
        return "Bienvenue " + nom + ", votre espace bancaire et loisirs est prêt.";
    }

    public String messageConfirmationImport() {
        return "Les données ont été traitées avec succès.";
    }
}

Modifier aussi dans Application.java :

System.out.println("=== Application GitLab - Messages améliorés ===");

8. Partie 4 — Commit et push

Chaque participant fait :

git status
git add .
git commit -m "Modification fonctionnalité personne X"
git push -u origin NOM_DE_LA_BRANCHE

Exemple :

git push -u origin feature/personne-a-catalogue

9. Partie 5 — Créer une merge request

Dans GitLab :

Merge requests > New merge request

Choisir :

Source branch : feature/personne-x-...
Target branch : main

Titre conseillé :

Ajout fonctionnalité personne X

10. Partie 6 — Provoquer volontairement des conflits

Le mainteneur accepte d’abord la merge request de la personne A.

Ensuite, les personnes B, C et D auront probablement un conflit dans Application.java, car chaque branche a modifié la même ligne :

System.out.println("=== Application de démonstration GitLab ===");

GitLab peut afficher :

Merge blocked: merge conflicts must be resolved.

C’est normal. Ce n’est pas une catastrophe. C’est Git qui demande un adulte dans la pièce.


11. Partie 7 — Résoudre les conflits avec IntelliJ

Étape 1 — Se placer sur sa branche

Exemple personne B :

git checkout feature/personne-b-calculateur

Étape 2 — Récupérer main

git fetch origin

Étape 3 — Fusionner main dans sa branche

git merge origin/main

Si conflit :

CONFLICT (content): Merge conflict in src/main/java/fr/formation/gitlabtp/Application.java
Automatic merge failed; fix conflicts and then commit the result.

Étape 4 — Résoudre avec IntelliJ

Dans IntelliJ, ouvrir le fichier en conflit. Il contient des marqueurs comme :

<<<<<<< HEAD
System.out.println("=== Application GitLab - Calculateur corrigé ===");
=======
System.out.println("=== Application GitLab - Catalogue enrichi ===");
>>>>>>> origin/main

Il faut supprimer les marqueurs et conserver une version cohérente.


12. Corrections attendues par rôle

Correction personne B

Après fusion de la personne A, la personne B doit résoudre ainsi :

System.out.println("=== Application GitLab - Catalogue enrichi et calculateur corrigé ===");

Puis :

git add .
git commit -m "Résolution conflit Application personne B"
git push

Correction personne C

Après fusion de A et B :

System.out.println("=== Application GitLab - Catalogue, calculateur et client sécurisé ===");

Puis :

git add .
git commit -m "Résolution conflit Application personne C"
git push

Correction personne D

Après fusion de A, B et C :

System.out.println("=== Application GitLab - Catalogue, calculateur, client et messages ===");

Puis :

git add .
git commit -m "Résolution conflit Application personne D"
git push

13. Version finale attendue des fichiers

La version finale complète est fournie dans le dossier :

solutions/version-finale/

Elle doit compiler avec :

javac src/main/java/fr/formation/gitlabtp/*.java
java -cp src/main/java fr.formation.gitlabtp.Application

Résultat attendu approximatif :

=== Application GitLab - Catalogue, calculateur, client et messages ===
Catalogue bancaire et loisirs
[Compte courant, Carte bancaire premium, Assurance voyage, Compte épargne loisirs]
Total avant remise : 149.7
Total après remise : 134.73
Bienvenue Alice MARTIN, votre espace bancaire et loisirs est prêt.
Les données ont été traitées avec succès.

14. Commandes Git utiles

Action Commande
Voir l’état git status
Voir les branches git branch
Créer une branche git checkout -b nom-branche
Changer de branche git checkout nom-branche
Récupérer le distant git fetch origin
Fusionner main git merge origin/main
Ajouter les fichiers git add .
Commit git commit -m "message"
Push git push
Historique graphique git log --oneline --graph --all

15. Bilan

Vous devez savoir :

  1. ce qu’est une branche
  2. pourquoi on ne travaille pas directement sur main
  3. ce qu’est une merge request
  4. pourquoi un conflit apparaît
  5. comment résoudre un conflit
  6. pourquoi il faut relire le code final après résolution
  7. comment IntelliJ aide à résoudre les conflits
  8. pourquoi Git ne choisit pas toujours automatiquement entre deux intentions concurrentes.

Phrase clé

Git compare du texte. Il ne comprend pas le métier. Quand deux personnes modifient la même ligne, Git ne tranche pas arbitrairement : il demande au développeur de décider.