web-dev-qa-db-fra.com

Avec Mercurial, comment puis-je "compresser" une série de changesets avant de pousser?

Disons que j'ai un référentiel Mercurial local et distant. Maintenant, je commence à travailler sur une fonctionnalité. Je travaille dessus, et quand je pense que c'est fait, je valide le changeset. En testant un peu plus, je trouve que je pourrais améliorer encore cette fonctionnalité en modifiant quelque chose dans le code. Je fais le changement et je m'engage. 20 minutes plus tard, je découvre qu'il y a un bogue dans cette nouvelle fonctionnalité. Je le répare donc et le commets également.

J'ai maintenant 3 changesets que je voudrais vraiment pousser vers le référentiel distant comme un changeset avec le message "Implementing feature X", par exemple.

Comment puis-je faire cela sans trop de soucis? Je crois que je pourrais le faire avec des patchs, mais cela me semble beaucoup de travail.

93
Lucas

Que diriez-vous du Collapse Extension ?

38
Steve Losh

L'extension histedit correspond exactement à ce que vous recherchez.

hg histedit -o

ou

hg histedit --outgoing

affichera une liste des changesets sortants. De la liste, vous pouvez

  • Plier 2 ou plusieurs ensembles de modifications en créant un seul ensemble de modifications
  • Supprime les changesets en les supprimant de l'historique
  • Réorganisez les changesets comme bon vous semble.

histedit vous demandera le nouveau message de validation des changesets pliés dont les valeurs par défaut sont les deux messages séparés par "\ n ***\n".

Vous pouvez également obtenir des résultats similaires avec l’extension mq, mais c’est beaucoup plus difficile.

Vous pouvez également utiliser l'extension collapse uniquement pour le pliage, mais elle ne fournit pas une interface utilisateur aussi agréable que Nice ni un moyen de modifier le message de validation résultant. La modification du message de validation résultant permet également de nettoyer le message final, ce que je finis toujours par utiliser.

48
Stefan Rusek

Oui, vous pouvez le faire avec des correctifs: Supposons que votre travail se situe dans les changesets 100 à 110 inclus.

  1. Créez un patch:

    % hg export -o mypatch 100:110 --git

  2. Mettre à jour à 99:

    % hg update 99

  3. Appliquez le correctif avec --no-commit (sinon vous récupérerez tous vos changesets):

    % hg import --no-commit mypatch

  4. Commettez tous les changements en même temps:

    % hg commit

  5. Vous avez maintenant deux têtes (110 et 111) qui devraient être équivalentes en termes de fichiers qu’elles produisent dans votre répertoire de travail.

    % hg strip 100

OK, maintenant que j'ai tout épelé, cela semble long, mais l'ayant fait moi-même plusieurs fois, je ne trouve pas que ce soit une corvée trop lourde ...

20
Arkady

Si vous utilisez TortoiseHg, utilisez peut simplement sélectionner deux révisions (utilisez CTRL pour sélectionner les suivantes), faites un clic droit et sélectionnez "Compresser l’historique" .

Après cela, vous obtiendrez une nouvelle liste de modifications dans new head à partir de la première modification que vous avez précédemment sélectionnée. Elle contiendra toutes les listes de modifications descendantes entre celles que vous avez sélectionnées.

Vous pouvez simplement supprimer les anciennes listes de modifications si vous n'en avez plus besoin: utilisezMQextensions pour cela. Encore une fois, dans TortoiseHg: faites un clic droit sur la première liste de modifications à supprimer avec tous ses descendants, "Modify History -> Strip" .

19
Rageous

Ma méthode préférée d’utilisation de mq pour ce pliage est d’utiliser TortoiseHg comme décrit ici . Cependant, cela peut facilement être fait depuis la ligne de commande comme ceci:

hg qimport -r <first>:<last> 
    -- where <first> and <last> are the first and last changesets 
    -- in the range of revisions you want to collapse

hg qpop <first>.diff
    -- remove all except for the first patch from the queue
    -- note: mq names patches <#>.diff when it imports them, so we're using that here

