Comment mettre de côté un tas de changements non engagés tout en travaillant sur autre chose

98

Si j'ai un tas de changements non validés et que je veux les mettre de côté tout en travaillant sur autre chose à la place, puis plus tard (fi après plusieurs jours), revenez-y et continuez à travailler. Quel serait le flux de travail le plus simple pour y parvenir? (Jusqu'à présent, je n'ai d'expérience qu'avec les fonctionnalités de base de Mercurial). Ma méthode habituelle était de créer une nouvelle branche en utilisant le clone, mais il pourrait y avoir de meilleures façons.

Erik
la source

Réponses:

133

Vous avez une poignée d'options:

  1. Étalez les articles. Cela enregistre les modifications et les supprime du répertoire de travail afin que la branche puisse continuer. Cela ne crée pas un ensemble de modifications.

    hg shelve --all --name "UnfinishedChanges"
    
    hg unshelve --name "UnfinishedChanges"
    

    Mettre à jour / modifier : les nouvelles versions de mercurial peuvent avoir besoin d'utiliser

    hg shelve -n "UnfinishedChanges"
    hg unshelve "UnfinishedChanges"
    

    Vous pouvez toujours utiliser --namecomme alternative à -n, mais mercurial ne semble --nameplus aimer . De plus, le --alln'est plus nécessaire et Mercurial va en fait paniquer.

  2. Mettre en file d'attente les éléments à l'aide de mq. Ce n'est pas trop différent de mettre de côté à certains égards, mais se comporte différemment. Le résultat final est le même, les modifications sont supprimées et peuvent éventuellement être réappliquées ultérieurement. Lorsqu'ils sont poussés, les correctifs sont des ensembles de modifications logiques, lorsqu'ils sont sautés, ils sont enregistrés ailleurs et ne font pas partie de l'historique des ensembles de modifications.

    hg qnew "UnfinishedWork"
    hg qrefresh
    hg qpop
    
    hg qpush "UnfinishedWork"
    
  3. Engagez-les localement, mettez à jour le jeu de modifications précédent et continuez à travailler et utilisez des branches anonymes (ou plusieurs têtes). Si vous souhaitez ensuite les modifications, vous pouvez fusionner les têtes. Si vous ne souhaitez pas les modifications, vous pouvez supprimer l'ensemble de modifications.

    hg commit -m"Commiting unfinished work in-line."
    hg update -r<previous revision>
    
    hg strip -r<revision of temporary commit>
    
  4. Confiez-les à une branche nommée. Le flux de travail devient alors le même que l'option 3 - fusionner ou supprimer lorsque vous êtes prêt.

    hg branch "NewBranch"
    hg commit -m"Commiting unfinished work to temporary named branch."
    hg update <previous branch name>
    

Personnellement, j'utilise l'option 3 ou 4 car cela ne me dérange pas de supprimer les ensembles de modifications ou d'enregistrer un code partiel (à condition que cela ne soit finalement pas poussé). Cela peut être utilisé en conjonction avec la nouvelle phase éléments de pour masquer vos ensembles de modifications locaux aux autres utilisateurs si nécessaire.

J'utilise également la rebasecommande pour déplacer les ensembles de modifications afin d'éviter les fusions où une fusion n'ajouterait rien à l'historique du code. Fusion J'ai tendance à économiser pour l'activité entre les branches importantes (telles que les branches de publication) ou l'activité d'une branche de fonctionnalités plus longue. Il y a aussi la histeditcommande que j'utilise pour compresser les ensembles de modifications où le "bavardage" de ceux-ci réduit la valeur.

Les files d'attente de correctifs sont également un mécanisme courant pour ce faire, mais elles ont une sémantique de pile. Vous poussez et pop des patchs, mais un patch qui est "sous" un autre patch dans la pile nécessite que celui qui se trouve dessus soit également poussé.

Attention , comme avec toutes ces options, si les fichiers ont plus de changements depuis les changements temporaires que vous avez mis en attente / mis en file d'attente / ramifiés, il y aura une résolution de fusion requise lors du retrait / du transfert / de la fusion.

Adam Houldsworth
la source
Merci pour la bonne réponse et les exemples utiles. Savez-vous si l'utilisation de signets hg est également une option?
Erik
@Erik Possiblement, mais je n'ai aucune expérience de son utilisation.
Adam Houldsworth
2
les signets peuvent être utilisés pour vous aider avec l'option 3 - vous pouvez en utiliser un pour étiqueter la révision que vous avez créée pour cacher votre modification. Ils ne peuvent pas faire la tâche seuls.
Steve Kaye
l'option --alln'est pas reconnue. c'est un comportement par défaut pour mettre de toute façon tous les changements en suspens.
naXa
@naXa Bonjour mon pote, si l'une de mes commandes est légèrement incorrecte (peut-être parce que la version a changé), n'hésitez pas à modifier la réponse et je l'approuverai si nécessaire :-)
Adam Houldsworth
23

Personnellement, je n'aime aucune des réponses publiées jusqu'à présent:

  1. Je n'aime pas le branchement de clones parce que j'aime que chaque projet n'ait qu'un seul répertoire. Travailler sur différents répertoires en même temps gâche complètement l'historique des fichiers récents de mes éditeurs. Je finis toujours par changer le mauvais fichier. Alors je ne fais plus ça.
  2. J'utilise shelvepour des correctifs rapides (juste pour déplacer mes modifications non validées vers une autre branche, si je me rends compte que je suis dans la mauvaise). Vous parlez de jours, pas question de mettre quelque chose de côté pendant des jours.
  3. Je pense que mqc'est trop compliqué pour une situation aussi ordinaire

