Le guide avancé de Git : Git Stash, Reset, Rebase, etc.

Publié: 2022-03-11

Chaque développeur doit avoir une bonne compréhension du contrôle de version, et Git est devenu la norme de facto pour le contrôle de version dans le développement de logiciels.

Souvent cependant, les développeurs n'apprennent que quelques commandes simples et négligent la puissance de l'historique Git et les autres choses que Git peut faire pour vous rendre beaucoup plus efficace. Par exemple, la gestion des versions est très facile avec Git en utilisant git tag .

J'ai suivi un cours avancé sur Git en ligne (avec Github) et j'ai ensuite enseigné un cours Git pour débutants en collaboration avec Github. Lorsque j'ai remarqué qu'il n'y avait pas beaucoup d'articles techniques sur mes fonctionnalités Git préférées, j'ai sauté sur l'occasion pour les partager avec mes collègues développeurs. Dans cet article, vous apprendrez à tirer parti des fonctions Git avancées suivantes :

  • git stash , qui effectue une sauvegarde locale temporaire de votre code
  • git reset , qui vous permet de ranger votre code avant de faire un commit
  • git bisect , une fonction qui permet de chasser les mauvais commits
  • git squash , qui vous permet de combiner vos commits
  • git rebase , qui permet d'appliquer les modifications d'une branche à une autre

Cachette Git

Git stash vous permet de sauvegarder votre code sans faire de commit. Comment est-ce utile? Imaginez le scénario suivant :

