Mercurial cherry picking change for commit

dites, j'ai fait beaucoup de changements à mon code et n'ai besoin de commettre que quelques-uns de ces changements. Est-il un moyen de le faire dans mercurial? Je sais que darcs a une fonctionnalité comme celle-ci.

je sais hg transplant peut faire entre les branches, mais j'ai besoin de quelque chose comme cela pour avoir commis le code dans la présente branche, et non pas lors de l'ajout de changement établit à partir d'une autre branche.

56
demandé sur Kevin Panko 2009-05-13 01:23:26

10 réponses

MQ comme le Tchad mentionnés sont à sens unique. Il y a aussi des solutions plus légères:

  • Record extension qui fonctionne à peu près de la même manière que darcs record. Il est distribué avec mercurial.
  • Shelve extension qui vous permet de "mettre en attente" certains changements, vous permettant de ne commettre qu'un sous-ensemble de vos changements (ceux qui ne sont pas mis en attente)
33
répondu Kurt Schelfthout 2017-06-29 12:43:49

si vous utilisez TortoiseHg 1.x pour Windows, cette fonctionnalité est implémentée joliment "151940920, tout droit sorti de la boîte (pas d'extensions requises).

  1. Lancez L'outil TortoiseHg Commit.
  2. choisissez un fichier pour lequel vous souhaitez engager un sous-ensemble de ses changement.
  3. cliquez sur le Hunk Onglet de sélection dans le volet de prévisualisation.
  4. double-clic ou utilisez la barre d'espace pour bascule qui changent de mecs devraient être inclus dans la livraison.

Pour TortoiseHg 2.x , l'onglet Sélection de Hunk est maintenant parti. À sa place, est le Shelve tool . Il a un peu plus de fonctionnalités que la vieille sélection de hunk. Ces nouvelles fonctionnalités viennent au prix d'une complexité accrue.

enter image description here

Notez qu'il n'est pas nécessaire d'activer explicitement L'extension Mercurial Shelve lorsque vous utilisez cette fonctionnalité. Selon Steve Borho (développeur principal TortoiseHg) dans réponse à une question TortoiseHg différente : "nous avons une copie locale de l'extension de shelve et d'appeler directement dans elle."


pour TortoiseHg 2.7+ , cette fonctionnalité a été améliorée et réintroduite. Il est maintenant intégré directement dans L'outil de propagation:

example of change selection in the commit tool

note dans la liste des fichiers à gauche que le fichier supérieur est coché pour indiquer qu'il sera inclus, le second fichier n'est pas coché parce qu'il ne sera pas inclus, et le troisième fichier, échantillon.txt, est rempli (l'indicateur de case à cocher Null) parce que seuls les changements sélectionnés à partir de ce fichier seront inclus dans la propagation.

le passage à L'échantillon.txt qui be included est coché dans la partie inférieure droite de la sélection de changement de l'image. Le changement qui sera exclu n'est pas vérifié et la vue diff est grisée. Notez également que l'icône de l'outil de rayonnage est encore facilement disponible.

36
répondu mwolfe02 2017-06-29 12:45:00

le tutoriel Mercurial Queues est terrible pour ce cas d'utilisation. Tous les exemples que j'ai vus supposent que vous n'avez pas encore fait un commit et que vous rafraîchissez un seul patch. La plupart du temps ce n'est pas le cas, et vous avez 2 ou 3 commits que vous voulez écraser ensemble ou changer d'une autre manière.

disons que vous avez ce genre d'histoire:

---O---O---A---B---C

le premier exemple est de squash commits a, B, et C. premier init mq:

$ hg qinit

maintenant nous devons "importer" les commits a, B et c dans la file d'attente patch. Supposons qu'il s'agisse des 3 dernières propagations. Nous pouvons utiliser la syntaxe de révision "-N" pour les importer comme ceci:

$ hg qimport -r -3:-1

qui signifie importer sous forme de patches à partir de 3 patches jusqu'à la dernière propagation. Vous pouvez vérifier l'état de ces patches avec hg qseries . Il devrait montrer quelque chose comme ceci:

$ hg qseries
101.diff
102.diff
103.diff

où les nombres 101, 102 et 103 correspondent aux numéros de révision locale des propagations A, B et C. Maintenant ces correctifs sont appliqué , ce qui signifie que les changements qu'ils décrivent sont déjà dans la copie de travail. Vous pouvez vous débarrasser des modifications de la copie de travail et les supprimer de l'historique des propagations, en les sauvegardant uniquement sous forme de patch, en utilisant hg qpop . Vous pouvez soit dire hg qpop; hg qpop pour désactiver les changements C et B de la pile, soit spécifier un patch à"pop to". Dans ce cas, il serait quelque chose comme ceci:

$ hg qpop 101.diff
now at: 101.diff

vous avez maintenant les patches pour les commits B et c dans la file d'attente du patch, mais ils ne sont pas appliqués (leurs modifications ont été "perdues" - ils n'existent que dans la zone de la file d'attente du patch). Vous pouvez maintenant incorporer ces patches dans le dernier, c'est-à-dire créer une nouvelle propagation qui est l'équivalent de la somme des modifications A+B+C.

$ hg qfold -e 102.diff 103.diff

