Références
git :
- doc officielle : https://git-scm.com/doc
- https://grafikart.fr/tutoriels/git-presentation-1090#autoplay
git flow : https://www.atlassian.com/fr/git/tutorials/comparing-workflows/gitflow-workflow
Exercices : https://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
Repository local vs distant (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.
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
- Cliquez sur le bouton vert "Create repository" pour obtenir l'interface suivante :
- 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
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.
Pull request
- Trouver un repository sur github sur lequel vous voulez contribuer
- Faire un "Fork"
- Cloner le "fork" en local
- Créer une nouvelle branche (develop par exemple si elle n'existe pas)
- Opérer les changement et les pousser (sur votre "fork")
- Pousser sur votre "fork"
- Se rendre sur l'interface de github et cliquer sur le bouton "Compare & pull request"
- Cliquer sur le bouton "Create pull request"
- Attendre que le "reviewer" accepte votre code ou vous demande de le modifier
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
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)