Références

git :

git flow : https://www.atlassian.com/fr/git/tutorials/comparing-workflows/gitflow-workflow

Exerciceshttps://learngitbranching.js.org/

Installation sur linux

# Installation de Git
sudo apt -y install git

Installation de git bash pour windows

git avec git flow : https://git-scm.com/download/win

Attention, au début de l'installation, une option vous permettra de choisir "main" et non pas "master" comme nom de branche par défaut.

Principes de base

git est un gestionnaire de versions, c'est à dire qu'il permet de garder une trace de toutes les versions d'un logiciel en développement.

Le logiciel (avec ses versions) est stocké dans un dépôt (repository) local et/ou distant. Le projet est disponible dans le répertoire de travail (working directory). Si un fichier est modifié, pour qu'il fasse partie de la prochaine version, il faut le marquer et le placer dans une zone d'attente dite "staging area" par une opération d'ajout "add". Les fichiers en attente participent à la prochaine version par une opération de "commit". Chaque commit est identifié par le résultat d'une fonction de hachage appelée "sha-1".

Les 3 principaux états d'un fichier local

staging area

Repository local vs distant (origin)

local origin

Configuration de base 

Configuration de l'utilisateur

git config --global user.name "Bob Dylan"
git config --global user.email "bob@dylan.com"

Pour vérifier :

git config --global --get user.name
git config --global --get user.email

Créer les raccourcis pour les commandes les plus courantes

git config --global alias.co checkout
git config --global alias.br branch
git config --global alias.ci commit
git config --global alias.st status

Faire en sorte que le nom de la branche de base soit bien "main". Attention cela sous-entend que vous avez une version de git supérieure à 2.30 (git --version pour vérifier)

git config --global init.defaultBranch main

Configuration générale

git config color.ui true

Commandes de bases

Créer un dépot local

git init

Revenir à la branche main

git checkout main

Ajouter les premiers fichiers du "working directory" dans la "staging area"

git add .

Retour d'un fichier appartenant à la "staging area" vers le "working directory"

git rm --cached nomdufichier

Retour d'un fichier modifié dans le "working directory" à son état lors du dernier "commit"

git checkout nomdufichier

Ajouter au "repository" local le code qui se trouve dans la "staging area"

git ci -m "Premier commit avec une explication sur le contenu."

Modifier le dernier message de commit

git commit --amend -m "New commit message"

Envoyer les derniers commits sur le repository distant

git push

Récupérer les derniers commits depuis le repository distant

git pull

Voir ou l'on en est du "working directory" et de la "staging area"

git status

Voir la différence entre la version actuelle d'un fichier et sa version dans le dernier commit

git diff nomdufichier

Créer un patch à partir de la différence entre 2 états du même fichier

git diff nomdufichier > custom_patch_file.patch

Voir les branches présentes dont la branche en cours

git br

Voir l'historique des commits

git log

Voir l'historique des commits avec un meilleur aperçu des branches

git log --all --decorate --oneline --graph

Annuler un commit

git revert sha_du_commit

Créer une branche develop

git checkout -b develop

Supprimer une branche 

git branch -d nomdelabranche

Supprimer une branche alors qu'elle n'est pas fusionnée et qu'elle a au moins un commit

git branch -D

Faire un merge de develop sur master

git checkout master
git diff master..develop // pour voir les différences entre les deux branches
git merge develop // crée un commit


Supprimer la branche bonjour

git branch -d bonjour // valable dans le cas où la branche bonjour a été mergée
git branc -D bonjour // Attention supprime la branche bonjour même si elle comporte des commits qui n'ont pas été mergés : perte de travail !

Pousser ma branche master sur le repository github "origin"

git push origin main

Rebase

Voici un scénario dans lequel 

git pull --rebase

s'avère être une solution :

Vous travaillez sur une branche de fonctionnalités nommée feature-xyz. Pendant que vous travailliez sur votre fonctionnalité, un autre développeur a fusionné ses modifications dans la branche principale (main). Vous souhaitez désormais intégrer ces modifications dans votre branche de fonctionnalités pour garantir la compatibilité et rester à jour avec la dernière base de code.