hg qfold <next>.diff
    -- where <next> is <first>+1, then <first>+2, until you've reached <last>

hg qfinish -a
    -- apply the folded changeset back into the repository

(Il y a peut-être une meilleure façon de faire l'étape qfold, mais je n'en suis pas conscient, j'utilise habituellement TortoiseHg pour cette opération.)

Cela semble un peu compliqué au début, mais une fois que vous avez commencé à utiliser mq, c’est assez simple et naturel;

18
Chris Phillips

hg collapse et hg histedit sont les meilleurs moyens. Ou plutôt, ce serait la meilleure façon, s’ils fonctionnaient de manière fiable ... J’ai eu histedit pour planter avec un vidage de pile dans les trois minutes. Collapse n'est pas tellement mieux.

Je pensais pouvoir partager deux autres BKM:

  1. hg rebase --collapse

    Cette extension est distribuée avec Mercurial. Je n'ai pas encore eu de problèmes avec ça. Il se peut que vous deviez jouer à certains jeux pour contourner les limitations de hg rebase - fondamentalement, cela n’aime pas de changer de base pour un ancêtre sur la même branche, nommée ou par défaut, bien que cela le permette en cas de changement de base entre branches (nommées).

  2. Déplacez le référentiel (foo/.hg) vers le répertoire de travail (bar) et ses fichiers. Pas l'inverse.

Certaines personnes ont parlé de créer deux arbres de clonage et de copier des fichiers entre eux. Ou se patcher entre eux. Au lieu de cela, il est plus facile de déplacer les répertoires .hg.

hg clone project work
... lots of edits
... hg pull, merge, resolve
hg clone project, clean
mv work/.hg .hg.work
mv clean/.hg work/.hg
cd work
... if necessary, pull, nerge, reconcile - but that would only happen because of a race
hg Push

Cela fonctionne tant que les vrais référentiels, les arborescences .hg, sont indépendants du répertoire de travail et de ses fichiers.

S'ils ne sont pas indépendants ...

4
Krazy Glew

Je n'ai jamais utilisé Mercurial, mais cela ressemble beaucoup à ce dont Martin Fowler parlait il y a peu sur son blog:

http://martinfowler.com/bliki/MercurialSquashCommit.html

2
Joseph

Supposons que vous ayez deux commits THIS et THAT non publiés dans Mercurial et que vous souhaitiez rejoindre le commit unique à THIS point ::

... --> THIS --> ... --> THAT --> ... --> LAST

Vérifiez que vos commits ne sont pas publiés ::

$ hg glog -r "draft() & ($THIS | $THAT)"

Mettre à jour à LAST commit ::

$ hg up

et importer commet jusqu'à THIS dans MQ ::

$ hg qimport $THIS::.

Désappliquez tous les patchs et appliquez uniquement la première THIS ::

$ hg qpop -a
$ hg qpush
$ hg qapplied
... THIS ...

Rejoindre avec THAT ::

$ hg qfold $THATNAME

NOTE Pour trouver le nom THATNAME, utilisez ::

$ hg qseries

Appliquez tous les correctifs et déplacez-les vers l'historique du référentiel:

$ hg qpush -a
$ hg qfinish -a

Mon article de blogue sur le sujet est Rejoindre deux commits dans Mercurial .

0
gavenkoa

HistEdit fera ce que vous voulez, mais c'est probablement trop cher. Si la seule chose dont vous avez besoin est de plier certains changesets, le Collapse Extension fera l'affaire.

0
Steve Losh

Oui, strip --keep fonctionne pour la question de l'auteur. Mais c'était légèrement différent des autres, par exemple, si vous avez une version de 1 à 30 mais que vous voulez seulement réduire la version 12-15. D'autres solutions fonctionnent mais pas strip --keep

0
Frank Tao

Pourquoi pas juste la commande hg strip --keep?

Ensuite, vous pouvez valider toutes les modifications en une seule.

0
G. Demecki