Je pense que le meilleur moyen est simplement de valider vos modifications, puis de revenir à l'ensemble de modifications avant de commencer ces modifications et de travailler à partir de là. Il y a quelques problèmes mineurs, permettez-moi d'illustrer:

Supposons que vous ayez l'ensemble de modifications A. Ensuite, vous commencez vos modifications. À ce stade, vous voulez le mettre de côté pendant un certain temps. Tout d'abord, engagez votre travail:

hg ci -m "Working on new stuff"

Si vous le souhaitez, vous pouvez ajouter un signet pour vous permettre de revenir plus tard. Je crée toujours des signets vers mes succursales anonymes.

hg bookmark new-stuff

Revenir au changeset avant ces modifications

hg update A

À partir de là, vous travaillez et générez le changeset C. Maintenant que vous avez 2 têtes (B et C), vous serez averti lorsque vous essayez de pousser. Vous ne pouvez pousser qu'une seule branche en spécifiant la tête de cette branche:

hg push -r C

Ou vous pouvez changer la phase de la new-stuffbranche en secret. Les modifications secrètes ne seront pas transmises.

hg phase -r new-stuff --secret --force
Rafael Piccolo
la source
Merci pour la réponse détaillée! J'aime vraiment lire les flux de travail des gens pour ces problèmes (ordinaires?).
Erik
Je pense que mqc'est un peu trop compliqué pour que cette situation, mais il a une assez large gamme d'utilisations, y compris celui - ci, qu'il vaut la peine d'investir le temps de parler couramment avec elle.
Norman Gray
12

Pour conserver les modifications locales non validées, le moyen le plus simple pour moi est de les enregistrer sous forme de fichier de correctif.

hg diff > /tmp/`hg id -i`.patch

et lorsque vous devez revenir à l'état précédent:

hg up <REV_WHERE_SAVED>
hg patch --no-commit /tmp/<REV_WHERE_SAVED>.patch
mapcuk
la source
Je déshabille /tmpet hg id -iil travaillerai sur Windoze aussi.
anatoly techtonik
Et hg upn'est pas nécessaire là-bas.
anatoly techtonik
1
@techtonik Que se passerait-il si j'applique le patch sur une autre révision? Surtout si les fichiers patchés sont modifiés.
mapcuk
Mercurial essaiera de le fusionner, et vous devrez de toute façon faire face à un conflit.
anatoly techtonik
6

Vous pouvez simplement cloner votre repo plusieurs fois. J'ai tendance à avoir un clone racine, puis plusieurs enfants à partir de là. Exemple:

  • MyProject.Root
  • MyProject.BugFix1
  • MyProject.BugFix2
  • MyProject.FeatureChange1
  • MyProject.FeatureChange2

Les 4 fils sont tous clonés à partir de la racine et push / pull de / vers la racine. La racine pousse / tire ensuite du repo principal sur le réseau / Internet quelque part. La racine agit comme votre sorte de zone de rassemblement personnelle.

Donc, dans votre cas, vous venez de cloner un nouveau dépôt et de commencer à travailler. Laissez votre travail «mis en attente» seul dans l'autre repo. C'est si simple.

Le seul inconvénient est l'utilisation de l'espace disque, mais si c'était un problème, vous n'utiliseriez pas du tout DVCS;) Oh et cela pollue en quelque sorte votre liste de "projets récents" de Visual Studio, mais qu'est-ce que c'est.

[Modifier les commentaires suivants]: -

Pour conclure alors ... ce que vous faites est parfaitement normal et normal. Je dirais que c'est la meilleure façon de travailler lorsque ce qui suit est vrai: 1) c'est de courte durée 2) vous n'avez pas besoin de collaborer avec d'autres développeurs 3) les changements n'ont pas besoin de quitter votre PC jusqu'à la validation / pousser le temps.

nbevans
la source
Une raison pour ne pas utiliser de succursales? C'est à cela qu'ils servent et ils sont considérablement plus rapides que le repo-clonage.
Adam Houldsworth
Dans ma question, j'ai déclaré ce qui suit: Ma méthode habituelle était de créer une nouvelle branche en utilisant le clone, mais il pourrait y avoir de meilleures façons.
Erik
1
@AdamHouldsworth, techniquement, ce sont des branches ... juste de courte durée. Faire une branche nommée pour un travail de courte durée est complètement stupide. Il abuse du but nommé branches qui sont pour des histoires de travail de longue durée.
nbevans
@NathanE Si vous pensez que les branches nommées pour un travail de courte durée sont "complètement stupides", alors il y a aussi le branchement anonyme, le rayonnage ou la file d'attente de correctifs comme autres options légères. Le re-clonage, à mon avis, est tout aussi stupide face aux autres options - c'est un avantage potentiel d'avoir deux ensembles de code ouverts dans deux instances VS, mais je dois rarement le faire, donc utiliser des clones comme une évidence ne le fait pas ne me sers pas. Juste pour clarifier, je n'étais pas le downvoter.
Adam Houldsworth
@NathanE Ils ne sont pas non plus exclusifs pour les «histoires de travail à long terme», c'est juste quelque chose dans lequel ils sont bons si vous suivez l'intégration continue. Directement à partir de la documentation : "Les branches se produisent si les lignes de développement divergent", si vous mettez un travail sur une table pour travailler sur autre chose, cela me semble être une divergence, quelle que soit sa durée.
Adam Houldsworth