Mercurial déplace les modifications vers une nouvelle branche

124

J'ai un certain nombre de changements que j'ai commis dans mon référentiel local, mais qui n'ont pas encore été poussés. Étant donné qu'une fonctionnalité prend plus de temps que prévu, je souhaite échanger ces modifications sur une branche nommée avant de pousser. Comment puis-je faire ceci?

Casebash
la source

Réponses:

153

Comme suggéré par Mark, la MqExtension est une solution pour votre problème. IMHO un flux de travail plus simple consiste à utiliser l' extension rebase . Supposons que vous ayez une histoire comme celle-ci:

@  changeset:   2:81b92083cb1d
|  tag:         tip
|  summary:     my new feature: edit file a
|
o  changeset:   1:8bdc4508ac7b
|  summary:     my new feature: add file b
|
o  changeset:   0:d554afd54164
   summary:     initial

Cela signifie que la révision 0est la base sur laquelle vous avez commencé à travailler sur votre fonctionnalité. Maintenant, vous voulez avoir des révisions 1-2sur une branche nommée, disons my-feature. Mettre à jour vers la révision 0et créer cette branche:

$ hg up 0
$ hg branch my-feature
$ hg ci -m "start new branch my-feature"

L'histoire ressemble maintenant à ceci:

@  changeset:   3:b5939750b911
|  branch:      my-feature
|  tag:         tip
|  parent:      0:d554afd54164
|  summary:     start new branch my-feature
|
| o  changeset:   2:81b92083cb1d
| |  summary:     my new feature: edit file a
| |
| o  changeset:   1:8bdc4508ac7b
|/   summary:     my new feature: add file b
|
o  changeset:   0:d554afd54164
   summary:     initial

Utilisez la rebasecommande pour déplacer les révisions 1-2vers la révision 3:

$ hg rebase -s 1 -d 3

Cela donne le graphique suivant:

@  changeset:   3:88a90f9bbde7
|  branch:      my-feature
|  tag:         tip
|  summary:     my new feature: edit file a
|
o  changeset:   2:38f5adf2cf4b
|  branch:      my-feature
|  summary:     my new feature: add file b
|
o  changeset:   1:b5939750b911
|  branch:      my-feature
|  summary:     start new branch my-feature
|
o  changeset:   0:d554afd54164
   summary:     initial

C'est tout ... comme mentionné dans les commentaires à la réponse de Mark, déplacer des ensembles de modifications déjà poussés est généralement une mauvaise idée, à moins que vous ne travailliez dans une petite équipe où vous êtes capable de communiquer et d'appliquer votre manipulation d'historique.

Oben Sonne
la source
4
IMHO l'inconvénient de cette solution est qu'elle introduit un commit factice "start new branch my-feature" (c'est-à-dire un qui ne change aucun fichier).
sschuberth
9
@sschuberth: Je pense qu'être explicite est une bonne chose ici. Si le changeset supplémentaire vous pose problème, combinez-le avec le suivant (par exemple en utilisant la foldcommande de l' extension histedit désormais intégrée ).
Oben Sonne
6
@AmirRachum: hg log -G( GraphlogExtension ). J'ai supprimé certaines lignes manuellement, mais il aurait également pu être rendu complètement automatiquement à l'aide de styles de journal personnalisés .
Oben Sonne
2
Activer l' extension de rebase : mercurial.selenic.com/wiki/RebaseExtension#Configuration
56ka
1
@sschuberth Je suis d'accord. Ma solution de contournement consiste à rebaser vos commits non factices sur le parent du commit factice avec l'indicateur --keepbranches, puis à supprimer votre commit factice. C'est beaucoup de travail pour changer le nom d'une branche, mais parfois Mercurial est stupide comme ça.
weberc2
30

Vous pouvez utiliser le MqExtension . Disons que les ensembles de modifications à déplacer sont des révisions 1 à 3:

hg qimport -r 1:3    # convert revisions to patches
hg qpop -a           # remove all them from history
hg branch new        # start a new branch
hg qpush -a          # push them all back into history
hg qfin -a           # finalize the patches
Mark Tolonen
la source
Je souhaite importer 63:64 et 66:68. Je reçois la révision 65 n'est pas le parent de 64
Casebash
Que voulez-vous faire avec 65 ans? Mq ne peut convertir que des ensembles de modifications consécutifs à partir d'une tête. Il transforme les changesets normalement immuables en patchs mutables qui peuvent être édités. Cela modifie les hachages (affectant tous les enfants), vous ne pouvez donc pas sauter.
Mark Tolonen
J'ai un certain nombre de changements (dont 65) que j'ai fait sur la branche principale et que j'ai poussé
Casebash
1
Ne modifiez pas les ensembles de modifications qui ont été poussés. Mq modifie les hachages pour qu'ils soient effectivement de nouveaux ensembles de modifications. Modifier uniquement l'historique qui n'a pas été poussé.
Mark Tolonen
Si vous avez déjà poussé 65, vous ne devriez certainement pas déplacer 63 et 64, et simplement vous contenter de déplacer 66:68 (encore une fois, seulement si vous ne les avez pas poussés).
Matt
9