Problème :

Vous rencontrez des conflits de fusion lorsque vous essayez de fusionner la branche principale dans votre branche feature-xyz. De plus, vous souhaitez éviter d’encombrer votre historique de validation avec des validations de fusion inutiles.

Solution :

Utilisez 

git pull --rebase

pour réappliquer vos commits locaux en plus des dernières modifications de la branche master. Cela vous aidera à résoudre tout conflit tout en gardant votre historique de validation linéaire et propre.

git

Astuce

utilisez

git config --global pull.rebase true

pour éviter de taper l'indicateur --rebase à chaque fois que vous tirez

Créer un repository distant sur gihub

  • Si ce n'est pas encore fait, créez un compte sur github
  • Cliquez sur le bouton vert "New" en haut à gauche pour obtenir l'interface suivante
    create repo
  • Cliquez sur le bouton vert "Create repository" pour obtenir l'interface suivante :
    create repository step 2
  • Entrez les instructions ci-dessus entourées de rouge sur votre console locale en ayant vérifier que vous vous trouvez bien sur un répertoire qui possède déjà un repository (git st pour vérifier). Ces opérations vont relier la branche "main" de votre repository local à votre repository sur github. Vous devriez obtnir un message de ce type :
    Énumération des objets: 5, fait.
    	Décompte des objets: 100% (5/5), fait.
    	Compression par delta en utilisant jusqu'à 8 fils d'exécution
    	Compression des objets: 100% (4/4), fait.
    	Écriture des objets: 100% (5/5), 113.50 Kio | 1.04 Mio/s, fait.
    	Total 5 (delta 0), réutilisés 0 (delta 0), réutilisés du pack 0
    	To github.com:yvandouenel/tpgit01.git
    	 * [new branch]      main -> main
    	la branche 'main' est paramétrée pour suivre 'origin/main'.

Cycle de vie d'un projet géré avec git flow

Git flow est un flux de travail (workflow) pour git. Git flow part du principe qu'il est nécessaire de créer plusieurs branches :

  • main ou master est la branche sur laquelle se trouvera le code abouti et c'est donc la version en production
  • develop est la branche sur la quelle on travaille pour les améliorations de faibles importance
  • les branches de features permettent aux codeurs de développer des fonctionnalités (features) plus importantes, qui vont prendre plus de temps.

Git flow fait intervenir la notion de tag et de changelog. Un tag permet de repérer un point marquant dans l'historique de git. Il se crée en général quand on décide de fusionner (merge) la branche develop avec la branche main. Le fichier txt (ou md) changelog est un sommaire des différentes changements opérés sur votre branche main. Voici à quoi peut ressembler un début de fichier changelog :

version 0.1.0 - 8/03/2021
----------------------------
Le cv de Jason avec bootstrap 5 et un js pour donner l'illusion d'une écriture en temps réél

branches

Initialiser git flow

git flow init

Répondre aux questions de la façon suivante :

Which branch should be used for bringing forth production releases?
   - main
Branch name for production releases: [main] 
Branch name for "next release" development: [develop] 
How to name your supporting branch prefixes?
Feature branches? [feature/] 
Bugfix branches? [bugfix/] 
Release branches? [release/] 
Hotfix branches? [hotfix/] 
Support branches? [support/] 
Version tag prefix? [] 
Hooks and filters directory? [/home/yvan/Dropbox/Formation/Diginamic/2022/git/.git/hooks]

Les commandes de base avec git flow

Ajouter une branche de fonctionnalité : 

git flow feature start nomdelafonctionnalite

Fusionner (merge) une branche de fonctionnalité

git flow feature finish nomdelafonctionnalite

Etapes pour créer une nouvelle version du logiciel que l'on utilisera en production (la premiere est en général la v0.1.0)

