Mercurial: comment modifier le dernier commit?

Je cherche une contre-partie de git commit --amend dans Mercurial, c’est-à-dire un moyen de modifier le commit auquel ma copie de travail est liée. Les exigences pour cette procédure de modification sont les suivantes:

  • si possible, il ne devrait nécessiter aucune extension. Il ne doit pas nécessiter d’extensions autres que celles par défaut , c’est-à-dire des extensions qui ne sont pas fournies avec une installation officielle Mercurial.

  • Si l’engagement à modifier est un chef de ma twig actuelle, aucun nouveau chef ne devrait être créé. Si le commit n’est pas la tête, une nouvelle tête peut être créée.

  • la procédure doit être sûre de manière à ce que, pour quelque raison que ce soit, la modification échoue, je souhaite restaurer la même copie de travail et le même état du référentiel qu’avant la modification. En d’autres termes, si la modification elle-même peut échouer, il devrait y avoir une procédure de sécurité pour restaurer la copie de travail et l’état du référentiel. Je fais référence aux “échecs” qui sont liés à la nature de la procédure de modification (comme par exemple les conflits), pas aux problèmes liés aux systèmes de fichiers (comme les ressortingctions d’access, l’impossibilité de verrouiller un fichier pour l’écriture, …) )

Mise à jour (1):

  • la procédure doit être automatisable , elle peut donc être effectuée par un client GUI sans aucune intervention de l’utilisateur.