Vous avez déjà fait trois commits soignés et ordonnés, mais vous avez également du code non validé qui est assez désordonné ; vous ne voudrez pas le valider sans supprimer d'abord votre code de débogage. Ensuite, pour une raison quelconque, vous devez soudainement vous occuper d'une autre tâche et devez changer de branche. Cela peut souvent arriver si vous êtes sur votre branche main et que vous avez oublié de créer une nouvelle branche pour votre fonctionnalité. En ce moment, votre code ressemble à ceci :

 $ git status On branch my-feature Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory) modified: css/common.scss no changes added to commit (use "git add" and/or "git commit -a")
 $ git diff diff --git a/css/common.scss b/css/common.scss index 2090cc4..90fd457 100644 --- a/css/common.scss +++ b/css/common.scss @@ -13,6 +13,6 @@ body { font-family: "Proxima Nova", Arial, sans-serif; font-size: 13px; - color: #333; + color: red; background-color: #f00; }

Lorsque vous exécutez git stash , le code non validé disparaît sans être validé. Le stockage revient à enregistrer un commit local temporaire dans votre branche. Il n'est pas possible de pousser un stash vers un référentiel distant, donc un stash est juste pour votre usage personnel.

 $ git stash Saved working directory and index state WIP on my-feature: 49ee696 Change text color

Votre branche apparaît maintenant telle qu'elle était lorsque vous avez effectué votre dernier commit. Désormais, vous pouvez changer de branche en toute sécurité sans perdre votre code ni avoir un commit désordonné. Lorsque vous revenez à votre branche et que vous exécutez git stash list , vous verrez une liste de caches qui ressemble à ceci :

 $ git stash list stash@{0}: WIP on my-feature: 49ee696 Change text color

Vous pouvez facilement réappliquer le contenu stocké en exécutant git stash apply . Vous pouvez également appliquer un stash spécifique (si vous avez stashé plus d'une fois) en exécutant git stash apply stash@{1} (le '1' indique l'avant-dernier stash). Voici un exemple de stockage de plusieurs commits et d'application d'un stockage différent :

 $ git diff diff --git a/css/common.scss b/css/common.scss index 2090cc4..90fd457 100644 --- a/css/common.scss +++ b/css/common.scss @@ -13,6 +13,6 @@ body { font-family: "Proxima Nova", Arial, sans-serif; font-size: 13px; - color: #333; + color: red; background-color: #f00; } $ git stash Saved working directory and index state WIP on my-feature: 49ee696 Change text color $ git diff diff --git a/css/common.scss b/css/common.scss index 2090cc4..b63c664 100644 --- a/css/common.scss +++ b/css/common.scss @@ -13,6 +13,6 @@ body { font-family: "Proxima Nova", Arial, sans-serif; font-size: 13px; - color: #333; + color: red; background-color: #f00; } $ git stash Saved working directory and index state WIP on my-feature: 49ee696 Change text color
 $ git stash list stash@{0}: WIP on my-feature: 49ee696 Change text color stash@{1}: WIP on my-feature: 49ee696 Change text color stash@{2}: WIP on my-feature: 49ee696 Change text color $ git stash apply stash@{2} On branch my-feature Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory) modified: css/common.scss no changes added to commit (use "git add" and/or "git commit -a")

git stash apply stash@{2} a appliqué le code caché le plus ancien, lorsque nous avons changé la couleur du texte en rouge.

 $ git diff diff --git a/css/common.scss b/css/common.scss index 2090cc4..90fd457 100644 --- a/css/common.scss +++ b/css/common.scss @@ -13,6 +13,6 @@ body { font-family: "Proxima Nova", Arial, sans-serif; font-size: 13px; - color: #333; + color: red; background-color: #f00; }

Si vous décidez de ne pas valider votre travail une fois que vous avez restauré la réserve, vous pouvez exécuter git checkout . , qui réinitialise tout le code non validé.

Comme autre exemple d'utilisation de Git stash : disons que vous avez de nouveaux fichiers, dont l'un a un bogue. Laissez tout sauf le fichier de bogue suspecté non mis en scène (le code doit être mis en scène pour être stocké), vous pouvez ensuite stocker ce fichier et résoudre le problème. Si le fichier caché n'était pas le problème, vous pouvez restaurer la cachette.

 $ git status On branch my-feature Untracked files: (use "git add <file>..." to include in what will be committed) css/colors.scss nothing added to commit but untracked files present (use "git add" to track)
 $ git add css/colors.scss $ git stash Saved working directory and index state WIP on my-feature: 0d8deef delete colors $ git status On branch my-feature nothing to commit, working tree clean $ git stash apply stash@{0} On branch my-feature Changes to be committed: (use "git reset HEAD <file>..." to unstage) new file: css/colors.scss

Vous pouvez également transférer vos commits cachés vers une nouvelle branche de fonctionnalité ou une branche de débogage en utilisant git stash branch :

 $ git status On branch my-feature Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory) modified: css/common.scss no changes added to commit (use "git add" and/or "git commit -a") $ git stash Saved working directory and index state WIP on my-feature: 66f3f3b Add colors file $ git stash branch debugging-branch M css/common.scss Switched to a new branch 'debugging-branch' Unstaged changes after reset: M css/common.scss On branch debugging-branch Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory) modified: css/common.scss Dropped refs/stash@{0} (d140624f60d8deef7bceb0d11fc80ed4fd47e0a1)

Notez que lorsque vous avez appliqué un stash, le stash n'est pas supprimé. Vous pouvez supprimer les caches individuellement en utilisant git drop , ou supprimer toutes les caches en utilisant git stash clear :

 $ git stash list stash@{0}: WIP on my-feature: 66f3f3b Add colors file stash@{1}: WIP on my-feature: 0d8deef delete colors stash@{2}: WIP on my-feature: 49ee696 Change text color $ git stash drop stash@{2} Dropped stash@{2} (8ed6d2ce101aa2e28c8ccdc94cb12df8e5c468d6) $ git stash list stash@{0}: WIP on my-feature: 66f3f3b Add colors file stash@{1}: WIP on my-feature: 0d8deef delete colors $ git stash clear $ git stash list $

Réinitialiser Git

