« veuillez rebaser au-dessus de master et nous fusionnerons votre pull request”.
« pouvez-vous écraser vos commits ensemble pour que nous obtenions une githistory propre et réversible?”.
« pouvez-vous réécrire le message de votre commit pour mieux décrire le problème et comment il le résout?”.
ces Questions sont fréquemment posées en tirer des demandes. Voyons pourquoi ilsexiste, comment les exécuter, et leurs problèmes possibles.,
reformuler le dernier message de validation
l’une des réécritures d’historique les plus simples que nous puissions faire avec git est de modifier le message lastcommit. Disons que juste après avoir fait un commit, vous trouvez une faute de frappe dans sa description, ou vous trouvez une meilleure façon de décrire l’ensemble de modifications. Pour faire la correction que vous exécutez:
git commit --amend
il ouvrira un éditeur avec le dernier message de validation, vous pouvez donc le modifier. Après l’enregistrement, un nouveau commit sera créé avec les mêmes modifications et le nouveau message, remplaçant le commitwith le message précédent.,
cela peut être utile pour inclure des fichiers que vous avez oublié de suivre, ou includemodifications aux fichiers que vous venez de commettre. Pour ce faire, vous pouvez ajouter les modifications et ensuite effectuer la modification:
git add README.md config/routes.rb git rm notes.txt git commit --amend
en plus de modifier le message de validation, la nouvelle validation contiendra les modifications spécifiées avecgit add
Etgit rm
. Vous pouvez également modifier l’auteur. Par exemple:
git commit --amend --author="Tute Costa and Dan Croak <[email protected]>"
réalisation débloquée!, Vous pouvez maintenant modifier le dernier commit de votre référentiel pour inclure des modifications plus récentes aux fichiers et / ou pour améliorer le message de commit. Mais ne commencez pas à modifier toutes les choses avant de comprendre la dernière section de ce blog intitulé « DANGER ».
reformuler d’autres messages de validation
aimerait en parler maintenant, mais nous devons comprendre un outil plus général avant. Restez à l’écoute! Tout le reste sera plus facile une fois que nous aurons lu à propos de Interactive
Rebase Interactive
git rebase
ré-applique les commits, un par un, dans l’ordre, de votre branche actuelle à une autre., Il accepte plusieurs options et paramètres, c’est donc une explication de la pointe de l’iceberg, assez pour faire le pont entre les commentaires StackOverflow ou GitHub et les pages de manuel git.
une option intéressante qu’il accepte Est--interactive
(-i
pour faire court), qui ouvrira un éditeur avec une liste des commits qui sont sur le point d’être modifiés. Thislist accepte les commandes, permettant à l’utilisateur de modifier la liste avant de lancer l’action therebase.
prenons un exemple.,
Reformuler d’autres messages de commit, prendre 2
disons que je veux à reformuler l’un des 4 derniers s’engage de ce blog. Je puis exécutezgit rebase -i HEAD~4
et voici ce que je vois:
pick 07c5abd Introduce OpenPGP and teach basic usage pick de9b1eb Fix PostChecker::Post#urls pick 3e7ee36 Hey kids, stop all the highlighting pick fa20af3 git interactive rebase, squash, amend # Rebase 8db7e8b..fa20af3 onto 8db7e8b # # 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
Nous voyons les quatre derniers commits, de la plus ancienne à la plus récente. Voir le commentaire ci dessous la liste des commits? Bon travail d’explication, git! pick
(p
pour faire court) est l’action par défaut. Dans ce cas, il réappliquerait le commit tel quel, aucun changement dans itscontents ou message. L’enregistrement (et l’exécution) de ce fichier n’apporterait aucune modification au référentiel.,
Si je dis reword
(r
pour faire court) dans un commit je veux edit:
pick 07c5abd Introduce OpenPGP and teach basic usage pick de9b1eb Fix PostChecker::Post#urls r 3e7ee36 Hey kids, stop all the highlighting pick fa20af3 git interactive rebase, squash, amend
Quand j’ai enregistrer et quitter l’éditeur, git va suivre les commandes, landingmyself dans l’éditeur de nouveau, comme si j’avais modifié commit 3e7ee36
. Je modifie thatcommit message, Enregistrer et quitter l’éditeur, et voici la sortie:
maintenant Caleb dit dans son message de validation « arrêter toute la mise en évidence”, que vous soyez un enfant ou non.
succès Débloqué! Vous pouvez maintenant changer le message de anycommit que vous voulez., Vous pouvez le faire, assurez-vous simplement de comprendre la section « DANGER”.
la Courge s’engage
Deux autres commandes rebase interactif nous offre sont:
-
squash
(s
pour faire court), qui allie l’engager dans la précédente (theone dans la ligne avant) -
fixup
(f
pour faire court), qui agit comme le « squash”, mais ignore ce commit’smessage
Nous allons continuer à travailler sur le rebase exemple, nous workedbefore., Nous avions quatre commits, les miens pour cet article de blog, et trois autres de Caleb, qui étaient liés à son précédent post sur PGP:
pick 07c5abd Introduce OpenPGP and teach basic usage pick de9b1eb Fix PostChecker::Post#urls pick 3e7ee36 Hey kids, stop all the highlighting pick fa20af3 git interactive rebase, squash, amend
disons que je veux fusionner les commits de Caleb ensemble, car ils appartiennent au même ensemble de changements logiques, et nous pouvons donc git revert
nous trouvons que weprefer n’a pas ces changements dans ce référentiel. Nous voudrons conserver le premier message de validation et écraser les deux validations suivantes dans le précédent., Je change pick
en squash
le cas échéant:
pick 07c5abd Introduce OpenPGP and teach basic usage s de9b1eb Fix PostChecker::Post#urls s 3e7ee36 Hey kids, stop all the highlighting pick fa20af3 git interactive rebase, squash, amend
enregistrer, et j’atterris dans l’éditeur pour décider du message de validation des commits meldedthree (voir comment ils sont concaténés les uns après les autres):
# This is a combination of 3 commits. # The first commit's message is: Introduce OpenPGP and teach basic usage Besides demystifying a relatively complex tool, protocol, and etiquette, this post is intended to help with problems such as the one outlined in this tweet: > Emailed sensitive info to someone with PGP. They replied, with my > original email, all in clear text. They didn't realize it. # This is the 2nd commit message: Fix PostChecker::Post#urls # This is the 3rd commit message: Hey kids, stop all the highlighting # Please enter the commit message for your changes. Lines starting # with '#' will be ignored, and an empty message aborts the commit. # # Author: Caleb Hearth # Date: Tue Sep 2 09:39:07 2014 -0500 # # rebase in progress; onto 71d4789 # You are currently editing a commit while rebasing branch 'tc-git-rebase' on '71d4789'.
je décide de supprimer le troisième message de validation et d’ajouter une note plus pertinente au deuxième message de validation. Enregistrez l’éditeur, et les quatre commits ont été transformés en deux: celui de Caleb, et le mien après. Bon!,
nous aurions pu utiliser la commandefixup
, si nous avions vu plus tôt que nous voulions les changements, mais pas le message de validation, du troisième commit. Dans ce cas, les commandes auraient ressemblé à:
pick 07c5abd Introduce OpenPGP and teach basic usage s de9b1eb Fix PostChecker::Post#urls f 3e7ee36 Hey kids, stop all the highlighting pick fa20af3 git interactive rebase, squash, amend
lors de l’enregistrement, L’éditeur aurait inclus le troisième message de commit déjà recommandé pour nous:
Save, et outputs:
le résultat est le même: 2 commits au lieu de 4, chacun avec un seul article de blog différent.
succès Débloqué! Vous pouvez maintenant fusionner les commits ensemble. Toujours, soyez conscient de la section DANGER.,
Rebase au-dessus de master
Nous fork une bibliothèque open source, commencer à travailler sur une branche de fonctionnalité, et master dans le projet amont va de l’avant. Notre historique ressemble à:
A---B---C feature / D---E---F---G upstream/master
le responsable de la bibliothèque demande de « rebaser au-dessus du maître”, nous corrigeons donc tous les conflits de fusion qui peuvent survenir entre les deux branches et gardons notre ensemble de modifications ensemble.Le mainteneur aimerait voir un historique comme:
A'--B'--C' feature / D---E---F---G upstream/master
Nous voulons réappliquer nos commits, un par un, dans l’ordre, sur le maître en amont.,Cela ressemble à la description de la commande rebase! Voyons voir quelles commandes nous mettraient dans le scénario souhaité:
# Point our `upstream` remote to the original fork git remote add upstream https://github.com/thoughtbot/factory_girl.git # Fetch latest commits from `upstream` (the original fork) git fetch upstream # Checkout our feature branch git checkout feature # Reapply it onto upstream's master git rebase upstream/master # Fix conflicts, then `git rebase --continue`, repeat until done # Push to our fork git push --force origin feature
succès Débloqué! Votre branche de fonctionnalité sera appliquée au-dessus du dernier maître de la fourche d’origine.
Et donc, nous arrivons à…
DANGER: Vous êtes à la réécriture de l’histoire
Voir le --force
dans le dernier git push
commande? Cela signifie que nous écrasons l’histoire du répertoire., C’est toujours sûr de le faire dans les commits que nous ne partageons pas avec d’autres membres de l’équipe, ou dans les branches qui nous appartiennent (voir mes initiales dans l’exemple de cet article de blog).
Mais si vous forcez les éditions push qui étaient déjà partagées avec l’équipe (les commitsthat existent en dehors de mon référentiel, comme les modifications que j’ai apportées aux commitsthat PGP qui ont déjà été partagées), alors la branche de tout le monde se désynchronise.
réécrire l’histoire signifie abandonner les commits existants et en créer de nouveaux, qui peuvent être très similaires mais sont différents., Si d’autres basent leur travail sur vos engagements précédents, puis que vous réécrivez et forcez vos commits, les membres de votre équipe devront fusionner à nouveau leur travail (s’ils remarquent la perte potentielle).
chez thoughtbot, nous préfixons nos branches avec nos initiales, signalant que ces engagements peuvent être réécrits et que d’autres ne devraient pas ajouter de commits à la branche. Lorsque ces commits atterrissent dans master ou une branche partagée, nous ne les réécrivons plus jamais.
réécrivez donc l’historique git, à condition que les commits réécrits n’existent que dans votre répertoire, ou que vous et votre équipe sachiez que personne d’autre ne devrait baser le travail sur ofthem.,
succès Débloqué! Vous savez maintenant comment rebaser tout en étant un bon citoyen.