cela affichera votre éditeur pour que vous puissiez modifier le message de propagation. Par défaut, le message d' sera la concaténation des messages de propagation pour les changements A, B et c, séparés par des astérisques. La bonne chose ici est que hg qfold va tabuler-compléter les patches si vous utilisez bash et avoir le script de complétion HG source. Cela laisse l'histoire comme celle-ci, où A+B+C est un commit unique qui est la combinaison des 3 patches qui nous intéressent:

---O---O---A+B+C

un autre cas d'utilisation est si nous avons le même genre d'histoire qu'avant, mais nous voulons laisser tomber patch B et fusionner A+C. Ceci est assez similaire à ci-dessus en fait. Quand vous arrivez à l'étape de qfold, vous ne feriez que plier dans le dernier commit plutôt que le dernier 2 commits:

$ hg qfold -e 103.diff

cela laisse le changement pour B dans la file d'attente du patch, mais il n'est pas appliqué à la copie de travail et son commit n'est pas dans l'histoire. Vous pouvez le voir en exécutant:

$ hg qunapplied
102.diff

l'histoire ressemble maintenant à ceci, où A+C est un commit simple qui combine modifications A et C:

---O---O---A+C

un cas d'utilisation finale pourrait être que vous devez appliquer seulement commit C. Vous le feriez en exécutant qimport comme ci-dessus, et vous retireriez tous les correctifs que vous ne vouliez pas:

$ hg qpop -a

le drapeau-A signifie pop off tous les patches. Maintenant, vous pouvez appliquer juste celui que vous voulez:

$ hg qpush 103.diff

Cela vous laisse avec cette histoire:

---O---O---C

une Fois que vous avez terminé avec tout ça, tu dois finir la file d'attente. Cela peut être fait avec:

$ hg qfinish -a

nous y voilà. Vous pouvez maintenant exécuter hg push et ne propager que ce que vous voulez, ou hg email un correctif cohérent à la liste de diffusion.

16
répondu richq 2009-05-13 20:35:02

j'ai l'impression de rater quelque chose parce que personne ne l'a déjà suggéré.

la commande normale" HG commit " peut être utilisée pour choisir sélectivement ce qu'il faut commettre (vous n'avez pas à propager toutes les modifications en attente dans le répertoire de travail local).

si vous avez un ensemble de modifications comme ceci:

M ext-web/docroot/WEB-INF/liferay-display.xml
M ext-web/docroot/WEB-INF/liferay-portlet-ext.xml
M ext-web/docroot/WEB-INF/portlet-ext.xml

vous pouvez commettre seulement deux de ces changements avec...

hg commit -m "partial commit of working dir changes" ext-web/docroot/WEB-INF/liferay-display.xml ext-web/docroot/WEB-INF/liferay-portlet-ext.xml

pas très pratique de la ligne de commande parce que vous devez taper à la main les fichiers à propager (par rapport à un processus de boîte à cocher GUI comme tortoise), mais c'est aussi simple que possible et ne nécessite aucune extension. Et le globbing de fichiers peut probablement aider à réduire la saisie (comme ci-dessus, les deux fichiers engagés partagent de manière unique "liferay" dans leurs noms de chemin.

16
répondu Gary Affonso 2011-12-26 21:08:18

vous pouvez utiliser le record extension , qui est distribué avec Mercurial.

vous devez d'abord l'activer dans votre fichier ~/.hgrc , en l'ajoutant à la section [extensions] :

[extensions]
record=

tapez hg record au lieu de hg commit , et vous pourrez sélectionner les modifications à apporter aux fichiers que vous voulez propager.

vous pouvez également utiliser l'extension crecord qui fournit une interface plus agréable pour examiner et sélectionner les changements. (Il n'est pas distribué avec Mercurial, cependant, et je l'ai vu de temps en temps gâcher un commit donc il n'est pas complètement sans bug.)

7
répondu ronnix 2016-10-15 12:06:34

quelque temps a passé. Semble que la meilleure option est maintenant hg commit --interactive

4
répondu ElyashivLavi 2017-02-07 07:28:45

je crois Mercurial Files d'attente remplit ce rôle pour Mercurial. Il y a un très bon tutoriel lié là.

3
répondu Chad Birch 2017-06-29 12:44:21

Essayer qct (Qt Commettre l'Outil). Il a une fonction "select changes" qui démarre un outil de fusion à 3 voies pour vous permettre d'annuler des changements individuels. Après que vous vous engagez, ces changements que vous "undd" revenez.

2
répondu 2009-05-24 22:51:31

j'utilise engagez-patch . C'est un script qui vous permet d'éditer la diff avant de commettre. C'est très agréable avec le mode diff et le mode vc D'Emacs.

dans le passé j'ai utilisé crecord, mais il y a des bogues liés à unicode (en fait l'extension record a les bogues, dont crecord dépend).

2
répondu jpkotta 2010-10-07 21:42:34

vous devez d'abord oublier tout ce que vous avez toujours su sur GUI et revenir à la ligne de commande. Suivant de la ligne de commande faites ceci:

hg stat > filelist.txt

cette pipes tous vos fichiers modifiés dans un fichier texte appelé filelist.txt

ensuite, éditez votre liste de fichiers pour n'inclure que les fichiers que vous souhaitez propager.

Enfin valider à l'aide de la fileset sytnax:

hg commit "définies: listfile:test.txt' "

-1
répondu SSchulte 2014-04-17 19:37:35