web-dev-qa-db-fra.com

Mercurial: comment modifier le dernier commit?

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

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

  • si l'engagement à modifier est une tête de ma branche actuelle, aucune nouvelle tête ne devrait être créé. Si le commit n'est pas head, une nouvelle tête peut être créée.

  • la procédure doit être sûre de manière à ce que si, pour quelque raison que ce soit, la modification échoue, je souhaite que la même copie de travail et le même état de référentiel soient restaurés comme avant la modification. En d'autres termes, si la modification elle-même peut échouer, il devrait exister une procédure de sécurité intégrée permettant de restaurer la copie de travail et l'état du référentiel. Je fais référence aux "échecs" qui relèvent de la nature de la procédure de modification (comme les conflits, par exemple), et non de problèmes liés au système de fichiers (comme les restrictions d'accès, l'impossibilité de verrouiller un fichier pour l'écriture, ... )

Mise à jour (1):

  • la procédure doit être automatable , de sorte qu'elle puisse être exécuté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 est possible que certains fichiers modifiés soient verrouillés). Cela signifie notamment qu’une approche possible ne peut à aucun moment exiger un répertoire de travail propre.
201
mstrap

Avec la version Mercurial 2.2 , vous pouvez utiliser l'option --amend avec hg commit pour mettre à jour le dernier commit avec le répertoire de travail en cours.

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

L'indicateur --amend peut être utilisé pour modifier le parent du répertoire de travail avec un nouveau commit contenant les modifications du parent, en plus de celles déjà signalées par le statut hg, le cas échéant. L'ancien commit est stocké dans un ensemble de sauvegarde au format .hg/strip-backup (voir hg help bundle et hg help dissocier pour savoir comment le restaurer).

Le message, l'utilisateur et la date proviennent de la validation modifiée, 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 bien, c’est que ce mécanisme est «sûr», car il s’appuie sur la fonctionnalité relativement nouvelle «Phases» pour empêcher les mises à jour qui modifieraient l’historique déjà disponible en dehors du référentiel local.

276
Chris Phillips

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

  1. hg strip --keep --rev -1 annule le (1) dernier (s) commit (s), afin que vous puissiez le refaire (voir cette réponse pour plus d’informations).

  2. Utilisation de l’extension MQ fournie avec Mercurial 

  3. Même si elle n’est pas livrée avec Mercurial, il faut mentionner l’extension Histedit

Vous pouvez également consulter la page Historique des modifications du wiki Mercurial.

En bref, l’édition de l’histoire est très difficile et découragée. Et si vous avez déjà poussé vos modifications, vous ne pouvez pratiquement plus rien faire, sauf si vous avez le contrôle total de tous les autres clones.

Je ne connais pas vraiment la commande git commit --amend, mais autant que je sache, 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.

51
krtek

Equivalent graphique pour hg commit --amend:

Cela fonctionne également à partir de l'interface graphique de TortoiseHG (j'utilise v2.5):

Basculez dans la vue "Valider" ou, dans la vue "Plan de travail", sélectionnez l’entrée "Répertoire de travail" . Le bouton "Valider" a une option intitulée "Modifier la révision actuelle" (cliquez sur la flèche du menu déroulante pour le trouver) ). 

enter image description here

          ||
          ||
          \/

enter image description here

Caveat emptor:

Cette option supplémentaire ne sera activée que si la version de Mercurial est au moins 2.2.0, et si la révision en cours n'est pas publique, n'est pas un correctif et n'a pas de les enfants. [...] 

Cliquez sur le bouton pour appeler 'engage --amend' pour 'modifier' la révision. 

Plus d'informations à ce sujet sur le canal THG dev

37
Cristi Diaconescu

En supposant que vous n’ayez pas encore propagé vos modifications, 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 supprimer tous les patchs, car le dernier (hg qpop) suffit (voir ci-dessous).

  • supprimez la dernière entrée du fichier .hg/patches/series ou les correctifs que vous n’aimez pas. La réorganisation est possible aussi.

  • hg qpush -a; hg qfinish -a
  • supprimez les fichiers .diff (correctifs non appliqués) toujours dans le fichier .hg/patches (il devrait en être un dans votre cas).

Si vous ne voulez pas à reprendre tout de votre patch, vous pouvez le modifier en utilisant hg qimport -r0:tip (ou similaire), puis modifier les éléments et utiliser hg qrefresh pour fusionner les modifications dans le patch le plus haut de votre empiler. Lisez hg help qrefresh.

En éditant .hg/patches/series, vous pouvez même supprimer plusieurs correctifs 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.

Bien sûr, cette procédure est fortement découragée et risquée . Faites une sauvegarde de tout avant de faire cela!

En tant que sidenote, je l'ai déjà fait des millions de fois sur des référentiels réservés aux particuliers.

8
hochl

Je suis à l'écoute de ce que krtek a écrit. Plus spécifiquement la solution 1:

Hypothèses:

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

Solution:

  • utiliser hg rollback pour annuler le dernier commit
  • engager à 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 seront uniquement ajoutées aux fichiers; cela inclut un commit. Mercurial enregistre les longueurs de fichier de la dernière transaction et peut donc annuler complètement une étape en tronquant les fichiers à leur ancienne longueur.

7
Lucero

Les versions récentes de Mercurial incluent l'extension evolve 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 modifier [OPTION] ... [DOSSIER] ...

alias: actualiser

combinez un changeset avec des 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.

0
Karl Bartel

Pourrait ne pas résoudre tous les problèmes de la question initiale, mais comme cela semble être le post de facto sur la façon dont Mercurial peut modifier un engagement précédent, je vais ajouter mes 2 centimes d’informations.

Si vous êtes comme moi et que vous souhaitez uniquement modifier le message de validation précédent (réparer une faute de frappe, etc.) sans ajouter de fichier, cela fonctionnera.

hg commit -X 'glob:**' --amend

Sans aucun modèle d'inclusion ou d'exclusion, hg commit inclura par défaut tous les fichiers dans le répertoire de travail. L'application du modèle -X 'glob:**' exclura tous les fichiers possibles, ne permettant que de modifier le message de validation.

Sur le plan fonctionnel, cela revient à git commit --amend lorsqu'il n'y a aucun fichier dans index/stage.

0
kaskelotti