Utiliser Git et GitHub
Pour partager un code et faciliter la collaboration, le suivi des modifications et la sauvegarde de votre projet, GitHub est l’une des solutions les plus populaires.
GitHub se distingue par sa facilité d’utilisation et ses fonctionnalités de gestion de projets open source ou privés.
Dans cet article, vous trouverez les étapes essentielles pour déposer un projet sur GitHub depuis une distribution Linux.
De l’installation de Git à la configuration de votre dépôt local, vous découvrirez comment structurer efficacement vos fichiers pour un suivi optimal et comment pousser votre travail vers un dépôt distant.
Déposer un projet sur GitHub depuis une distribution linux
Pour déposer un projet sur GitHub depuis votre distribution linux, vous pouvez suivre les étapes suivantes :
1. Installer Git (si ce n’est pas déjà fait)
(pour savoir si git est installé 🙂
git --versionOuvrez un terminal et tapez :
sudo apt update
sudo apt install git2. Configurer Git avec votre nom d’utilisateur et votre email GitHub
git config --global user.name "Votre Nom"
git config --global user.email "votre_email@example.com"3. Initialiser le dépôt Git dans votre projet
Accédez au répertoire de votre projet et initialisez un dépôt Git :
cd /chemin/vers/votre/projet
git init4. Ajouter les fichiers à votre dépôt Git
git add .5. Créer un commit
git commit -m "Initial commit"6. Créer un dépôt sur GitHub
- Allez sur GitHub et connectez-vous.
- Cliquez sur le bouton « New repository ».
- Donnez un nom à votre dépôt, ajoutez une description si vous le souhaitez, et cliquez sur « Create repository ».
7. Lier votre dépôt local au dépôt distant GitHub
Copiez l’URL du dépôt GitHub (par exemple, https://github.com/votre_nom_utilisateur/votre_depot.git) et tapez :
git remote add origin https://github.com/votre_nom_utilisateur/votre_depot.gitLa commande git remote permet de lister et gérer les dépôts distants auxquels votre dépôt local est lié.
git remote -vUtilisez cette commande pour afficher les dépôts distants et leurs URLs.
La commande git remote get-url origin vous permet de récupérer l’URL du dépôt distant associé à un alias (souvent origin).
git remote get-url originCela est utile pour vérifier l’URL distante de votre dépôt Git.
8. Pousser votre projet sur GitHub
git push -u origin master # '-u' = '--set-upstream'Récapitulatif des commandes :
sudo apt update
sudo apt install git
git config --global user.name "Votre Nom"
git config --global user.email "votre_email@example.com"
cd /chemin/vers/votre/projet
git init
git add .
git commit -m "Initial commit"
git remote add origin https://github.com/votre_nom_utilisateur/votre_depot.git
git push -u origin masterEt voilà, votre projet est maintenant déposé sur GitHub.
Cloner un dépôt GitHub en local
1. Installer Git (si ce n’est pas déjà fait)
Si Git n’est pas installé sur ta machine, vous pouvez le télécharger et l’installer à partir de git-scm.com. Assurez-vous que Git est bien configuré en exécutant la commande suivante dans un terminal :
git --versionCela devrait afficher la version de Git installée.
2. Cloner le dépôt GitHub
Une fois Git installé, ouvrez un terminal (ou une invite de commandes) et exécutez la commande suivante pour cloner ton dépôt :
git clone https://github.com/VOTRE-NOM-DUTILISATEUR/NOM-DU-DEPOT.gitRemplacez VOTRE-NOM-DUTILISATEUR par votre nom d’utilisateur GitHub et NOM-DU-DEPOT par le nom du dépôt que vous voulez cloner.
3. Accéder au dépôt cloné
Après avoir cloné le dépôt, vous pouvez accéder au répertoire en tapant :
cd NOM-DU-DEPOT4. Utiliser le dépôt en local
Vous pouvez maintenant faire des modifications, créer des branches, ou synchroniser votre dépôt avec GitHub via des commandes comme :
git pull: pour récupérer les dernières modifications du dépôt distant.git add,git commit,git push: pour ajouter, valider et pousser vos modifications.
5. Remarque sur le pull
Un pull fait un merge.
Si il n’y a pas de nouveaux commit par rapport au remote, il fait un fast-forward.
Dans le cas inverse il fait une fusion avec un commit de merge.
Le pull est alors l’équivalent d’un git fetch && git merge origin/main
6. Différences entre Git Pull et Git Fetch
Git Fetch
- Fonctionnement :
git fetchrécupère les nouvelles données du dépôt distant (tous les commits, branches, et tags) sans les intégrer automatiquement dans votre branche de travail. - Utilité : Permet de voir les modifications distantes sans altérer votre environnement local. Idéal pour examiner les changements avant de les appliquer.
git fetch originGit Pull
- Fonctionnement :
git pullcombine ungit fetchsuivi d’unmerge. Il récupère les modifications distantes et les fusionne dans votre branche locale. - Utilité : Permet d’intégrer rapidement les modifications distantes dans votre travail local. Cependant, cette méthode peut créer des commits de fusion non désirés.
git pull originRebaser avec Git Fetch (Pull Rebase)
Le rebase avec pull --rebase permet de placer vos modifications locales au-dessus des commits distants, conservant ainsi un historique plus linéaire et évitant les commits de fusion inutiles.
Étapes pour faire un pull avec rebase en utilisant fetch
Récupérez les modifications distantes avec fetch :
git fetch origin2. Appliquez un rebase pour intégrer les modifications distantes sans créer de commit de fusion :
git rebase origin/mainRemplacez main par le nom de votre branche si nécessaire.
Effectuer un Pull Rebase Directement
Pour combiner le fetch et le rebase en une seule commande, utilisez git pull --rebase :
git pull --rebase origin mainCela remet tes commits au-dessus des commits distants, proprement, sans créer un merge inutile. Çela garde un historique propre et lisible.
Avantages du Pull Rebase
- Historique linéaire : Maintient un historique de commits ordonné sans commits de fusion inutiles.
- Prévention des conflits : Vous pouvez traiter les conflits étape par étape pendant le rebase, ce qui simplifie la gestion des modifications avant de les pousser.
Mise en situation :
Imaginez que vous et un collègue ayez travaillé en même temps sur la même branche.
Votre collègue a poussé ses commits sur GitHub, et vous avez fait des commits en local.
Votre historique a divergé.
Voici ce qui se passe dans les deux cas :
La méthode par défaut : git pull (avec Merge)
Git va prendre les commits de GitHub et les fusionner avec vos commits locaux.
Pour cela, il crée un commit spécial appelé « Commit de fusion » (Merge Commit).
- Le résultat visuel : Votre historique ressemble à une voie ferrée qui se divise en deux branches avant de se rejoindre.
- L’inconvénient : Si vous êtes plusieurs à travailler, votre historique GitHub va être pollué par des dizaines de messages du type « Merge branch ‘main’ of github.com…« . L’historique devient difficile à lire.
La méthode propre : git pull –rebase
Le rebase change complètement la donne. Au lieu de fusionner les deux histoires, Git va temporairement « mettre de côté » vos commits locaux non publiés, appliquer les nouveaux commits venus de GitHub, puis ré-empiler vos commits un par un par-dessus. Voici la séquence exacte en coulisses :
- Sauvegarde temporaire: Étape 1.
Git met vos commits locaux (ceux que vous n’avez pas encore poussés sur GitHub) dans une zone de mémoire temporaire. Votre branche locale revient temporairement à l’état où elle était avant vos modifications. - Mise à jour: Étape 2.
Git télécharge et applique les commits de vos collègues qui sont sur GitHub. Votre branche locale est maintenant parfaitement synchronisée avec le serveur. - Ré-application: Étape 3.
Git reprend vos commits mis de côté et tente de les appliquer, un par un, au bout de la file. C’est ici que l’historique est réécrit : la « base » de départ de vos commits a changé.
Pourquoi utiliser git pull –rebase ? (Les avantages)
- Un historique rectiligne : Plus aucun « commit de fusion » inutile. Votre historique de commits devient une seule ligne droite, propre et parfaitement chronologique.
- Facilité de lecture : Pour un MLOps ou un Product Manager qui inspecte le code, c’est un bonheur. On voit exactement qui a fait quoi, sans les nœuds créés par les fusions de branches.
- Idéal pour le Git Flow quotidien : C’est la commande reine lorsque vous travaillez sur une branche partagée et que vous voulez simplement vous mettre à jour avant de faire un `git push`.
⚠️ Le point de vigilance (Gestion des conflits)
Si votre collègue et vous avez modifié la même ligne du même fichier :
- Avec un git pull classique, vous gérez tous les conflits en une seule fois dans le commit de fusion.
- Avec –rebase, vous gérez les conflits commit par commit. Si vous avez 5 commits en retard, Git s’arrêtera au premier commit conflictuel. Vous devrez corriger la ligne, taper git add , puis exécuter git rebase –continue pour passer au commit suivant.
Règle d’or : Le rebase réécrit l’historique. Vous pouvez l’utiliser sans aucune crainte lors d’un pull car vous ne réécrivez que votre historique local (les commits qui n’ont pas encore été partagés avec le reste du monde).
Utilisation de la commande git status
La commande git status est utilisée pour obtenir un état instantané du répertoire de travail dans Git. Elle vous permet de voir les fichiers qui ont été modifiés, ajoutés ou supprimés, ainsi que l’état de ces modifications par rapport à l’index (staging area) et le dernier commit.
Ce que git status affiche:
- Fichiers dans le répertoire de travail :
- Modifiés mais non ajoutés à la zone de staging : Git vous montre les fichiers qui ont été modifiés dans votre répertoire de travail mais qui n’ont pas encore été ajoutés à la zone de staging avec
git add.
Ils apparaissent sous une section généralement intitulée « Changes not staged for commit ».
- Modifiés mais non ajoutés à la zone de staging : Git vous montre les fichiers qui ont été modifiés dans votre répertoire de travail mais qui n’ont pas encore été ajoutés à la zone de staging avec
- Fichiers dans la zone de staging (staged) :
- Prêts à être commités : Les fichiers qui ont été modifiés et ensuite ajoutés à la zone de staging avec
git addapparaissent dans une section intitulée « Changes to be committed ».
Ces fichiers sont prêts à être validés (committed) avec la commandegit commit.
- Prêts à être commités : Les fichiers qui ont été modifiés et ensuite ajoutés à la zone de staging avec
- Fichiers non suivis (untracked files) :
- Les fichiers nouveaux ou non suivis qui n’ont jamais été ajoutés au suivi par Git s’affichent dans une section intitulée « Untracked files ».
Ces fichiers ne sont pas encore pris en compte par Git tant que vous ne les ajoutez pas avecgit add.
- Les fichiers nouveaux ou non suivis qui n’ont jamais été ajoutés au suivi par Git s’affichent dans une section intitulée « Untracked files ».
Exemple d’utilisation
git statusCe qui pourrait afficher quelque chose comme ceci :
On branch master
Your branch is up to date with 'origin/master'.
Changes to be committed:
(use "git restore --staged ..." to unstage)
modified: fichier1.txt
new file: fichier2.txt
Changes not staged for commit:
(use "git add ..." to update what will be committed)
(use "git restore ..." to discard changes in working directory)
modified: fichier3.txt
Untracked files:
(use "git add ..." to include in what will be committed)
fichier4.txtCe que cela signifie :
On branch master: Vous êtes actuellement sur la branchemaster.Your branch is up to date with 'origin/master'.: La branche locale est à jour avec la branche distanteorigin/master.Changes to be committed:Ces fichiers sont dans la zone de staging (staged) et prêts à être commités :fichier1.txta été modifié et ajouté à la zone de staging.fichier2.txtest un nouveau fichier qui a été ajouté à la zone de staging.
Changes not staged for commit:Ces fichiers ont été modifiés, mais n’ont pas encore été ajoutés à la zone de staging :fichier3.txtest modifié mais non staged.
Untracked files:Ces fichiers sont nouveaux et non suivis par Git :fichier4.txtest un fichier qui n’est pas encore suivi et qui n’a pas été ajouté à la zone de staging.
Actions courantes après git status :
- Pour ajouter des fichiers modifiés à la zone de staging :
git add fichier3.txt- Pour committer les changements :
- Une fois que les fichiers sont dans la zone de staging, vous pouvez valider (committer) les changements :
git commit -m "Message de commit"- Pour ajouter des fichiers non suivis (untracked) :
git add fichier4.txtRésumé :
git statusvous donne une vue claire de l’état de tes fichiers dans Git.- Il montre les fichiers modifiés, les fichiers prêts à être commités et les fichiers non suivis.
- Cette commande est essentielle pour vérifier ce qui est prêt pour le prochain commit ou pour voir les changements en cours dans ton projet.
Explorer l’historique Git
Git permet de suivre les changements effectués dans un projet via un historique des commits. Voici quelques commandes utiles pour naviguer dans cet historique :
1. Afficher l’historique avec git log --pretty=oneline
Cette commande permet d’afficher l’historique des commits de manière concise, en affichant chaque commit sur une seule ligne :
git log --pretty=onelineElle montre le hash abrégé du commit suivi du message de commit. Cela est très pratique pour avoir une vue d’ensemble rapide des changements.
2. Créer un alias pour cette commande avec git config
Vous pouvez configurer un alias pour cette commande afin de l’utiliser plus rapidement. Par exemple, en créant l’alias git lo :
git config --global alias.lo 'log --pretty=oneline'Dès lors, vous pourrez taper git lo pour obtenir le même résultat que git log --pretty=oneline.
3. Utiliser git log -p pour voir les différences
Pour visualiser les différences (ou diffs) entre les versions de chaque fichier modifié dans l’historique, utilisez :
git log -pCela montre les détails des changements ligne par ligne pour chaque commit, en affichant ce qui a été ajouté ou supprimé dans chaque fichier.
4. Utiliser git log --oneline --graph --name-status pour voir chaque commit sous forme de graphe
ubuntu@ip-172-31-16-75:~/repo$ git log --oneline --graph --name-status
* d5f7e2a (HEAD → modif-doc) message de branche
| M doc.txt
* 88628b3 (master) Ajout de ligne
| M doc.txt
* b0ca7d6 Ajout du fichier de documentation
A doc.txt5. Voir les détails d’un commit avec git show
Si tu souhaites voir les détails d’un commit spécifique, par exemple les fichiers modifiés et les changements appliqués, tu peux utiliser la commande suivante :
git show <hash_du_commit>Remplace <hash_du_commit> par le hash du commit que tu veux inspecter. Cette commande affiche les changements complets pour ce commit.
Voir les différences entre différentes zones
git diff
Cette commande montre ce qui a changé dans les fichiers locaux et qui n’a pas encore été ajouté à l’index (ou zone de staging).
git diff git diff –staged
Cette commande montre les modifications qui ont été ajoutées à la zone de staging avec git add, mais qui n’ont pas encore été validées (committed).
git diff --stagedComparer deux commits spécifiques
Cette commande montre les différences entre deux commits spécifiques dans l’historique Git.
git diff <commit1> <commit2><commit1> et <commit2> sont les identifiants (SHA-1) ou références des commits.
Voir les différences locales pour un fichier modifié :
Cette commande montre les différences non commités entre les fichiers locaux modifiés et la version qui est déjà commitée dans la branche master
git diff src/blog/config.py
git diff src/templates/page.htmlComparer avec la branche distante origin/master :
Cette commande montre les difference entre les fichiers locaux et les fichiers actuels dans la branche origin/master (sur le dépôt distant)
git diff origin/master -- src/blog/config.py
git diff origin/master -- src/templates/page.htmlVoir les différences entre deux commits pour un fichier spécifique :
Cette commande montre les difference entre les fichiers locaux et les fichiers actuels dans la branche origin/master (sur le dépôt distant)
git diff 1a2b3c4d 5e6f7g8h -- src/main.pyLes branches
1. Créer une nouvelle branche et basculer immédiatement dessus.
C’est un raccourci pour deux commandes : git branch <nom_de_branche> (création) suivi de git checkout <nom_de_branche> (basculement).
Exemple :
git checkout -b nouvelle_brancheCette commande crée une nouvelle branche appelée nouvelle_branche et change la branche actuelle vers cette nouvelle branche.
2. Lister, créer ou supprimer des branches Git.
Usage :
- Lister les branches :
git branch- Créer une nouvelle branche sans basculer dessus :
git branch nom_de_branche- Supprimer une branche locale :
git branch -d nom_de_branche3. Bascule entre les branches dans un dépôt Git.
Exemple :
git switch develop4. Comparer des branches
La commande git diff permet de comparer les différences entre deux branches.
- Comparer deux branches :
git diff brancheA brancheBCela montre les différences (ajouts/suppressions) entre les branches brancheA et brancheB.
- Comparer une branche avec la branche actuelle :
git diff brancheBSi vous êtes sur brancheA, cela montre les différences avec brancheB.
- Options supplémentaires : Pour obtenir un résumé des fichiers modifiés sans voir le contenu exact :
git diff brancheA brancheB --stat5. Pousser une branche vers origin/master
Cette commande pousse la nouvelle branche locale vers origin/master.
git push -u origin nom_de_brancheRésumé général :
git checkout -b: Crée une nouvelle branche et bascule dessus.git branch: Liste, crée ou supprime des branches.git checkout: Change de branche dans le dépôt.git diff: Compare les différences entre deux branches.
Ces commandes sont utiles pour visualiser comment une branche diffère d’une autre avant de procéder à une fusion.
git merge et git rebase
1. git switch -c mabranche
But : Crée une nouvelle branche nommée mabranche et bascule immédiatement sur celle-ci.
C’est un raccourci pour deux commandes : git branch mabranche (création de la branche) suivi de git switch mabranche (basculement sur la nouvelle branche).
Exemple :
it switch -c mabrancheCela crée une nouvelle branche appelée mabranche et passe dessus automatiquement. C’est une manière pratique de démarrer une nouvelle branche de travail directement à partir de la branche courante.
git switch --track origin/labranchedistanteCela crée une nouvelle branche locale basée sur la branche distante appelée labranchedistante et passe dessus automatiquement. C’est une manière pratique de démarrer une nouvelle branche de travail directement à partir de la branche distante.
2. git merge
But : Fusionne une branche source (par exemple mabranche) dans la branche courante (par exemple main).
Cela combine les modifications de deux branches en une seule.
Exemple :
git switch main
git merge mabrancheFast-forward merge : Si la branche main n’a pas de nouveaux commits par rapport à mabranche, Git effectuera un « fast-forward ».
3. git merge –no-ff
But : Force la création d’un commit de fusion, même si un « fast-forward » est possible.
Cela garde un historique clair de la fusion, avec un commit de merge dédié.
Exemple :
git switch main
git merge --no-ff mabranche4. Exemples concrets : git merge et git merge –no-ff
Exécution de git merge (fast-forward possible) :
git switch main
git merge mabrancheSi mabranche contient 3 commits et que main n’a pas de nouveaux commits depuis que mabranche a divergé, Git peut effectuer une fusion fast-forward.
Cela signifie que Git avance simplement la branche main jusqu’au dernier commit de mabranche sans créer de commit de fusion.
L’historique après un fast-forward ressemblerait à ceci :
* Commit 3 (mabranche)
* Commit 2 (mabranche)
* Commit 1 (mabranche)
* Commit 2 (main)
* Commit 1 (main)
Dans ce cas, l’historique est linéaire, comme si les commits de mabranche avaient été effectués directement dans main, car il n’y a eu aucun travail supplémentaire dans main.
Aucun commit de fusion n’est créé.
Exécution de git merge –no-ff (force la création d’un commit de fusion) :
git switch main
git merge --no-ff mabrancheMême si une fusion fast-forward est possible, l’option –no-ffforce la création d’un commit de fusion. Cela permet de conserver une trace explicite de la fusion dans l’historique.
L’historique après une fusion avec –no-ff ressemblerait à ceci :
* Commit de fusion
|\
| * Commit 3 (mabranche)
| * Commit 2 (mabranche)
| * Commit 1 (mabranche)
* | Commit 2 (main)
* | Commit 1 (main)
Différences clés entre git merge et git merge –no-ff :
- git merge (fast-forward) : Si aucun commit n’a été fait sur main après la divergence avec mabranche, Git avance simplement main pour pointer vers le dernier commit de mabranche. Cela ne crée pas de commit de fusion et l’historique reste linéaire.
- git merge –no-ff : Même lorsque Git pourrait avancer la branche avec un fast-forward, l’option –no-ff force la création d’un commit de fusion, ce qui rend l’historique plus explicite en montrant qu’une branche a été fusionnée.
Pourquoi utiliser –no-ff ?
Clarté de l’historique : L’option –no-ff est utile pour garder une trace visible de la fusion des branches. Cela permet de voir clairement dans l’historique que deux branches distinctes ont été combinées, même si la fusion aurait pu se faire en fast-forward.
5. git rebase
But : Applique les commits d’une branche sur une autre, en les repositionnant au sommet de la branche cible.
Exemple :
git switch mabranche
git rebase mainCas d’utilisation :
Lorsqu’une branche de fonctionnalité doit intégrer les changements récents d’une branche principale, le rebase permet de « mettre à jour » cette branche sans ajouter de commit de fusion.
6. git merge –abort
But : Annule une fusion en cours si quelque chose ne va pas (comme des conflits complexes).
Exemple :
git merge --abort7. Résolution des conflits
Lorsque tu fais un git merge ou un git rebase, il peut y avoir des conflits. Voici comment les résoudre :
Comment identifier un conflit :
Auto-merging fichier.txt
CONFLICT (content): Merge conflict in fichier.txtÉtapes pour résoudre les conflits :
- Ouvre les fichiers en conflit et modifie les parties voulues.
- Supprime les marqueurs de conflit (
<<<<<<< HEAD,=======,>>>>>>>). git add fichier_conflit.txt- Finalise la fusion avec
git commitou le rebase avecgit rebase --continue.
8. Différence entre Merge et Rebase en Git
Lors de la gestion de branches avec Git, deux méthodes populaires pour intégrer des changements d’une branche dans une autre sont le merge et le rebase. Chacune de ces méthodes a ses avantages selon les besoins et la situation.
Merge : Fusion de branches
Le merge (fusion) est l’approche la plus courante pour intégrer les changements d’une branche à une autre.
Cette méthode crée un commit de merge, qui enregistre une nouvelle étape dans l’historique en combinant les deux branches, tout en préservant leur historique.
Cela signifie que l’historique des commits reste intact, avec une trace claire du moment où les branches ont divergé et convergé.
L’historique après un commit de merge ressemblerait à ceci :
* Commit de fusion
|\
| * Commit 3 (mabranche)
| * Commit 2 (mabranche)
| * Commit 1 (mabranche)
* | Commit 2 (main)
* | Commit 1 (main)
- Avantages :
- L’historique de la branche reste intact, ce qui rend facile de suivre l’évolution du projet.
- Le processus est simple et rapide pour intégrer les changements.
- Utile lorsque vous voulez conserver l’historique complet des commits pour un suivi transparent.
- Inconvénients :
- Peut rendre l’historique plus complexe à lire, surtout avec beaucoup de branches et de commits.
Exemple :
git switch main
git merge feature-branchRebase : Réorganisation des commits
Le rebase réécrit l’historique en appliquant les commits d’une branche au-dessus de l’autre branche. Il permet de conserver un historique linéaire, sans commit de merge. Le rebase fait comme si tous les commits de la branche étaient appliqués à partir du dernier commit de la branche cible, donnant un historique plus propre.
* Commit 3 (mabranche)
* Commit 2 (mabranche)
* Commit 1 (mabranche)
* Commit 2 (main)
* Commit 1 (main)
- Avantages :
- Crée un historique linéaire, facile à suivre et à lire, sans commits de merge.
- Utile pour des projets avec beaucoup de collaborateurs où la clarté de l’historique est primordiale.
- Inconvénients :
- Réécrit l’historique, ce qui peut créer des conflits compliqués à gérer.
- Doit être utilisé avec précaution, surtout si la branche a déjà été partagée avec d’autres utilisateurs.
Exemple :
git switch feature-branch
git rebase mainQuand utiliser Merge ou Rebase ?
Merge est idéal pour les situations où vous souhaitez préserver l’historique des branches et lorsque l’importance est accordée à la traçabilité des branches divergentes.
Rebase est parfait pour maintenir un historique propre et linéaire, particulièrement utile dans des branches privées ou lors de la préparation de pull requests.
Conclusion
Choisir entre merge et rebase dépend principalement de vos préférences et des besoins de votre projet. Le merge est sûr et préserve tout l’historique, tandis que le rebase offre une vision plus claire et ordonnée de l’évolution du code, au prix de manipuler avec soin l’historique.
merge Fast-Forward ou Rebase ???
1. Le point de départ
git merge (Fast-Forward) : C’est un comportement automatique et passif.
Il ne peut se produire que si la branche cible (ex: main) n’a pas bougé (aucun nouveau commit) depuis que vous avez créé votre branche secondaire (ex: feature).
S’il y a le moindre commit en plus sur main, le Fast-Forward est techniquement impossible.
git rebase : C’est une action volontaire et active.
On l’utilise précisément lorsque la branche cible (main) A bougé. Le rebase sert à rattraper ce retard en réécrivant l’histoire.
2. Le mécanisme interne
Pour bien comprendre, imaginons que vous ayez créé une branche feature à partir de main.
Cas A : Le Fast-Forward (Pas de retard)
Pendant que vous travailliez sur feature, personne n’a touché à main.
Les deux branches partagent le même passé exact, feature a juste pris de l’avance.
L’action : Vous faites git switch main puis git merge feature.
Le mécanisme : Git constate qu’il n’y a aucun conflit possible. Il ne crée rien, ne modifie aucun commit. Il se contente de déplacer le pointeur (la balise) main tout au bout de votre branche feature.
Cas B : Le Rebase (Historique réécrit pour rattraper le retard)
Pendant que vous travailliez sur feature, un collègue a poussé 2 nouveaux commits sur main. Vous êtes « en retard ».
L’action : Vous faites git switch feature puis git rebase main.
Le mécanisme : Git va couper vos commits locaux de la branche feature, les mettre de côté, appliquer les 2 nouveaux commits de votre collègue sur votre branche, puis recréer (ré-empiler) vos commits par-dessus. Vos commits changent de base (d’où le nom re-base). Ils obtiennent un nouvel identifiant (SHA-1) : leur historique est réécrit.
3. Le cas d’usage combiné (Le flux de travail parfait)
En équipe, on n’oppose pas les deux, on les combine souvent pour garder un historique propre via cette routine :
Vous codez sur votre branche feature pendant que main évolue sur le serveur.
Avant de fusionner, vous faites un git rebase main sur votre branche. Vos commits sont ré-empilés tout au bout du projet. Votre branche est désormais alignée sur main, mais avec un coup d’avance.
Vous basculez sur main et vous faites un git merge feature. Comme vous avez fait le rebase juste avant, main n’a plus de retard : Git fait alors un Fast-Forward parfait pour aligner les pointeurs.
9. Les 4 modes de fusion
1. Le mode « Fast-Forward » (Le raccourci par défaut)
Le Fast-Forward (avance rapide) se produit automatiquement lorsque vous fusionnez une branche (ex: `feature`) dans votre branche principale (ex: `main`), et que **la branche principale n’a reçu aucun nouveau commit** depuis que vous avez créé la branche `feature`.
- Ce que fait Git : Il n’y a pas de conflit possible, l’historique est linéaire. Git ne s’embête pas à créer un commit de fusion.
Il se contente de déplacer le pointeur de la branche `main` tout au bout, pour l’aligner sur le dernier commit de la branche `feature`. - Le résultat : L’historique devient complètement plat. Visuellement, on ne sait même plus qu’une branche séparée a existé un jour.
2. Le mode `–no-ff` (Forcer le commit de fusion)
Parfois, même si l’historique est linéaire et qu’un Fast-Forward est possible, vous voulez garder une trace historique du fait que ces commits appartenaient à une fonctionnalité bien précise. C’est là qu’intervient `git merge –no-ff feature`.
- Ce que fait Git : Il refuse le raccourci. Il crée obligatoirement un commit de fusion (Merge Commit), ce qui force l’historique à dessiner une « bosse » (une branche qui s’ouvre et qui se referme).
- Le résultat : Vous conservez la mémoire de votre flux de travail. Si vous devez un jour annuler (revert) toute la fonctionnalité, il vous suffira d’annuler ce seul commit de fusion, plutôt que de devoir supprimer les commits individuels un par un.
Existe-t-il d’autres modes de fusion (merge) ?
Oui, Git propose d’autres stratégies et drapeaux majeurs pour fusionner le code. Voici les deux principaux que vous rencontrerez en équipe :
3. Le mode `–squash` (L’écrasement)
C’est le mode ultra-populaire sur GitHub lors de la validation des Pull Requests. Imaginez que sur votre branche feature, vous ayez fait 15 commits un peu brouillons (` »fix »`, ` »test2″`, ` »add file »`, ` »ca marche enfin »`). Vous ne voulez pas polluer la branche principale avec ces détails.
- Ce que fait Git : Il prend toutes les modifications apportées par vos 15 commits, les condense (les squashe) en un seul et unique commit géant, et applique ce gros commit sur la branche principale.
- Avantage : La branche principale reste d’une propreté absolue (1 commit = 1 fonctionnalité terminée).
4. Le mode –ff-only (La sécurité stricte)
C’est l’inverse de –no-ff. Vous dites à Git : « Fusionne la branche, mais SEULEMENT si tu peux le faire en avance rapide (Fast-Forward). Si l’historique a bougé et que tu dois créer un commit de fusion, refuse et bloque l’action ».
Pourquoi l’utiliser : C’est une excellente sécurité pour s’obliger (ou obliger ses scripts CI/CD) à faire un rebase d’abord pour s’assurer que tout est propre et aligné avant d’intégrer le code. —
Résumé pour vos choix en production (MLOps / Dev)
| Commande | Résultat sur l’historique | Quand l’utiliser ? |
|---|---|---|
git merge (Fast-Forward) |
Totalement plat et linéaire. | Pour des petits ajustements rapides ou des corrections locales. |
git merge --no-ff |
Une branche visible qui s’ouvre et se ferme avec un commit de fusion. | Pour des grosses fonctionnalités (permet d’isoler le groupe de commits). |
git merge --squash |
Un seul commit propre sur la branche cible, historique de la branche supprimé. | Le standard pour nettoyer les Pull Requests avant d’intégrer dans main. |
Résoudre les conflits lors de la synchronisation de votre dépôt local avec le dépôt distant. :
1. Stasher les modifications locales (Sauvegarde temporaire)
git stashSauvegarde temporairement les modifications locales.
2. Tirer les nouvelles modifications du dépôt distant
git pullRécupère les nouvelles modifications depuis le dépôt distant.
3. Appliquer les modifications stashées
git stash popRéapplique les modifications sauvegardées temporairement.
4. Résoudre les conflits
Ouvrir les fichiers en conflit, résoudre les conflits
<<<<<<< HEAD
Votre code local
=======
Le code provenant de la branche distante
>>>>>>> nom_de_branche_distantepuis les ajouter à l’index
git add src/blog/settings.py src/templates/base.html5. Valider la résolution des conflits
git commit -m "Résolution des conflits après le pull"Valide les modifications après résolution des conflits.
6. Pousser les modifications vers le dépôt distant
git push origin masterPublie les modifications résolues sur le dépôt distant.
Naviguer dans l’Historique Git
Git propose de nombreuses commandes pour naviguer, réécrire et ajuster l’historique d’un projet. Voici quelques-unes des commandes les plus utiles pour la gestion de l’historique :
1. Modifier le Dernier Commit : git commit --amend
La commande git commit --amend permet de modifier le dernier commit, que ce soit pour corriger le message, ajouter des fichiers oubliés, ou ajuster les modifications effectuées.
git commit --amend -m "Nouveau message pour le dernier commit"2. Gérer les Branches avec git branch
Pour travailler avec plusieurs versions du projet, vous pouvez créer des branches en utilisant git branch :
- Créer une nouvelle branche :
git branch - Lister toutes les branches :
git branch - Supprimer une branche :
git branch -d
3. Naviguer entre les Commits avec git checkout
- Pour passer d’une branche à une autre facilement :
git switch <nom_de_branche>- Pour revenir à un commit précis en utilisant son hash :
git checkout <hash_du_commit>- Accéder au commit immédiatement précédent :
git checkout^- Accéder à un commit trois niveaux en amont dans l’historique :
git checkout~34. Fusionner les derniers Commits avec git rebase -i
- Pour ajuster plusieurs commits à la fois,
git rebase -ipermet de réorganiser, éditer ou fusionner les derniers commits :
git rebase -i HEAD~4Ici, vous pourrez interagir avec les 4 derniers commits, en choisissant les actions à effectuer.
5. Créer un Commit Vide avec git commit --allow-empty
- Pour ajouter un commit vide, souvent utilisé pour déclencher des scripts ou pipelines automatisés :
git commit --allow-empty -m "Commit vide pour déclencher pipeline"6. Annuler les modifications locales dans le répertoire de travail
Si vous avez modifié un fichier mais n’êtes pas satisfait des changements, vous pouvez restaurer le fichier à son état dans l’index (zone de staging) avec git restore.
La commande git restore --worktree permet de rétablir un fichier à son état précédent ( –worktree est le comportement par défaut) :
git restore <nom_du_fichier>Cela remplace le contenu de nom_du_fichier dans le répertoire de travail par celui de l’index, annulant ainsi les modifications locales non validées.
7. Retirer des fichiers de l’index sans toucher aux fichiers locaux (unstage)
- Pour désindexer un fichier sans supprimer ses modifications locales :
git reset <nom_du_fichier>- Pour revenir à un état antérieur de l’historique sans toucher aux fichiers locaux :
git resetLa commande git restore --staged permet aussi de rétablir un fichier à son état précédent :
git restore --staged <nom_du_fichier>Cette commande supprime le fichier de la zone de staging sans le supprimer du répertoire de travail.
La commande Git Reset
La commande git reset est une des commandes Git les plus puissantes et potentiellement dangereuses si elle est mal utilisée. Elle permet de réécrire l’historique en déplaçant la référence de la branche actuelle (HEAD) vers un autre commit, tout en offrant un contrôle précis sur l’état de l’index (staging area) et du répertoire de travail (working directory).
Fonctionnalités principales de git reset
1. Déplacer HEAD vers un commit spécifique :
git reset [options] commit_hashCette commande réoriente la branche courante vers commit_hash, modifiant ainsi l’historique de cette branche.
2. Contrôler l’état de l’index et du répertoire de travail : Les options --soft, --mixed et --hard déterminent comment git reset affecte l’index et le répertoire de travail.
Options importantes :
--soft :
- Déplace
HEADvers le commit spécifié sans modifier l’index ni le répertoire de travail. - Conserve les modifications pour être revalidées.
Les modifications sont revenues à l’état staged.
git reset --soft commit_hash--mixed (par défaut) :
- Déplace
HEADet met à jour l’index pour qu’il corresponde au nouveauHEAD. - Les modifications non validées sont présentes dans le répertoire de travail mais ne sont pas indexées.
git reset --mixed commit_hash--hard :
EAD, met à jour l’index et le répertoire de travail pour qu’ils correspondent au nouveauHEAD.- Attention : Les modifications non validées seront perdues.
git reset --hard commit_hashExemples pratiques :
1. Annuler le dernier commit tout en conservant les modifications dans l’index :
git reset --soft HEAD~12. Annuler le dernier commit en conservant les modifications dans le répertoire de travail :
git reset --mixed HEAD~13. Réinitialiser complètement le projet à un état antérieur :
git reset --hard abc1234Diagramme des effets de git reset
Considérons une situation où HEAD pointe vers commit C avec des modifications non validées dans le répertoire de travail. Voici les effets des différentes options :
--soft :
Avant :
HEAD -> C
Index : C
Travail : C + modifications
Après `git reset --soft B` :
HEAD -> B
Index : C
Travail : C + modifications
--mixed :
Après `git reset --mixed B` :
HEAD -> B
Index : B
Travail : C + modifications
--hard :
Après `git reset --hard B` :
HEAD -> B
Index : B
Travail : B
Précautions à prendre
- Perte de données : L’utilisation de
git reset --hardpeut entraîner la perte définitive de modifications non validées. - Historique partagé : Évitez de réécrire l’historique des branches partagées.
Différences avec d’autres commandes
git revert: Annule les modifications d’un commit avec un nouveau commit sans réécrire l’historique.git checkoutetgit restore: Bascule entre les branches ou restaure des fichiers sans affecter l’historique des commits.
Conseils supplémentaires
- Visualiser l’historique : Utilisez
git log --oneline --graphpour visualiser les commits avant ungit reset. - Sauvegarder les modifications : Utilisez
git stashpour sauvegarder temporairement des changements non validés.
Cas d’utilisation courants
1. Annuler plusieurs commits locaux :
git reset --mixed HEAD~32. Nettoyer le répertoire de travail :
git reset --hardEn résumé :
git resetdéplaceHEADavec un contrôle sur l’index et le répertoire de travail.- Les options
--soft,--mixed, et--hardoffrent des choix selon les besoins. - Prudence : Vérifiez toujours les modifications non validées avant d’utiliser
git reset, surtout avec--hard.
Comprendre git clean dans Git
Lorsqu’on travailles avec Git, il y a deux types de fichiers dans ton dépôt :
- Fichiers suivi → ceux qui ont déjà été ajoutés avec
git addet qui font partie de l’historique Git. - Fichiers non suivis (untracked) → ceux qui existent dans ton répertoire de travail mais que Git ne connaît pas (par exemple : fichiers générés, résultats de tests, caches, notebooks temporaires, etc.).
- 👉 Problème : ces fichiers non suivis peuvent vite encombrer ton dépôt et rendre ton
git statusillisible. - 👉 Solution :git clean.
git cleanest une commande qui permet de supprimer définitivement les fichiers et dossiers non suivis par Git.- ⚠️ Attention : contrairement à
git resetougit restore, les fichiers supprimés pargit cleanne vont pas dans la corbeille → ils disparaissent réellement.
Les options principales
git clean -n→ dry-run : affiche la liste des fichiers/dossiers qui seraient supprimés, sans les effacer. (à utiliser en premier pour vérifier !)git clean -f→ supprime les fichiers non suivis.git clean -fd→ supprime les fichierset les dossiers non suivis.git clean -fx→ supprime aussi les fichiers ignorés par `.gitignore` (⚠️ dangereux si tu ignores volontairement des fichiers de config locale).git clean -fdx→ le mode grand ménage : supprime absolument tout ce qui n’est pas suivi par Git, y compris ce qui est ignoré.
Exemples pratiques
Vérifier avant d’agir :
git clean -nRésultat typique :
Would remove predictions/
Would remove docker-compose.yml- Supprimer uniquement les fichiers listés :
git clean -f- Supprimer fichiers et dossiers non suivis :
git clean -fd- Supprimer aussi ce qui est dans
.gitignore:
git clean -fdxBonnes pratiques
- ✅ Toujours tester avec
git clean -navant. - ✅ Vérifier si les fichiers sont commités sur une autre branche avant de nettoyer.
- ✅ Ne pas abuser de
-xsauf si tu veux vraiment tout purger (par ex. reconstruire ton projet depuis zéro).
Résumé
git clean= supprime les fichiers non suivis.-n= tester sans supprimer.-f= supprimer fichiers.-fd= supprimer fichiers + dossiers.-fdx= supprimer absolument tout (même ignoré).
Fonctionnement de .gitignore :
Le fichier .gitignore est utilisé par Git pour déterminer quels fichiers et répertoires doivent être ignorés dans un projet. Lorsqu’un fichier ou un répertoire est répertorié dans .gitignore, Git ne le suivra pas et ne l’ajoutera pas au dépôt. Cela est particulièrement utile pour exclure des fichiers temporaires, des fichiers de configuration locale, des fichiers générés automatiquement ou d’autres fichiers qui ne doivent pas être inclus dans le contrôle de version.
1. Création d’un fichier .gitignore
Vous pouvez créer un fichier .gitignore à la racine de votre projet (ou dans n’importe quel sous-répertoire) en utilisant un éditeur de texte.
Par exemple :
touch .gitignore2. Ajout de règles au fichier .gitignore
Vous pouvez spécifier les fichiers et répertoires à ignorer en ajoutant des règles dans le fichier .gitignore. Voici quelques exemples de règles courantes :
- Ignorer tous les fichiers d’un type spécifique :
*.log- Ignorer un répertoire spécifique et son contenu :
/node_modules- gnorer tous les fichiers dans un répertoire spécifique :
logs/- Ignorer des fichiers spécifiques :
secret.txt- Ignorer tous les fichiers sauf un dans un répertoire :
/directory/*
!/directory/important.txtExemples de .gitignore pour différents projets :
Projet Python/Django :
# Environnements virtuels
venv/
env/
# Fichiers de configuration locaux
.env
# Fichiers compilés Python
__pycache__/
*.py[cod]
# Journaux et fichiers temporaires
*.log
*.tmp
Projet Node.js :
# Modules Node
node_modules/
# Fichiers de logs
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Fichiers environnementaux
.env
Projet général :
# Fichiers temporaires
*.tmp
*.swp
# Fichiers de journalisation
*.log
# Systèmes d'exploitation spécifiques
.DS_Store
Thumbs.db
Important à savoir
- Les règles de
.gitignoresont spécifiques au répertoire où le fichier.gitignoreest placé.
Si vous avez un.gitignoredans un sous-répertoire, il sera appliqué uniquement aux fichiers et sous-répertoires de ce répertoire. - Si vous ajoutez une règle à
.gitignoreaprès que des fichiers ont déjà été ajoutés et suivis par Git, ces fichiers continueront d’être suivis.
Vous devrez les retirer du suivi avec la commandegit rm --cached <fichier>pour que Git commence à les ignorer. - Vous pouvez utiliser des commentaires dans le fichier
.gitignoreen commençant une ligne par le symbole#.
En résumé, le fichier .gitignore est un outil puissant pour gérer les fichiers et répertoires que vous ne souhaitez pas inclure dans votre dépôt Git, vous aidant ainsi à garder votre projet propre et organisé.