Mercurial - revenir à l'ancienne version et continuer à partir de là

249

J'utilise Mercurial localement pour un projet (c'est le seul repo il n'y a pas de pousser / tirer vers / de n'importe où ailleurs).

À ce jour, il a une histoire linéaire. Cependant, la chose sur laquelle je travaille actuellement, j'ai réalisé que c'est une approche terrible et je veux revenir à la version avant de la commencer et l'implémenter d'une manière différente.

Je suis un peu confus avec les commandes branch/ revert/ update -Cdans Mercurial. Fondamentalement, je veux revenir à la version 38 (actuellement sur 45) et avoir mes prochains commits ont 38 en tant que parent et continuer à partir de là. Je me fiche que les révisions 39-45 soient perdues à jamais ou se retrouvent dans une impasse.

De quelle commande / ensemble de commandes ai-je besoin?

Paolo
la source
6
Pour toute personne intéressée, cela est apparu dans la barre latérale associée, ce qui est une excellente explication de revenir à la mise à jour: stackoverflow.com/questions/2506803/…
Paolo

Réponses:

150
hg update [-r REV]

Si vous vous engagez plus tard, vous créerez effectivement une nouvelle branche. Ensuite, vous pouvez continuer à travailler uniquement sur cette branche ou éventuellement fusionner la branche existante en elle.

van
la source
6
le prochain commit créera une nouvelle branche. Si vous n'êtes pas sûr, faites simplement une sauvegarde de votre référentiel (avec copie de travail), essayez-le - n'aimez pas le résultat -> recommencez à zéro sans frais
van
C'est une réponse douteuse car elle fusionne vos modifications actuelles avec l'ancienne révision qui est probablement ce que vous ne voulez pas faire. La bonne réponse devrait être hg revert.
Trevor de Koekkoek
La réponse est très bien, sauf pour ce qui est de la fusion (je ne pense pas que le questionneur voudra fusionner).
ctrl-alt-delor
3
@NeonWarge REV est simplement un espace réservé pour la révision. Il peut s'agir de son numéro, de son hachage, d'un signet, etc. Trevor: ce n'est pas douteux car il ne fusionne rien. Pas besoin de.
DanMan
401

Voici la feuille de triche sur les commandes:

  • hg updatemodifie la révision parent de votre copie de travail et modifie également le contenu du fichier pour qu'il corresponde à cette nouvelle révision parent. Cela signifie que les nouveaux validations continueront à partir de la révision vers laquelle vous effectuez la mise à jour.

  • hg revertmodifie uniquement le contenu du fichier et laisse la révision parent de la copie de travail seule. Vous utilisez généralement hg revertlorsque vous décidez que vous ne souhaitez pas conserver les modifications non validées que vous avez apportées à un fichier dans votre copie de travail.

  • hg branchdémarre une nouvelle branche nommée. Considérez une branche nommée comme une étiquette que vous attribuez aux ensembles de modifications. Donc, si vous le faites hg branch red, les changements suivants seront marqués comme appartenant à la branche "rouge". Cela peut être un bon moyen d'organiser les changesets, en particulier lorsque différentes personnes travaillent sur différentes branches et que vous souhaitez plus tard voir d'où provient un changeset. Mais vous ne voulez pas l'utiliser dans votre situation.

Si vous utilisez hg update --rev 38, les ensembles de modifications 39 à 45 resteront comme une impasse - une tête ballante comme nous l'appelons. Vous recevrez un avertissement lorsque vous poussez, car vous allez créer des "têtes multiples" dans le référentiel vers lequel vous poussez. L'avertissement est là car il est assez impoli de laisser de telles têtes car elles suggèrent que quelqu'un doit faire une fusion. Mais dans votre cas, vous pouvez simplement aller de l'avant et hg push --forcepuisque vous voulez vraiment le laisser suspendu.

Si vous n'avez pas encore poussé la révision 39-45 ailleurs, vous pouvez les garder confidentielles. C'est très simple: avec hg clone --rev 38 foo foo-38vous obtiendrez un nouveau clone local qui ne contient que jusqu'à la révision 38. Vous pouvez continuer à travailler foo-38et pousser les nouveaux (bons) changesets que vous créez. Vous aurez toujours les anciennes (mauvaises) révisions dans votre fooclone. (Vous êtes libre de renommer les clones comme vous le souhaitez, par exemple foovers foo-badet foo-38vers foo.)

