Git Squash expliqué

Qu'est-ce que Git Squash?

Une des choses que les développeurs entendent assez souvent à propos de leurs pull requests est quelque chose comme "Cela me semble bien, s'il vous plaît écraser et fusionner". La partie amusante est qu'il n'y a pas de telle commande comme git squash(sauf si vous créez un alias pour elle).

Pour squashtous tirer des moyens de demande généralement à compacter les commits dans cette demande dans un (rarement autre numéro) pour le rendre plus concis, lisible et ne pas polluer l'histoire de la branche principale. Pour y parvenir, un développeur doit utiliser le mode interactif de la commande Git Rebase.

Très souvent, lorsque vous développez une nouvelle fonctionnalité, vous vous retrouvez avec plusieurs commits intermittents dans votre historique - vous vous développez progressivement après tout. Cela peut être juste quelques fautes de frappe ou étapes de la solution finale. La plupart du temps, il ne sert à rien d'avoir tous ces commits dans la version publique finale de votre code, il est donc plus avantageux de tous les compacter en une seule version finale.

Supposons donc que vous ayez le journal de validation suivant dans la branche que vous souhaitez fusionner dans le cadre de la demande d'extraction:

$ git log --pretty=oneline --abbrev-commit 30374054 Add Jupyter Notebook stub to Data Science Tools 8490f5fc Minor formatting and Punctuation changes 3233cb21 Prototype for Notebook page

De toute évidence, nous préférerions n'avoir qu'un seul commit ici, car il n'y a aucun avantage à savoir ce que nous avons commencé à écrire et quelles fautes de frappe nous y avons corrigées plus tard. Seul le résultat final est important.

Donc, ce que nous faisons est de démarrer une session de rebase interactive à partir du HEAD actuel (commit 30374054 ) pour commettre 3233cb21 , avec l'intention de combiner les 3 derniers commits en un seul:

$ git rebase -i HEAD~3

Cela ouvrira un éditeur avec quelque chose comme ce qui suit:

pick 3233cb21 Prototype for Notebook page pick 8490f5fc Minor formatting and Punctuation changes pick 30374054 Add Jupyter Notebook to Data Science Tools # Rebase # # 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 # # 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

Comme toujours, Git nous donne un très beau message d'aide où vous pouvez voir l' squashoption que nous recherchons.

Actuellement, les instructions de rebase interactif indiquent pickchaque commit spécifié et conservent le message de commit correspondant. C'est - ne changez rien. Mais nous voulons n'avoir qu'un seul commit à la fin.

Ainsi, vous pouvez simplement éditer le texte dans votre éditeur en remplaçant pickpar squash(ou juste s) chaque commit dont nous voulons nous débarrasser et enregistrer / quitter l'éditeur. Cela pourrait ressembler à ceci:

s 3233cb21 Prototype for Notebook page s 8490f5fc Minor formatting and Punctuation changes pick 30374054 Add Jupyter Notebook to Data Science Tools

Lorsque vous fermez votre éditeur après avoir enregistré cette modification, il sera rouvert immédiatement et vous suggérera de choisir et de reformuler ces messages de validation. Quelque chose comme ça:

# This is a combination of 3 commits. # The first commit's message is: Prototype for Notebook page # This is the 2nd commit message: Minor formatting and Punctuation changes # This is the 3rd commit message: Add Jupyter Notebook to Data Science Tools # Please enter the commit message for your changes. Lines starting # with '#' will be ignored, and an empty message aborts the commit.

À ce stade, vous pouvez supprimer tous les messages que vous ne souhaitez pas inclure dans la version finale de validation. Vous pouvez également les reformuler ou simplement écrire un message de validation à partir de zéro.

N'oubliez pas que la nouvelle version comprendra toutes les lignes qui ne commencent pas par le #caractère. Encore une fois, enregistrez et quittez votre éditeur.

Votre terminal devrait maintenant afficher un message de réussite, y compris Successfully rebased and updated et le journal git devrait afficher un historique agréable et compacté avec un seul commit. Tous les engagements intermédiaires sont partis et nous sommes prêts à fusionner!

Avertissement concernant la non-concordance de l'historique des validations locales et distantes

Cette opération est légèrement dangereuse si votre branche est déjà publiée dans un référentiel distant - vous modifiez l'historique de validation après tout. Il est donc préférable de faire l'opération de squash sur une branche locale avant de pousser .

Parfois, il sera déjà poussé - comment créeriez-vous une demande d'extraction après tout? Dans ce cas, vous devrez forcer les modifications sur la branche distante après avoir effectué l'écrasement, car votre historique local et votre historique de branche dans le référentiel distant sont différents:

$ git push origin +my-branch-name

Faites de votre mieux pour vous assurer que vous êtes le seul à utiliser cette branche distante à ce stade, sinon vous compliquerez la vie de l'autre développeur en cas d'incohérence d'historique. Mais comme l' écrasement est généralement effectué en tant qu'opération finale sur une branche avant de s'en débarrasser, ce n'est généralement pas si grave.