git flow release start x.x.x
// Création ou modification du fichier changelog.txt cf plus haut
// commit du fichier changelog.txt
git flow release finish 'x.x.x'
git push --tags
git push
git push origin main

Hotfix : pour ajouter rapidement une modification sur la branche main qui sera également répercutée sur develop

// Attention, commencer la hotfix avant de modifier les fichiers
// le numéro de hotfix doit être cohérent avec le fichier changelog.txt
git flow hotfix start 0.1.2
// Modification à opérer en urgence
// add et commit de la modification
// Modification du fichier changelog
// add et commit de la modification de changelog
git flow hotfix finish '0.1.2'
git push --tags
git push
git push origin main

 

Interface et fonctionnalités sur github.com

  • Rendez-vous sur votre repository distant (type https://github.com/yvandouenel/tpgit01)
  • Trouvez dans l'interface comment on passe d'un branche à l'autre, d'un répertoire à l'autre et comment on visualise les fichiers ainsi que leur historique
  • Trouvez comment voir la différence entre deux commits successifs (cf bouton sha)
  • Trouvez comment voir la différence entre deux commits non successifs en utlisant la comparaison du type : https://github.com/yvandouenel/tpgit01/compare/5c6c4b0de2c18945408cdd8a952add8c2f439bc5..ac7633616972cd53890512a05c540245b2f160e1
  • Trouvez le moyen d'ajouter un "collaborateur" à l'un de vos repository sur l'interface de github

Premières manipulations

Créer un nouveau répertoire "testgit" dans ~/dev/ et se positionner dedans en ligne de commande

cd ~/dev

mkdir testgit

cd testgit/

Créer le dépot git

git init

Créer un fichier test.txt

nano test.txt

puis écrire "Ceci est un test" puis ctrl + x pour fermer puis entrer pour enregistrer

Voir ce qu'il y a de nouveau dans le dépot git 

git status

Ajouter le fichier test.txt avant commit

git add test.txt

Commiter avec le message d'explication : "Ceci est mon premier commit"

git ci -m "Ceci est mon premier commit."

Envoyer sur le serveur

git push

Vérifier que le dépot est "propre"

git st

Récupérer les fichiers  depuis le serveur github

git clone https://github.com/yvandouenel/xxx.git

Principaux alias

git config --global alias.st 'status'
git config --global alias.ci 'commit'
git config --global alias.co checkout
git config --global alias.br branch

Configuration

Ajouter la couleur

git config color.ui true

Ajouter du temps durant lequel on aura pas besoin de s’identifier à nouveau : 

git config --global credential.helper "cache --timeout 7200"

Ne pas prendre en compte les changements sur les droits des fichiers :

nano .git/config filemode = false

Pour aller plus loin ...

Fork

Un fork est une copie d'un dépôt. Créer un fork vous permet d'expérimenter librement des modifications sans affecter le projet d'origine.

L'avantage du fork est que vous pouvez proposer des commits que vous avez réalisés au dépôt d'origine avec un mécanisme de pull requests.
 

Explications sur fork

Pull request

  1. Trouver un repository sur github sur lequel vous voulez contribuer
  2. Faire un "Fork"
  3. Cloner le "fork" en local 
  4. Créer une nouvelle branche (develop par exemple si elle n'existe pas)
  5. Opérer les changement et les pousser (sur votre "fork")
  6. Pousser sur votre "fork"
  7. Se rendre sur l'interface de github et cliquer sur le bouton "Compare & pull request"
  8. Cliquer sur le bouton "Create pull request"
  9. Attendre que le "reviewer" accepte votre code ou vous demande de le modifier
     

Explications sur pull request

Revenir en "arrière"

Les différentes façons de revenir vers un ancien "commit"

Notion de HEAD

HEAD est le nom symbolique pour le commit sur lequel nous nous situons actuellement , c'est le commit sur lequel nous travaillons.HEAD pointe toujours vers le dernier commit de la branche actuelle. Si vous changez de branche, HEAD se mettra à jour pour pointer vers le dernier commit de la nouvelle branche.


HEAD détaché

Si vous extrayez un commit spécifique au lieu d'une branche, vous serez dans un état "HEAD détaché". Dans cet état, HEAD pointe directement vers un commit, pas vers une branche. Cela signifie que si vous effectuez de nouveaux commits, ils n'appartiendront à aucune branche et seront perdus lorsque vous extrayez une autre branche ou commitez.

Être dans un état « HEAD détaché » dans Git peut être utile dans certaines situations, telles que :

  • Explorer l'historique : si vous souhaitez explorer l'historique de votre projet sans affecter aucune branche, vous pouvez extraire un commit spécifique dans un état HEAD détaché. Cela vous permet de regarder autour de vous et de voir à quoi ressemblait le code à ce moment-là sans apporter de modifications susceptibles d'affecter vos branches.
  • Création d'une nouvelle branche à partir d'un commit spécifique : si vous trouvez un commit à partir duquel vous souhaitez démarrer une nouvelle branche, vous pouvez extraire ce commit, puis créer une nouvelle branche. Ceci est utile si vous souhaitez créer une branche qui commence à partir d'un point de l'historique qui n'est pas la dernière validation sur une branche existante.
  • Revenir à un état précédent : si vous devez rétablir l'état d'une validation précédente de votre projet, vous pouvez extraire cette validation dans un état HEAD détaché, puis créer une nouvelle branche à partir de là. Cela vous permet de créer une branche qui part de l'état précédent, que vous pouvez ensuite fusionner à nouveau dans votre branche principale ou avec laquelle travailler selon vos besoins.
  • Débogage : parfois, vous souhaiterez peut-être déboguer votre code à un moment précis. L'extraction d'un commit dans un état HEAD détaché vous permet de le faire sans affecter l'état actuel de vos branches.
  • Expérimentation temporaire : si vous souhaitez expérimenter des modifications sans les valider dans une branche, vous pouvez extraire une validation dans un état HEAD détaché et apporter des modifications expérimentales. Si l'expérience réussit, vous pouvez créer une nouvelle branche à partir du commit modifié.
  • Révision du code : si vous devez réviser le code d'une validation précédente, vous pouvez extraire cette validation dans un état HEAD détaché pour examiner le code sans affecter votre travail en cours.

Commandes pour passer en mode détaché

On peut d'abord commencer par voir l'historique des commits via la commande git log :

git log
commit ca7bc49c7a8ec7aef74b4fb9a3588710598cf322
Author: yvandouenel <y.douenel@coopernet.fr>
Date:   Wed Feb 14 11:57:27 2024 +0100

    Ajout du mode dark.

Pour passer en mode détaché, il faut utiliser la commande checkout suivi de l'identifiant du commit :

git checkout ca7bc49c7a8ec7aef74b4fb9a3588710598cf322

Commandes pour revenir en mode non-détaché

Si vous êtes dans un état HEAD détaché et que vous souhaitez revenir à un état HEAD non détaché, vous pouvez suivre ces étapes :

  • checkout sur la branche sur laquelle vous souhaitez accéder : utilisez la commande "git checkout" suivie du nom de la branche vers laquelle vous souhaitez basculer. Cela vous ramènera à la branche et toutes les modifications que vous avez apportées alors que vous étiez dans l'état HEAD détaché seront perdues à moins que vous ne créiez une nouvelle branche ou que vous ne les validiez dans une branche existante.
    git checkout <nom-branche>

Si vous avez apporté des modifications et souhaitez les conserver : Avant d'opérer un "checkout" vers une autre branche, vous pouvez créer une nouvelle branche et y valider vos modifications.

    git checkout -b <nouveau nom de branche>
    git ajouter .
    git commit -m "Message de validation"

Fetch

Explications sur fetch

Rebase

Explications sur rebase

Travaux pratiques

Télécharger le tp au format open office

Télécharger le tp au format pdf (risques de pb de copies du code)