Comment modifier un message de validation incorrect dans git (que j'ai poussé)?


152

Je veux modifier un message de commit plus profondément dans l'histoire et j'ai poussé de nombreux nouveaux commits.

Comment modifier le message de validation? C'est possible?

Réponses:


125

Le message de Linus Torvalds peut répondre à votre question:

Modifier / éditer les anciens messages de validation

Réponse courte: vous ne pouvez pas (si vous êtes poussé).


extrait (Linus désigne BitKeeper comme BK):

Note latérale, juste par intérêt historique: en BK, vous pourriez.

Et si vous y êtes habitué (comme moi), c'était vraiment très pratique. J'appliquais une bombe patch d'Andrew, je remarquais que quelque chose n'allait pas et je la modifais simplement avant de la sortir.

J'aurais pu faire la même chose avec git. Il aurait été assez facile de faire en sorte que le message de validation ne fasse pas partie du nom, tout en garantissant que l'historique n'a pas été touché, et en autorisant la chose "réparer les commentaires plus tard".

Mais je ne l'ai pas fait.

Une partie de celui-ci est purement "cohérence interne". Git est simplement un système plus propre grâce au fait que tout est protégé par SHA1 et que tous les objets sont traités de la même manière, quel que soit le type d'objet. Oui, il y a quatre différents types d'objets, et ils sont tous très différents, et ils ne peuvent pas être utilisés de la même manière, mais en même temps, même si leur codage peut être différent sur le disque, sur le plan conceptuel ils fonctionnent tous exactement le même.

Mais la cohérence interne n'est pas vraiment une excuse pour être inflexible, et il serait clairement très flexible si nous pouvions simplement réparer les erreurs après qu'elles se produisent. Ce n'est donc pas un argument très fort.

La vraie raison pour laquelle git ne vous permet pas de modifier le message de validation finit par être très simple: de cette façon, vous pouvez faire confiance aux messages. Si vous autorisez les gens à les changer par la suite, les messages ne sont pas très fiables par nature.


Pour être complet, vous pouvez réécrire votre historique de commit local afin de refléter ce que vous voulez, comme suggéré par sykora (avec un rebase et une réinitialisation - hard, gasp!)

Cependant, une fois que vous publiez votre histoire révisée à nouveau (avec git push origin +master:master, le +signe forçant la poussée à se produire, même si elle ne donne pas lieu à une validation « avance rapide ») ... vous pourriez obtenir des ennuis .

Extrait de cette autre question SO:

En fait, une fois, j'ai poussé avec --force vers le référentiel git.git et j'ai été grondé par Linus BIG TIME. Cela créera beaucoup de problèmes pour les autres. Une réponse simple est "ne le faites pas".


bonne réponse. Savez-vous si vous êtes maintenant en mesure de modifier les messages de validation déjà poussés dans les nouvelles versions de git? Quelque chose a-t-il changé depuis sa publication en 2009?
David West

@DavidWest le même principe est valable: vous pouvez réécrire votre historique et forcer une poussée.
VonC

2
Pour rendre les choses plus spécifiques, si vous modifiez / rebase les commits, leurs identifiants de commit (hachages hexadécimaux dans git index) changent inévitablement; cela signifie que les commits modifiés sont traités différemment de leurs anciens commits dans l'historique de git VCS. Cela dit, si les membres de votre équipe de développement ont malheureusement déjà retiré les anciens commits, ils sont obligés d'extraire les nouveaux commits modifiés et d'effectuer une fusion entre l'ancien et le nouveau dans leurs copies de travail locales.
Shigerello

1
Il est préférable de repousser les commits modifiés pour plus de commodité pour vos collègues, éliminant ainsi favorablement la nécessité de fusionner les copies de travail des collègues.
Shigerello

28

Actuellement, un remplacement git pourrait faire l'affaire.

En détail: créer une branche de travail temporaire

git checkout -b temp

Réinitialiser le commit à remplacer

git reset --hard <sha1>

Modifier le commit avec le bon message

git commit --amend -m "<right message>"

Remplacez l'ancien commit par le nouveau

git replace <old commit sha1> <new commit sha1>

retourne à la succursale où tu étais

git checkout <branch>

supprimer la branche temporaire

git branch -D temp

pousser

guess

terminé.


11
@Jonah: Je reçois un message "Tout est à jour" lorsque j'essaye de pousser vers la succursale distante
Simon Kagwi

1
Comme mentionné dans une autre réponse: utilisez rebase -i avec reformulation. Et cela réécrira l'histoire.
Sylvain

Merci pour la solution que je recherchais. Vous économisez mon temps!
Tomasz Kuter

1
@Jonah - J'ai un problème ... votre solution a mis à jour mes journaux de validation localement, mais pas à distance. Comment les y pousser?
Tomasz Kuter

1
@TomaszKuter, j'ai eu le même problème que vous. Mon message de validation n'a pas été mis à jour à distance. Je l'ai résolu en utilisant l'aide suivante de GitHub: help.github.com/articles/changing-a-commit-message . Suivez la section: Modification du message d'anciens ou de plusieurs messages de validation. C'est essentiellement la réponse ci-dessous donnée par user987419 Si vous avez déjà modifié le message de validation, vous pouvez faire le pick and save sans avoir à le modifier à nouveau.
evaldeslacasa

19

Vous pouvez utiliser git rebase -i(par rapport à la branche à partir de laquelle vous avez créé une branche) «i» pour interactif.

Remplacez le picksuivant du commentaire de validation que vous souhaitez modifier par r(ou reword), enregistrez et quittez et, ce faisant, vous pourrez effectuer la modification.

git push encore une fois et vous avez terminé!


1
Cela ne permet pas de modifier les messages lors des validations de fusion. Est-ce possible avec une variante de cette commande?
Andrew Mao

1
Essayez l' -pargument rebasedont les préserves fusionnent.
Cactus

3
J'aime cette procédure, mais je n'ai pas tout à fait compris la réponse au début. Au cas où quelqu'un aurait besoin d'aide, la page d'aide de Githulb offre de bonnes informations à ce sujet: help.github.com/articles/changing-a-commit-message
evaldeslacasa

15

Supposons que vous ayez un arbre comme celui-ci:

dd2e86 - 946992 - 9143a9 - a6fd86 - 5a6057 [master]

Tout d'abord, checkoutune branche temporaire:

git checkout -b temp

Sur la tempbranche, reset --hardà un commit dont vous voulez changer son message (par exemple, ce commit est 946992):

git reset --hard 946992

Utilisez amendpour changer le message:

git commit --amend -m "<new_message>"

Après cela, l'arbre ressemblera à ceci:

dd2e86 - 946992 - 9143a9 - a6fd86 - 5a6057 [master]
           \
            b886a0 [temp]

Ensuite, cherry-picktout le commettras qui est en avance sur 946992de masterla tempet les commettras, utilisez amendsi vous voulez changer leurs messages ainsi:

git cherry-pick 9143a9
git commit --amend -m "<new_message>
...
git cherry-pick 5a6057
git commit --amend -m "<new_message>

L'arbre ressemble maintenant à ceci:

dd2e86 - 946992 - 9143a9 - a6fd86 - 5a6057 [master]
               \
                b886a0 - 41ab2c - 6c2a3s - 7c88c9 [temp]

Maintenant, forcez le transfert de la branche temp vers la télécommande:

git push --force origin temp:master

La dernière étape, supprimer la branche masteren local, git fetch originextraire la branche masterdu serveur, puis passer à la branche masteret supprimer la branche temp.

Désormais, tous les messages seront mis à jour sur votre site local et distant.


5

Dans notre boutique, j'ai introduit la convention d'ajouter des balises annotées nommées de manière reconnaissable aux commits avec des messages incorrects, et d'utiliser l'annotation comme remplacement.

Même si cela n'aide pas les gens qui exécutent des commandes "git log" occasionnelles, cela nous fournit un moyen de corriger les références de bug tracker incorrectes dans les commentaires, et tous mes outils de construction et de publication comprennent la convention.

Ce n'est évidemment pas une réponse générique, mais c'est peut-être quelque chose que les gens peuvent adopter au sein de communautés spécifiques. Je suis sûr que si cela est utilisé à plus grande échelle, une sorte de support en porcelaine pourrait apparaître, éventuellement ...


3
"git notes" pourrait servir un objectif similaire
Christian Goetze

2

(Depuis http://git.or.cz/gitwiki/GitTips#head-9f87cd21bcdf081a61c29985604ff4be35a5e6c0 )

Comment changer s'engage plus profondément dans l'histoire

Étant donné que l'historique dans Git est immuable, corriger tout autre commit que le commit le plus récent (commit qui n'est pas en tête de branche) nécessite que l'historique soit réécrit à partir du commit modifié et en avant.

Vous pouvez utiliser StGIT pour cela, initialiser la branche si nécessaire, désengager jusqu'au commit que vous voulez changer, y accéder si nécessaire, faire un changement puis actualiser le patch (avec l'option -e si vous voulez corriger le message de commit), puis pousser tout et stg s'engagent.

Ou vous pouvez utiliser rebase pour le faire. Créez une nouvelle branche temporaire, rembobinez-la au commit que vous voulez changer en utilisant git reset --hard, changez ce commit (ce serait en haut de l'en-tête actuel), puis rebasez la branche en haut du commit modifié, en utilisant git rebase --onto.

Ou vous pouvez utiliser git rebase --interactive, qui permet diverses modifications telles que la réorganisation des patchs, la réduction, ...

Je pense que cela devrait répondre à votre question. Cependant, notez que si vous avez poussé du code vers un référentiel distant et que des personnes l'ont extrait, cela va gâcher leur historique de code, ainsi que le travail qu'ils ont effectué. Alors faites-le soigneusement.


Bonne réponse en théorie, très dangereux en pratique: voir stackoverflow.com/questions/253055#432518
VonC

0

Si vous utilisez des extensions Git: allez dans l'écran de validation, il devrait y avoir une case à cocher qui dit "Modifier la validation" en bas, comme on peut le voir ci-dessous:

entrez la description de l'image ici


@KrunalPandya Oui, ou appuyez simplement sur commit et push
Batsheva
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.