.. raw:: html

    <style> .greenbox {color:white;background-color:#2c9a43;font-weight: normal; padding: 2px 5px 1px 5px;border-radius: 5px} </style>
    <style> .whitebox {color:black;background-color:white;font-weight: normal; padding: 2px 5px 1px 5px;border-radius: 5px} </style>

.. role:: greenbox
.. role:: whitebox

.. _00github:

Environnement de travail du projet
----------------------------------

Le projet s'effectue dans un environnement GitHub / Codespaces. Pour rappel, GitHub est un service en ligne qui permet d'héberger des projets de développement logiciel. Codespaces est un service de développement en ligne qui permet de développer des applications directement dans le navigateur. Il est basé sur Visual Studio Code et permet de travailler sur des projets GitHub sans avoir à installer quoi que ce soit sur sa machine.

Pour ce qui va suivre, on considère que le binome est constitué des deux élèves ``Alice`` et ``Bob``. On considère que :

- ``Alice`` est propriétaire du projet ;
- et ``Bob`` est collaborateur du projet. 

.. important::

   Il faut décider dès à présent qui va jouer le rôle de ``Alice`` et qui va jouer le rôle de ``Bob``. Ces rôles sont définitifs et ne peuvent pas être changés en cours de projet.

Créer l'environnement
.....................

L'environnement est créé une seule fois pour toutes, par le propriétaire du projet, ici ``Alice``, à partir du starter code disponible dans `ce dépôt <https://github.com/DanielCourivaud/TBA>`_. Il est utilisé comme template pour créer le propre dépôt de ``Alice``. 

- :greenbox:`Use this template`  :greenbox:`Create a new repository`  :whitebox:`TBA`  :greenbox:`Create repository`

Après création, le repo est visible à l'adresse ``https://github.com/Alice/TBA``. Puisqu'il est public, il est également visible par ``Bob`` mais il ne peut pas y contribuer pour l'instant.

.. tip::

    Pour la suite, l'adresse du repo sera référencée par ``[REPOSITORY_HOMEPAGE]``.

Une fois le projet créé, ``Bob`` sera ajouté par ``Alice`` comme collaborateur et pourra contribuer de la même manière au projet. 

Ajouter des collaborateurs
..........................

Pour un travail en binome efficace, il faut que chacun des membres puisse ajouter/modifier/supprimer des fichiers. C'est automatiquement le cas pour ``Alice`` qui est propriétaire du repo. 

Pour que ``Bob`` puisse contribuer au projet, ``Alice`` doit l'inviter explicitement à partir de

``[REPOSITORY_HOMEPAGE] >> Settings >> Collaborators >> Add people``  

en lui donnant le rôle de ``Collaborator``.

Associer un codespace
.....................

Depuis la ``[REPOSITORY_HOMEPAGE]``, ``Alice`` et ``Bob`` doivent chacun démarrer leur propre codespace (il n'est pas possible de partager un codespace).

:greenbox:`Code` :greenbox:`Codespaces` :greenbox:`Create codespace on main`

.. warning::

   Une fois créé, le codespace est accessible à une adresse du type ``https://[STRANGE_CODESPACE_NAME].github.dev/``. Les codespaces de ``Alice`` et de ``Bob`` sont indépendants et n'ont donc pas la même adresse.
   
   Les codespaces sont associés au compte Github. Il n'est donc pas possible pour ``Alice`` d'accéder au codespace de ``Bob`` et vice versa (une erreur 404 est générée)
   
   La seule façon de partager du code entre ``Alice`` et ``Bob`` est de passer par le repo. Il est important :
   
      - de bien se répartir le travail pour éviter les conflits ;
      - de synchroniser régulièrement le repo avec les codespaces.

Les codespaces sont gérés sur la page `<https://github.com/codespaces>`_. Il faut veiller à stopper ou à supprimer les codespaces inutilisés pour ne pas consommer des ressources inutilement.


Le workflow
...........

.. important::

    Les informations ci dessous sont importantes et devront être consultées tout au long de la vie du projet.

Le repo est le référentiel du projet. A ce titre, il doit être régulièrement synchronisé avec chacun des codespaces. ``Alice`` et ``Bob`` devront suivre la démarche suivante :

   - synchronisation descendante à partir du repo : ``git pull``
   - modification/ajout/suppression de fichiers
   - ajout à l'index : ``git add .``
   - insertion dans l'historique : ``git commit -m "message explicatif"``
   - synchronisation montante avec le repo : ``git push``

Pour une organisation optimale, il sera pratique de ne pas travailler sur les mêmes fichiers. La structuration en modules/classes permet ça.

Etape initiale
!!!!!!!!!!!!!!

Au démarrage, le repo et les codespaces sont synchronisés comme l'indique la figure ci dessous. ``1e14`` est le commit initial et ne contient que le fichier ``README.md``.

.. image:: images/workflow-00.drawio.png
   :align: center

Pour Alice, dans le terminal du codespace ::

   Alice $ git log --format="%h"
   1e14

Même chose pour Bob ::
      
   Bob $ git log --format="%h"
   1e14

Alice ajoute du code
!!!!!!!!!!!!!!!!!!!!

Alice ajoute du code dans son codespace. 

Puis elle ajoute ces fichiers à l'index, et crée le commit. Dans le terminal du codespace ::

      Alice $ git add .
      Alice $ git commit -m "Ajout de code"
      Alice $ git log --format="%h"
      78de
      1e14


.. image:: images/workflow-01.drawio.png
   :align: center

A présent, le codespace de ``Alice`` est en avance sur le repo ::

      Alice $ git status

      # On branch master
      # Your branch is ahead of 'origin/master' by 1 commit.
      #
      nothing to commit (working directory clean)

Alice synchronise son codespace avec le repo
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

Pour maintenir le repo à jour avec ses dernières modifications, Alice doit synchroniser son codespace avec le repo. Elle pousse son commit ``78de`` ::
   
   Alice $ git push
   
.. image:: images/workflow-02.drawio.png
   :align: center

Le repo est à jour mais pas le codespace de Bob ::
   
   Alice $ git status
   On branch master
   Your branch is up to date with 'origin/master'.

   nothing to commit, working tree clean

Bob récupère les modifications d'Alice
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

Bob récupère les modifications d'Alice en synchronisant son codespace avec le repo. Il tire le commit ``78de`` ::
   
   Bob $ git pull
   remote: Enumerating objects: 1, done.
   remote: Counting objects: 100% (1/1), done.
   remote: Compressing objects: 100% (1/1), done.
   remote: Total 1 (delta 0), reused 0 (delta 0), pack-reused 0
   Unpacking objects: 100% (1/1), done.
   From https://github.com/Alice/TBA
      1e14..78de  master -> origin/master
   Updating 1e14..78de
   Fast-forward
   file1.txt | 2 +-
   1 file changed, 1 insertion(+), 1 deletion(-)

.. image:: images/workflow-03.drawio.png
   :align: center

Le codespace de Bob est synchronisé avec le repo ::
      
      Bob $ git status
      On branch master
      Your branch is up to date with 'origin/master'.
      $ git log --format="%h"
      78de
      1e14

Bob ajoute du code
!!!!!!!!!!!!!!!!!!

Il peut se trouver une situation dans laquelle Bob travaille de son côté, et crée le commit ``e094`` ::

   Bob $ git add .
   Bob $ git commit -m "Ajout d'autre code"
   Bob $ git log --format="%h"
      e094
      1e14
   
.. image:: images/workflow-04.drawio.png
   :align: center   
   
   
Lorsque Bob veut synchroniser son codespace avec le repo, il va se produire une erreur puisqu'il ne dispose pas du commit ``78de``::

   Bob $ git push
   To github.com:Alice/TBA
   ! [rejected]        master -> master (fetch first)
   error: impossible de pousser des références vers 'github.com:Alice/TBA'
   astuce: Les mises à jour ont été rejetées car la branche distante contient du travail que
   astuce: vous n'avez pas en local. Ceci est généralement causé par un autre dépôt poussé
   astuce: vers la même référence. Vous pourriez intégrer d'abord les changements distants
   astuce: (par exemple 'git pull ...') avant de pousser à nouveau.
   astuce: Voir la 'Note à propos des avances rapides' dans 'git push --help' pour plus d'information.

Si les modifications de Bob ne sont pas en conflit avec celles d'Alice, il peut tirer les modifications d'Alice, ajouter ses fichiers à l'index, créer le commit et pousser les modifications ::

   Bob $ git pull
   Bob $ git add .
   Bob $ git commit -m "Ajout d'autre code"
   Bob $ git log --format="%h"
      e094
      78de
      1e14

.. image:: images/workflow-05.drawio.png
   :align: center

Bob peut synchroniser son codespace avec le repo ::

   Bob $ git push

.. image:: images/workflow-06.drawio.png
   :align: center

Le repo est à jour et Alice peut récupérer les modifications de Bob ::

   Bob $ git pull

.. image:: images/workflow-07.drawio.png
   :align: center

Résolution de conflit
!!!!!!!!!!!!!!!!!!!!!

Il peut y avoir une situation pour laquelle Bob a effectué des modifications contradictoires avec le repo, par exemple modifié le même fichier qu'Alice. Dans ce cas, il y a un conflit et lorsque Bob tire les modifications d'Alice, il obtient un message d'erreur ::

   Bob $ git pull
   ! [rejected]        master -> master (non-fast-forward)
   error: failed to push some refs to 'https://github.com/yourusername/yourrepo'
   hint: Updates were rejected because the tip of your current branch is behind
   hint: its remote counterpart. Integrate the remote changes (e.g. 'git pull')
   hint: before pushing again.

Bob doit résoudre le conflit en éditant le fichier conflictuel. Il doit supprimer les marqueurs de conflit et choisir les modifications à conserver. Une fois le conflit résolu, il ajoute le fichier à l'index, crée un commit de résolution de conflit qui fait l'interface entre ``78de`` et ``e094`` ::

   Bob $ git add .
   Bob $ git commit -m "Résolution du conflit"
   Bob $ git log --format="%h"
      e094
      4a82
      78de
      1e14

.. image:: images/workflow-08.drawio.png
   :align: center

Bob peut alors synchroniser son codespace avec le repo et il sera possible à Alice de récupérer les modifications apportées par Bob ::

   Bob $ git push