Mise à jour (2):

  • les fichiers du répertoire de travail ne doivent pas être touchés (il peut y avoir des verrous du système de fichiers sur certains fichiers modifiés). Cela signifie en particulier qu’une approche possible ne peut à aucun moment nécessiter un répertoire de travail propre.

    Avec la sortie de Mercurial 2.2 , vous pouvez utiliser l’option --amend avec hg commit pour mettre à jour le dernier commit avec le répertoire de travail actuel

    À partir de la référence de ligne de commande :

    Le drapeau –amend peut être utilisé pour modifier le parent du répertoire de travail avec un nouvel commit contenant les modifications du parent en plus de celles signalées par le statut hg, le cas échéant. L’ancien commit est stocké dans un bundle de sauvegarde dans .hg / ssortingp-backup (voir help bundle hg et hg aident à la décomposer).

    Le message, l’utilisateur et la date sont extraits du commit modifié, sauf indication contraire. Lorsqu’un message n’est pas spécifié sur la ligne de commande, l’éditeur s’ouvre avec le message du commit modifié.

    Ce qui est génial, c’est que ce mécanisme est “sûr”, car il s’appuie sur la fonctionnalité “Phases” relativement nouvelle pour empêcher les mises à jour qui modifieraient l’historique qui a déjà été rendu disponible en dehors du référentiel local.

    Vous avez 3 options pour éditer les commits dans Mercurial:

    1. hg ssortingp --keep --rev -1 annule les derniers hg ssortingp --keep --rev -1 (1), vous pouvez donc recommencer (voir cette réponse pour plus d’informations).

    2. Utilisation de l’ extension MQ , livrée avec Mercurial

    3. Même s’il n’est pas fourni avec Mercurial, l’extension Histedit mérite d’être mentionnée.

    Vous pouvez également consulter la page Historique de l’ édition du wiki Mercurial.

    En bref, l’édition de l’histoire est vraiment difficile et découragée . Et si vous avez déjà poussé vos changements, il n’y a presque rien que vous puissiez faire, sauf si vous avez le contrôle total de tous les autres clones.

    Je ne suis pas vraiment familier avec la commande git commit --amend , mais AFAIK, Histedit est ce qui semble être l’approche la plus proche, mais malheureusement elle n’est pas livrée avec Mercurial. MQ est vraiment compliqué à utiliser, mais vous pouvez presque tout faire avec.

    Équivalent GUI pour hg commit --amend :

    Cela fonctionne également à partir de l’interface graphique de TortoiseHG (j’utilise la version 2.5):

    Passez à la vue “Valider” ou, dans la vue du plan de travail, sélectionnez l’entrée “Répertoire de travail”. Le bouton «Valider» comporte une option nommée «Modifier la révision en cours» (cliquez sur la flèche déroulante du bouton pour le trouver).

    entrer la description de l'image ici

      || || \/ 

    entrer la description de l'image ici

    Caveat emptor :

    Cette option supplémentaire ne sera activée que si la version mercurial est au moins 2.2.0 et si la révision en cours n’est pas publique, n’est pas un patch et n’a pas d’enfants. […]

    Cliquer sur le bouton appellera “commit –amend” pour “modifier” la révision.

    Plus d’infos à ce sujet sur le canal de développement THG

    En supposant que vous n’avez pas encore propagé vos changements, voici ce que vous pouvez faire.

    • Ajoutez à votre .hgrc:

       [extensions] mq = 
    • Dans votre référentiel:

       hg qimport -r0:tip hg qpop -a 

      Bien sûr, vous n’avez pas besoin de commencer par la révision zéro ou de faire apparaître tous les correctifs, car le dernier seul pop ( hg qpop ) suffit (voir ci-dessous).

    • Supprimez la dernière entrée du .hg/patches/series ou les patchs que vous n’aimez pas. La réorganisation est également possible.

    • hg qpush -a; hg qfinish -a
    • Supprimez les fichiers .diff (correctifs non appliqués) toujours dans .hg / patches (devrait en contenir un dans votre cas).

    Si vous ne souhaitez pas reprendre tout votre correctif, vous pouvez le modifier en utilisant hg qimport -r0:tip (ou similaire), puis éditez des éléments et utilisez hg qrefresh pour fusionner les modifications dans le patch le plus haut de votre stack. Lisez l’ hg help qrefresh .

    En éditant .hg/patches/series , vous pouvez même supprimer plusieurs patchs ou en réorganiser. Si votre dernière révision est 99, vous pouvez simplement utiliser hg qimport -r98:tip; hg qpop; [edit series file]; hg qpush -a; hg qfinish -a hg qimport -r98:tip; hg qpop; [edit series file]; hg qpush -a; hg qfinish -a hg qimport -r98:tip; hg qpop; [edit series file]; hg qpush -a; hg qfinish -a .

    Bien entendu, cette procédure est fortement déconseillée et risquée . Faites une sauvegarde de tout avant de faire cela!

    En tant que sidenote, je l’ai fait des milliards de fois sur des repositorys privés.

    Je suis à l’écoute de ce que krtek a écrit. Plus précisément la solution 1:

    Hypothèses:

    • vous avez engagé un (!) changeset mais ne l’avez pas encore poussé
    • vous souhaitez modifier cet ensemble de modifications (par exemple, append, supprimer ou modifier des fichiers et / ou le message de validation)

    Solution:

    • utiliser hg rollback pour annuler le dernier commit
    • commettre à nouveau avec les nouveaux changements en place

    La restauration annule vraiment la dernière opération. Sa façon de travailler est assez simple: les opérations normales dans HG ne feront que s’append aux fichiers; ceci inclut un commit. Mercurial garde une trace de la longueur des fichiers de la dernière transaction et peut donc annuler complètement une étape en tronquant les fichiers à leur ancienne longueur.

    Les versions récentes de Mercurial incluent l’extension hg amend qui fournit la commande hg amend . Cela permet de modifier un commit sans perdre l’historique de pré-modification dans votre contrôle de version.

    hg amender [OPTION] … [FICHIER] …

    alias: refresh

    combinez un ensemble de modifications avec les mises à jour et remplacez-le par un nouveau

     Commits a new changeset incorporating both the changes to the given files and all the changes from the current parent changeset into the repository. See 'hg commit' for details about committing changes. If you don't specify -m, the parent's message will be reused. Behind the scenes, Mercurial first commits the update as a regular child of the current parent. Then it creates a new commit on the parent's parents with the updated contents. Then it changes the working copy parent to this new combined changeset. Finally, the old changeset and its update are hidden from 'hg log' (unless you use --hidden with log). 

    Voir https://www.mercurial-scm.org/doc/evolution/user-guide.html#example-3-amend-a-changeset-with-evolve pour une description complète de l’extension evolve .