Je préfère la solution de patch décrite ici par Mark Tolonen

Ce que j'ai:

hg log -G

#default branch
@  changeset:   3:cb292fcdbde1
|
o  changeset:   2:e746dceba503
|
o  changeset:   1:2d50c7ab6b8f
|
o  changeset:   0:c22be856358b

Ce que je veux:

  @  changeset:   3:0e85ae268e35
  |  branch:      feature/my_feature
  |
  o  changeset:   2:1450cb9ec349
  |  branch:      feature/my_feature
  |
  o  changeset:   1:7b9836f25f28
  |  branch:      feature/my_feature
  |
 /
|
o  changeset:   0:c22be856358b

commandes mercurials:

hg export -o feature.diff 1 2 3
hg update 0
hg branch feature/my_feature
hg import feature.diff

Voici l'état de mon référentiel local

@  changeset:   6:0e85ae268e35
|  branch:      feature/my_feature
|
o  changeset:   5:1450cb9ec349
|  branch:      feature/my_feature
|
o  changeset:   4:7b9836f25f28
|  branch:      feature/my_feature
|
| o  changeset:   3:cb292fcdbde1
| |
| o  changeset:   2:e746dceba503
| |
| o  changeset:   1:2d50c7ab6b8f
|/
|
o  changeset:   0:c22be856358b

Maintenant, je dois supprimer les révisions 1 2 et 3 de ma branche par défaut. Vous pouvez le faire avec la commande strip de l'extension mq. hg stripsupprime l'ensemble de modifications et tous ses descendants du référentiel.

Activez l'extension en ajoutant les lignes suivantes à votre fichier de configuration (.hgrc ou Mercurial.ini):

vim ~/.hgrc et ajouter :

[extensions]
mq =

Et maintenant supprimez ce référentiel à la révision 1.

hg strip 1

et nous voici

@  changeset:   3:0e85ae268e35
|  branch:      feature/my_feature
|
o  changeset:   2:1450cb9ec349
|  branch:      feature/my_feature
|
o  changeset:   1:7b9836f25f28
|  branch:      feature/my_feature
|
o  changeset:   0:c22be856358b

Remarque: les changesets sont différents mais les révisions sont les mêmes

Guillaume Vincent
la source
5

Pour ceux qui sont enclins à utiliser l'interface graphique

  1. Allez à Tortoise Hg-> File-> Settingspuis cochez rebase.

entrez la description de l'image ici

  1. Redémarrez l'interface utilisateur de la tortue

  2. Créez une nouvelle branche dans laquelle vous déplacerez les modifications. Cliquez sur le nom de la branche actuelle -> choisissez Open a new named branch-> choisissez le nom de la branche.

entrez la description de l'image ici

  1. Si les modifications que vous souhaitez déplacer n'ont pas été apportées public(par exemple draft), passez à 5. (Si des modifications ont déjà été publiées et que vous n'êtes pas un développeur senior, vous devriez en parler à quelqu'un de senior (obtenir un bouc émissaire) car vous risquez de tout gâcher. , Je ne prends aucune responsabilité :)).

Allez sur View-> Show Console(ou Ctrl+ L) puis écrivez dans la console hg phase -f -d 2- où 2 est la version la plus basse que vous déplacerez vers la nouvelle branche.

  1. Aller à la branche et à la révision (devrait être la révision la plus élevée si vous déplacez les modifications vers la nouvelle branche créée à l'étape 3.) Right Mouse->Update

  2. Allez dans la branche et la révision à partir de laquelle vous déplacerez les modifications Right Mouse-> Modify History->Rebase

entrez la description de l'image ici

  1. Cliquez Rebaseet priez pour qu'il n'y ait pas de conflits, fusionnez si vous le devez.

  2. Poussez les changements, à ce stade, toutes les révisions devraient toujours l'être draft.

  3. Accédez à la révision la plus élevée de la branche vers laquelle vous déplaçiez les modifications Right Mouse-> Change Phase to-> Public.

entrez la description de l'image ici

J'espère que cela vous fera gagner du temps.

Matas Vaitkevicius
la source
Bon travail! va essayer ceci, juste une question cependant - pourquoi changer la phase en public à la fin? "Tous les ensembles de modifications vus dans un référentiel distant sont publics", alors quand vous poussez, ne serait-il pas défini comme public de toute façon?
Joshua Duxbury
@JoshLeeDucks En poussant, ils ne se transforment publicplus automatiquement (du moins pour moi, ils ne le font pas).
Matas Vaitkevicius