Si vous vous trouvez dans une situation où vous avez accidentellement commis un code désordonné, vous pouvez effectuer une réinitialisation "soft". Cela signifie que le code apparaît comme s'il n'avait pas encore été validé. Ensuite, vous pouvez ranger votre code dans votre IDE avant de faire un commit plus propre. Pour ce faire, vous pouvez exécuter git reset --soft HEAD~1 . Cela réinitialisera le commit le plus récent. Vous pouvez réinitialiser plus d'un commit en modifiant le nombre après ~ par exemple git reset --soft HEAD~2 .

 $ git reset --soft HEAD~1 $ git status On branch debugging-branch Changes to be committed: (use "git reset HEAD <file>..." to unstage) modified: css/common.scss Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory) modified: css/common.scss
 $ git diff diff --git a/css/common.scss b/css/common.scss index 2090cc4..90fd457 100644 --- a/css/common.scss +++ b/css/common.scss @@ -13,6 +13,6 @@ body { font-family: "Proxima Nova", Arial, sans-serif; font-size: 13px; - color: $grey; + color: red; background-color: #f00; }

La réinitialisation de Git est un peu plus déroutante, en particulier lors de l'enseignement de nouveaux utilisateurs de Git. Une réinitialisation logicielle doit être réservée à une véritable erreur, tandis qu'une réserve peut être utilisée pour échanger du code d'entrée et de sortie.

Vous pouvez également effectuer une réinitialisation matérielle ( git reset --hard HEAD~1 ). Ce type de réinitialisation efface essentiellement votre dernier commit. Vous devez être très prudent lorsque vous effectuez des réinitialisations matérielles, en particulier si vous poussez votre branche, car il n'y a aucun moyen de restaurer votre validation.

Bisecte de Git

Mon outil Git préféré est git bisect . Je n'en ai eu besoin qu'une poignée de fois mais quand je l'ai fait, c'était inestimable ! Je l'ai principalement utilisé sur de grandes bases de code où il y avait un problème pour lequel personne n'a trouvé la cause première, même après un débogage vigoureux.

git bisect effectue essentiellement une recherche binaire entre deux commits donnés, puis vous présente les détails d'un commit spécifique. Vous devez d'abord donner à Git un bon commit, où vous savez que votre fonctionnalité fonctionnait, et un mauvais commit. Notez que tant que vous avez un bon commit et un mauvais, les commits peuvent être espacés de plusieurs années (bien que plus vous remontez dans le temps, plus cela devient difficile !).

La chose la plus amusante à propos de git bisect est que vous ne savez généralement pas vraiment qui a écrit le commit bogué lorsque vous démarrez. L'excitation de découvrir où le bogue a été introduit a plus d'une fois poussé quelques collègues à se blottir autour de mon ordinateur !

Pour commencer, consultez la branche boguée et trouvez les bons commits. Vous devrez parcourir votre historique de commit et trouver le hachage de commit, puis vérifier ce commit spécifique et tester votre branche. Une fois que vous avez trouvé un bon et un mauvais endroit pour travailler, vous pouvez exécuter un git bisect .

Dans ce scénario, le texte est rouge sur ce site Web que nous avons créé (bien qu'il puisse utiliser un concepteur d'interface utilisateur) mais nous ne savons pas comment ni quand il a été rendu rouge. Ceci est un exemple très simple, dans un scénario réel, vous auriez probablement un problème beaucoup moins évident, par exemple un formulaire qui ne se soumet pas/ne fonctionne pas.

Lorsque nous exécutons un git log , nous pouvons voir la liste des commits parmi lesquels choisir.

 $ git log commit a3cfe7f935c8ad2a2c371147b4e6dcd1a3479a22 (HEAD -> main) Author: Ursula Clarke <[email protected]> Date: Tue Jan 11 10:52:57 2021 +0100 Update .gitignore file for .DS_Store commit 246e90977790967f54e878a8553332f48fae6edc Author: Ursula Clarke <[email protected]> Date: Tue Jan 11 10:51:23 2021 +0100 Change styling of page commit d647ac489ad43b3c6eaea5aceb02b0a7d7e5cf8e Author: Ursula Clarke <[email protected]> Date: Tue Jan 11 10:50:48 2021 +0100 Change text color commit 032a41136b6653fb9f7d81aef573aed0dac3dfe9 Author: Ursula Clarke <[email protected]> Date: Tue Jan 11 10:42:57 2021 +0100 Change text color commit 246e90977790967f54e878a8553332f48fae6edc Author: Ursula Clarke <[email protected]> Date: Tue Jan 11 10:41:23 2021 +0100 delete colors commit d647ac489ad43b3c6eaea5aceb02b0a7d7e5cf8e Author: Ursula Clarke <[email protected]> Date: Tue Jan 11 10:50:48 2021 +0100 Change text color commit ce861e4c6989a118aade031020fd936bd28d535b Author: Ursula Clarke <[email protected]> Date: Tue Jan 11 10:07:36 2021 +0100 ...

Si j'ouvre ma page Web sur le hachage de commit le plus récent, le texte est rouge, donc je sais que j'ai un problème.

Git bisect, étape 1 : une page Web avec du texte en rouge.

Maintenant, nous commençons la bissectrice et disons à Git que nous avons un mauvais commit.

 $ git bisect start $ git bisect bad 8d4615b9a963ef235c2a7eef9103d3b3544f4ee1

Maintenant, nous remontons dans le temps pour essayer de trouver un commit où le texte n'était pas rouge. Ici, j'essaie de vérifier mon premier commit…

 $ git checkout ce861e4c6989a118aade031020fd936bd28d535b Note: checking out 'ce861e4c6989a118aade031020fd936bd28d535b'. You are in 'detached HEAD' state. You can look around, make experimental changes and commit them, and you can discard any commits you make in this state without impacting any branches by performing another checkout. If you want to create a new branch to retain commits you create, you may do so (now or later) by using -b with the checkout command again. Example: git checkout -b <new-branch-name> HEAD is now at ce861e4 Add CSS styles

…et rafraichir la page web…

Git bisect, étape 2 : une page Web avec du texte noir.

Le texte n'est plus rouge, c'est donc un bon commit ! Plus le commit est récent, plus il est proche du mauvais commit, mieux c'est :

 $ git checkout d647ac489ad43b3c6eaea5aceb02b0a7d7e5cf8e Previous HEAD position was ce861e4c6989a118aade031020fd936bd28d535b Add CSS styles HEAD is now at d647ac4 Change text color

Git vous dira maintenant combien de commits il doit rechercher avant de trouver le bon. Le nombre de commits que Git traversera dépend du nombre de commits entre le bon et le mauvais commit (plus la durée est longue, plus Git a besoin d'itérer).

Maintenant, vous devrez tester à nouveau votre branche et voir si votre problème a disparu. Parfois, cela peut être un peu fastidieux si vous mettez régulièrement à jour des modules, car vous devrez peut-être réinstaller des modules de nœud sur votre référentiel frontal. S'il y a eu des mises à jour de la base de données, vous devrez peut-être également les mettre à jour.

git bisect vérifie automatiquement un commit au milieu de vos bons et mauvais commits. Ici, il s'agit d'estimer une étape pour trouver le mauvais commit.

 $ git bisect good 1cdbd113cad2f452290731e202d6a22a175af7f5 Bisecting: 1 revision left to test after this (roughly 1 step) [ce861e4c6989a118aade031020fd936bd28d535b] Add CSS styles $ git status HEAD detached at ce861e4 You are currently bisecting, started from branch '8d4615b'. (use "git bisect reset" to get back to the original branch)

Actualisez la page et voyez si votre problème a disparu. Le problème est toujours là, nous disons donc à Git qu'il s'agit toujours d'un mauvais commit. Pas besoin de référencer le hash du commit cette fois puisque Git utilisera le commit que vous avez extrait. Nous devrons répéter ce processus jusqu'à ce que Git ait parcouru toutes les étapes possibles.

 $ git bisect bad Bisecting: 0 revisions left to test after this (roughly 0 steps) [cbf1b9a1be984a9f61b79ae5f23b19f66d533537] Add second paragraph to page

Actualisez la page, et notre problème a de nouveau disparu, c'est donc un bon engagement :

Git bisect, étape 3 : la même page Web avec du texte noir supplémentaire.

À ce stade, Git a trouvé le premier mauvais commit :

 $ git bisect good ce861e4c6989a118aade031020fd936bd28d535b is the first bad commit commit ce861e4c6989a118aade031020fd936bd28d535b Author: Ursula Clarke <[email protected]> Date: Tue Jan 11 10:52:57 2021 +0100 Add CSS styles :000000 100644 0000000000000000000000000000000000000000 092bfb9bdf74dd8cfd22e812151281ee9aa6f01a M css

Nous pouvons maintenant utiliser git show pour afficher le commit lui-même et identifier le problème :

 $ git show ce861e4c6989a118aade031020fd936bd28d535b commit ce861e4c6989a118aade031020fd936bd28d535b Author: Ursula Clarke <[email protected]> Date: Tue Jan 11 10:52:57 2021 +0100 Add CSS styles diff --git a/css/base.scss b/css/base.scss index e69de29..26abf0f 100644 --- a/css/base.scss +++ b/css/base.scss @@ -1,7 +1,7 @@ body { background-color: $white; margin: 0px; line-height: 20px; - color: $grey; + color: red; }

Lorsque vous avez terminé, vous pouvez exécuter git bisect reset pour réinitialiser votre branche à son état de fonctionnement normal.

Plus les commits sont rapprochés, plus Git sera en mesure de trouver facilement le problème, mais je l'ai déjà fait suivre 10 étapes et je trouve toujours facilement le mauvais commit. Il n'est pas garanti de fonctionner, mais il a trouvé le problème la plupart du temps pour moi. Félicitations, vous êtes maintenant un archéologue du code !

Écraser vos engagements

Auparavant, j'ai travaillé à temps plein sur un projet open source pour une organisation mondiale et j'ai rapidement compris à quel point il est important d'écraser ou de combiner vos commits. Je pense que c'est une excellente habitude à prendre, même si votre employeur ne l'exige pas. C'est particulièrement important pour les autres développeurs qui devront revoir et modifier les fonctionnalités que vous avez créées ultérieurement.

Pourquoi écraser vos commits ?

  • Il est plus facile à lire pour les contributeurs de votre référentiel. Imaginez si vous avez une liste de commit comme celle-ci :
    • Mettre en œuvre le curseur du carrousel
    • Ajouter du style au carrousel
    • Ajouter des boutons au carrousel
    • Correction d'un problème étrange dans IE avec carrousel
    • Ajuster les marges dans le carrousel

    Il est beaucoup plus facile de les écraser dans un seul commit qui dit "Ajouter un carrousel à la page d'accueil".

  • Cela vous encourage à garder vos messages de commit compréhensibles et pertinents si chaque fois que vous faites une pull request, vous devez écraser vos commits en un seul. Combien de fois avez-vous vu un commit intitulé "WIP", "bugfix for login page" ou "fix typo" ? Il est important d'avoir des noms de validation pertinents, par exemple "Bugfix for #444 login page - fix scintillement dû à la fonction $scope manquante".

Une raison pour laquelle vous ne souhaitez peut-être pas écraser vos commits peut être que vous travaillez sur une fonctionnalité très détaillée et longue, et que vous souhaitez conserver un historique quotidien pour vous-même au cas où vous rencontreriez des bogues plus tard. Ensuite, votre fonctionnalité est plus facile à déboguer. Cependant, lorsque vous vérifiez votre fonctionnalité dans votre branche principale et que vous êtes sûr qu'elle est exempte de bogues, il est toujours logique de l'écraser.

Dans ce scénario, j'ai effectué cinq commits, mais tous sont liés à une fonctionnalité. Mes messages de commit sont également trop étroitement liés pour mériter d'être séparés - tous mes commits concernent le style de la page pour cette nouvelle fonctionnalité :

 $ git log commit a8fbb81d984a11adc3f72ce27dd0c39ad24403b7 (HEAD -> main) Author: Ursula Clarke <[email protected]> Date: Tue Jan 11 11:16:10 2021 +0100 Import colors commit e2b3ddd5e8b2cb1e61f88350d8571df51d43bee6 Author: Ursula Clarke <[email protected]> Date: Tue Jan 11 11:15:32 2021 +0100 Add new color commit d647ac489ad43b3c6eaea5aceb02b0a7d7e5cf8e Author: Ursula Clarke <[email protected]> Date: Tue Jan 11 10:50:48 2021 +0100 Change text color commit c005d9ceeefd4a8d4e553e825fa40aaafdac446e Author: Ursula Clarke <[email protected]> Date: Tue Jan 11 09:59:57 2021 +0100 Add CSS styles commit 9e046b7df59cef07820cc90f694fabc666731bd2 Author: Ursula Clarke <[email protected]> Date: Tue Jan 11 09:56:28 2021 +0100 Add second paragraph to page commit 5aff973577d67393d914834e8af4c5d07248d628 Author: Ursula Clarke <[email protected]> Date: Mon Jan 10 16:04:22 2021 +0100 Add colors CSS file and edit background color

Vous pouvez également utiliser git merge --squash , mais je pense qu'il est plus clair d'utiliser rebase car lorsque vous choisissez vos commits, il est plus facile de voir la description du commit. Si vous exécutez un git merge --squash , vous devez d'abord effectuer une réinitialisation matérielle de vos commits ( git reset --hard HEAD~1 ), et il est facile de se confondre avec le nombre exact de commits dont vous avez besoin pour le faire. Je trouve que git rebase est plus visuel.

Commencez par exécuter git rebase -i --root et votre éditeur de texte par défaut sur la ligne de commande s'ouvrira avec votre liste de commits :

 pick eb1eb3c Update homepage pick 5aff973 Add colors CSS file and edit background color pick 9e046b7 Add second paragraph to page pick c005d9c Add CSS styles pick d647ac4 Change text color pick e2b3ddd Add new color pick a8fbb81 Import colors # Rebase a8fbb81 onto b862ff2 (7 commands) # # Commands: # p, pick = use commit # r, reword = use commit, but edit the commit message # e, edit = use commit, but stop for amending # s, squash = use commit, but meld into previous commit # f, fixup = like "squash", but discard this commit's log message # x, exec = run command (the rest of the line) using shell # d, drop = remove commit # # These lines can be re-ordered; they are executed from top to bottom. # # If you remove a line here THAT COMMIT WILL BE LOST. # # However, if you remove everything, the rebase will be aborted. # # Note that empty commits are commented out

Vous voudrez peut-être simplement écraser vos derniers commits, auquel cas vous pouvez exécuter git rebase -i HEAD~3 et voir vos trois derniers commits :

 pick eb1eb3c Update homepage pick 5aff973 Add colors CSS file and edit background color pick 9e046b7 Add second paragraph to page # Rebase b862ff2..9e046b7 onto b862ff2 (3 commands) # # Commands: # p, pick = use commit # r, reword = use commit, but edit the commit message # e, edit = use commit, but stop for amending # s, squash = use commit, but meld into previous commit # f, fixup = like "squash", but discard this commit's log message # x, exec = run command (the rest of the line) using shell # d, drop = remove commit # # These lines can be re-ordered; they are executed from top to bottom. # # If you remove a line here THAT COMMIT WILL BE LOST. # # However, if you remove everything, the rebase will be aborted. # # Note that empty commits are commented out

Nous pouvons maintenant écraser tous les commits dans le premier commit comme indiqué ci-dessous.

 pick eb1eb3c Update homepage squash 5aff973 Add colors CSS file and edit background color squash 9e046b7 Add second paragraph to page # Rebase b862ff2..9e046b7 onto b862ff2 (3 commands) # # Commands: # p, pick = use commit # r, reword = use commit, but edit the commit message # e, edit = use commit, but stop for amending # s, squash = use commit, but meld into previous commit # f, fixup = like "squash", but discard this commit's log message # x, exec = run command (the rest of the line) using shell # d, drop = remove commit # # These lines can be re-ordered; they are executed from top to bottom. # # If you remove a line here THAT COMMIT WILL BE LOST. # # However, if you remove everything, the rebase will be aborted. # # Note that empty commits are commented out

Lorsque vous enregistrez le fichier, Git ouvrira votre message de validation à modifier.

 # This is a combination of 3 commits. # This is the 1st commit message: Update homepage # This is the commit message #2: Add colors CSS file and edit background color # This is the commit message #3: Add second paragraph to page # Please enter the commit message for your changes. Lines starting # with '#' will be ignored, and an empty message aborts the commit. # # Date: Wed Jan 13 18:31:28 2021 +0100 # # interactive rebase in progress; onto b862ff2 # Last commands done (3 commands done): # squash 5aff973 Add colors CSS file and edit background color # squash 9e046b7 Add second paragraph to page # No commands remaining. # You are currently rebasing branch 'main' on 'b862ff2'. # # Changes to be committed: # new file: .gitignore # new file: css/base.css # new file: css/base.scss # new file: css/colors.css # new file: css/colors.css.map # new file: css/colors.scss # new file: css/common.css # new file: css/common.scss # new file: index.html #

Pendant que nous effectuons le rebase, nous pouvons également modifier la description du commit afin qu'elle soit plus facile à lire.

 Implement new design for homepage. Add .gitignore file for Sass folder. # Please enter the commit message for your changes. Lines starting # with '#' will be ignored, and an empty message aborts the commit. #

Enregistrez à nouveau ce fichier et vous avez terminé ! Lorsque nous jetons un autre coup d'œil au journal Git, nous pouvons voir qu'il n'y a qu'un seul commit propre.

 [detached HEAD 574ec7e] Implement new design for homepage. Add .gitignore file for Sass folder. Date: Wed Jan 13 18:31:28 2021 +0100 10 files changed, 215 insertions(+) create mode 100644 .gitignore create mode 100644 css/base.css create mode 100644 css/base.scss create mode 100644 css/colors.css create mode 100644 css/colors.css.map create mode 100644 css/colors.scss create mode 100644 css/common.css create mode 100644 css/common.scss create mode 100644 index.html create mode 100644 verylargefile.txt Successfully rebased and updated refs/heads/main. $ git log commit 574ec7e5d7d7a96427e049cad9806cdef724aedd (HEAD -> main) Author: Ursula Clarke <[email protected]> Date: Wed Jan 13 18:31:28 2021 +0100 Implement new design for homepage. Add .gitignore file for Sass folder.

Rebase Git

Les développeurs hésitent généralement à utiliser git rebase car ils savent qu'un rebase peut être utilisé pour supprimer définitivement des fichiers de votre base de code.

Comme nous l'avons vu ci-dessus, git rebase peut être utilisé pour conserver votre code et le ranger ainsi que pour le supprimer - mais que se passe-t-il si vous voulez vraiment supprimer définitivement un fichier de l'historique ?

Une fois, j'ai été témoin d'un scénario dans lequel un membre de notre équipe de développement avait accidentellement engagé un très gros fichier dans la base de code. Il faisait partie d'une branche beaucoup plus grande, de sorte que le fichier volumineux est passé inaperçu lors de la révision du code et a été archivé par erreur dans la branche principale. Cela devenait un problème chaque fois que quelqu'un voulait recloner le référentiel - le téléchargement prenait très longtemps ! Et bien sûr, le dossier en question n'était pas nécessaire. Cela n'aurait pas été un problème si le fichier était le dernier commit sur la branche principale - dans ce cas, vous pouvez simplement exécuter une réinitialisation matérielle ( git reset --hard HEAD~1 ) et forcer la branche.

De même, si le fichier était le seul changement dans un commit donné, vous pouvez simplement supprimer le commit entier en exécutant git reset --hard <commit-id> . Dans notre scénario, cependant, le fichier volumineux a été validé avec un autre code que nous voulions conserver dans l'historique, en tant qu'avant-dernier commit.

Une fois que vous avez trouvé le commit gênant, vérifiez-le à l'aide de git checkout et du hash de commit :

 $ git checkout ce861e4c6989a118aade031020fd936bd28d535b Note: checking out 'ce861e4c6989a118aade031020fd936bd28d535b'. You are in 'detached HEAD' state. You can look around, make experimental changes and commit them, and you can discard any commits you make in this state without impacting any branches by performing another checkout. If you want to create a new branch to retain commits you create, you may do so (now or later) by using -b with the checkout command again. Example: git checkout -b <new-branch-name> HEAD is now at ce861e4 Add CSS styles

Supprimez le fichier ou modifiez votre code et laissez le code (ou les fichiers) que vous souhaitez conserver intact.

 $ rm verylargefile.txt $ git status HEAD detached at ce861e4 Changes not staged for commit: (use "git add/rm <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory) deleted: verylargefile.txt no changes added to commit (use "git add" and/or "git commit -a")

Assurez-vous d'exécuter git add -A afin que votre fichier supprimé soit mis en scène et que Git sache le supprimer. Maintenant, exécutez git commit --amend -v et Git vous demandera de modifier votre message de validation.

Après cela, exécutez git rebase --onto HEAD <commit-id> main . C'est là que vous pourriez rencontrer des conflits de fusion, ce qui signifie qu'il y a un conflit entre votre nouveau commit et l'ancien code. Git vous demandera de résoudre le conflit :

 $ git add -A $ git status HEAD detached at ce861e4 Changes to be committed: (use "git reset HEAD <file>..." to unstage) deleted: verylargefile.txt $ git commit --amend -v [detached HEAD 7c9516a] Add CSS styles Date: Thu Jan 14 14:43:54 2021 +0100 3 files changed, 9 insertions(+), 2 deletions(-) create mode 100644 css/common.css.map delete mode 100644 verylargefile.txt $ git status HEAD detached from ce861e4 nothing to commit, working tree clean $ git rebase --onto HEAD ce861e4 First, rewinding head to replay your work on top of it... Fast-forwarded HEAD to HEAD.

Si vous ouvrez le fichier dans votre éditeur de texte, vous verrez que Git a marqué deux versions du fichier d'index. Il vous suffit d'en supprimer un ou d'en modifier un pour conserver les modifications souhaitées.

 <p> Toptal was created by engineers. We are entrepreneurs, all passionate about working with top tech talent and exciting companies from all over the world. </p> <<<<<<< HEAD <p> Toptal connects the top 3% of freelance talent all over the world. </p> </main> </body> </html> ======= </main> </body> </html> >>>>>>> Add index file

Le code entre <<<<<<< HEAD et la ligne de signes égal est une version, et le code entre les signes égal et >>>>>>> Add index file est la version du commit "Ajouter un fichier d'index" . Vous pouvez donc voir qu'une version contient le paragraphe supplémentaire "Toptal connecte les 3 % de talents indépendants du monde entier", tandis que l'autre ne le fait pas.

Enregistrez votre fichier modifié et exécutez git add filename suivi de git rebase --continue . S'il n'y a aucun changement, vous pouvez également exécuter git rebase --skip . Le rebasage peut prendre un certain temps s'il y a eu beaucoup de commits entre votre commit "gros fichier" et le dernier commit sur main.

Soyez patient, et si vous faites partie d'une grande équipe, assurez-vous d'obtenir un deuxième avis ! Il est particulièrement important de consulter la ou les personnes qui ont écrit le ou les commits que vous fusionnez, si possible.

N'oubliez pas que les modifications de fusion sont pertinentes pour le commit spécifique dans l'historique, et non pour vos modifications les plus récentes. Par exemple, si vous modifiez un commit datant de l'époque où le texte de votre site était Arial, et qu'il s'agit maintenant de Verdana, vous devez toujours conserver ce commit avec l'historique d'Arial comme police.

Notez également que si Git voit un espace ou un caractère de fin de ligne, cela peut provoquer un conflit de fusion, alors soyez prudent !

Plus que simplement s'engager et tirer

Git est plus puissant que beaucoup de développeurs ne le pensent. S'il vous arrive d'introduire un débutant, assurez-vous de lui donner quelques conseils sur ces fonctionnalités inestimables. Cela permet un flux de travail plus efficace.

Vous souhaitez en savoir plus sur Git ? Jetez un œil à la page Git Tips and Practices de Toptal.