Enfin, vous pouvez également utiliser hg revert --all --rev 38puis valider. Cela créera une révision 46 qui semble identique à la révision 38. Vous continuerez ensuite à travailler à partir de la révision 46. Cela ne créera pas de fork de l'historique de la même manière explicite que l'a hg updatefait, mais d'un autre côté, vous ne vous plaindrez pas d'avoir plusieurs têtes. J'utiliserais hg revertsi je collaborais avec d'autres qui ont déjà fait leur propre travail basé sur la révision 45. Sinon, hg updatec'est plus explicite.

Martin Geisler
la source
2
Réponse IMPRESSIONNANTE. J'ai utilisé hg revert --all --rev ## et cela m'a sauvé le cul: D
Van Thoai Nguyen
1
Ne serait-il pas préférable de fermer également la branche de la tête pendante? Cela empêcherait de futurs avertissements sur le référentiel. Voir stackoverflow.com/a/3688320/900130
Zoltán
remarque: hg revert --all --rev xxx modifiera les fichiers locaux nécessaires pour revenir de l'endroit où vous vous trouvez dans votre référentiel local. Vous devez donc mettre à jour avant d'où vous souhaitez revenir.
Vincent
Pour dériver une version antérieure, j'ai d'abord dû faire un retour, puis une mise à jour. Cela étant dit, une explication moins opaque que la plupart.
CodeLurker
30

Je viens de rencontrer un cas de besoin de rétablir un seul fichier à la révision précédente, juste après avoir fait un commit et un push. La syntaxe abrégée pour spécifier ces révisions n'est pas couverte par les autres réponses, alors voici la commande pour le faire

hg revert path/to/file -r-2

Cela -2reviendra à la version avant la dernière validation, l'utilisation -1reviendrait simplement aux modifications non validées actuelles.

hyde
la source
1
Je trouve cela extrêmement utile. Bien sûr, pour l'option -r, vous pouvez simplement fournir le numéro de révision
Alex
Vous pouvez également sélectionner une révision spécifique. par exemplehg revert path/to/file -r478
Matt
7

À mon humble avis, hg strip -r 39convient mieux à ce cas.

Il nécessite que l'extension mq soit activée et présente les mêmes limitations que la "méthode de repo de clonage" recommandée par Martin Geisler: Si le changeset a été publié d'une manière ou d'une autre, il reviendra (probablement) à votre repo à un moment donné parce que vous avez seulement changé votre repo local.

magras
la source
Je ne connaissais pas celui-ci. Plus simple et plus propre que la suppression et le re-clonage du dépôt. Merci.
Rétablir Monica - notmaynard
6

Après utilisation, hg update -r REVil n'était pas clair dans la réponse comment valider ce changement afin que vous puissiez ensuite pousser.

Si vous essayez juste de valider après la mise à jour, Mercurial ne pense pas qu'il y ait de changements.

Je devais d'abord apporter une modification à n'importe quel fichier (disons dans un fichier README), donc Mercurial a reconnu que j'avais apporté une nouvelle modification, puis je pouvais le valider.

Cela a ensuite créé deux têtes comme mentionné.

Pour me débarrasser de l'autre tête avant de pousser, j'ai ensuite suivi l' étape de fusion sans opération pour remédier à cette situation.

J'ai alors pu pousser.

Brian Gershon
la source
vous pouvez faire un commit --close-branchsur l'ancienne branche. Vous pouvez également push -fpousser de nouvelles têtes, mais cela peut entraîner une confusion quant à savoir quelle est la version actuelle.
ctrl-alt-delor
5

Les réponses ci-dessus ont été des plus utiles et j'ai beaucoup appris. Cependant, pour mes besoins, la réponse succincte est:

hg revert --all --rev ${1}

hg commit -m "Restoring branch ${1} as default"

${1}est le numéro de la révision ou le nom de la branche. Ces deux lignes font en fait partie d'un script bash, mais elles fonctionnent bien seules si vous voulez le faire manuellement.

Cela est utile si vous devez ajouter un correctif à une branche de publication, mais que vous devez créer à partir de la valeur par défaut (jusqu'à ce que nous obtenions nos bons outils CI et capables de construire à partir de branches et de supprimer plus tard les branches de publication également).

Brian Carr
la source
1

J'installerais Tortoise Hg (une interface graphique gratuite pour Mercurial) et l'utiliserais. Vous pouvez ensuite simplement cliquer avec le bouton droit sur une révision à laquelle vous voudrez peut-être revenir - avec tous les messages de validation là sous vos yeux - et «Rétablir tous les fichiers». Rend intuitif et facile à faire défiler en avant et en arrière entre les versions d'un ensemble de fichiers, ce qui peut être vraiment utile si vous cherchez à déterminer quand un problème est apparu pour la première fois.

Geoff Kendall
la source