他の作業をしているときに、コミットされていない一連の変更を脇に置く方法


98

コミットされていない変更がたくさんあり、何か他の作業をしているときにそれを脇に置きたい場合は、後で(数日後にfi)戻って作業を続行します。これを達成する最も簡単なワークフローは何でしょうか?(これまでのところ、Mercurialの基本的な機能の経験しかありません)。私の通常の方法は、クローンを使用して新しいブランチを作成することでしたが、もっと良い方法があるかもしれません。

回答:


133

いくつかのオプションがあります。

  1. アイテムを棚に置きます。これにより変更が保存され、作業ディレクトリから削除されるため、ブランチを続行できます。変更セットは作成されません。

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

    更新/編集:mercurialの新しいバージョンを使用する必要がある場合があります

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

    --name代わりとして使用できますが-n、Mercurialは--nameもう好きではないようです。さらに、これ--allはもはや必要ではなく、Mercurialは実際にそれを狂わせます。

  2. を使用してアイテムにパッチをキューしますmq。これは、いくつかの点でシェルフにあまり似ていませんが、動作が異なります。最終結果は同じで、変更は削除され、オプションで後で再適用できます。プッシュすると、パッチは論理的な変更セットになり、ポップすると他の場所に保存され、変更セットの履歴の一部にはなりません。

    hg qnew "UnfinishedWork"
    hg qrefresh
    hg qpop
    
    hg qpush "UnfinishedWork"
    
  3. それらをローカルにコミットし、以前の変更セットに更新して作業を続け、匿名ブランチ(または複数のヘッド)を利用します。その後、変更が必要な場合は、ヘッドをマージできます。変更が必要ない場合は、変更セットを削除できます。

    hg commit -m"Commiting unfinished work in-line."
    hg update -r<previous revision>
    
    hg strip -r<revision of temporary commit>
    
  4. 名前付きブランチにコミットします。ワークフローはオプション3と同じになります-準備ができたらマージまたはストリップします。

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

個人的には、変更セットの削除や部分的なコードのチェックイン(それが最終的にプッシュされない限り)を気にしないため、オプション3または4を使用します。これは、必要に応じて、ローカルの変更セットを他のユーザーから隠すために、新しいフェーズのものと組み合わせて使用​​できます。

また、rebaseコマンドを使用して変更セットを移動し、マージによってコードの履歴に何も追加されないマージを回避します。マージ私は、重要なブランチ(リリースブランチなど)間のアクティビティ、またはより長寿命の機能ブランチからのアクティビティを保存する傾向があります。histedit変更セットを圧縮するために使用するコマンドもあり、変更セットの「雑感」によって値が減少します。

パッチキューもこれを行うための一般的なメカニズムですが、スタックのセマンティクスがあります。パッチをプッシュしてポップしますが、スタック内の別のパッチの「下」にあるパッチは、その上のパッチもプッシュする必要があります。

警告、これらすべてのオプションと同様に、一時停止した変更/キュー/分岐以降にファイルにさらに変更がある場合、シェルビング解除/プッシュ/マージの際にマージ解決が必要になります。


すばらしい答えと役立つ例をありがとう。hgブックマークの使用もオプションかどうかを知っていますか?
エリック

@Erik多分、私はそれを使用した経験がありません。
アダムホールズワース2012

2
ブックマークを使用してオプション3を支援できます-ブックマークを使用して、変更を隠しておくために作成したリビジョンにラベルを付けることができます。彼らは自分で仕事をすることはできません。
スティーブケイ

オプション--allが認識されません。とにかくすべての変更を保留するのがデフォルトの動作です。
naXa 2018

@naXaこんにちは、私のコマンドの1つが少しミスしている場合(バージョンが変更された可能性があるため)、回答を自由に編集してください。必要に応じて承認します:-)
Adam Houldsworth

23

個人的には、これまでに投稿された答えは好きではありません。

  1. 各プロジェクトにはディレクトリが1つしかないので、クローンのブランチは好きではありません。同時に異なるディレクトリで作業すると、編集者の最近のファイルの履歴が完全に乱雑になります。私はいつも間違ったファイルを変更してしまいます。だから私はもうそれをしません。
  2. shelveはクイックフィックスに使用します(自分が間違っていることに気付いた場合、コミットされていない変更を別のブランチに移動するためだけです)。あなたは何日も話している、私が何日も何かを棚上げにすることは決してないだろう。
  3. こんなmq普通のシチュエーションには複雑すぎると思います

最善の方法は、変更をコミットすることです。変更を開始する前に変更セットに戻り、そこから作業するのではありません。いくつかのマイナーな問題があります。説明しましょう:

チェンジセットがあるとしましょうA.変更を開始するよりも。この時点で、しばらくそれを脇に置いておきます。まず、作業をコミットします。

hg ci -m "Working on new stuff"

必要に応じて、ブックマークを追加して後で簡単に戻ることができます。私はいつも匿名のブランチにブックマークを作成しています。

hg bookmark new-stuff

これらの変更の前に変更セットに戻ります

hg update A

ここから、チェンジセットCを操作して生成します。2つのヘッド(BとC)ができたので、プッシュしようとすると警告が表示されます。そのブランチのヘッドを指定することで、1つのブランチのみをプッシュできます。

hg push -r C

または、new-stuffブランチのフェーズをシークレットに変更できます。秘密のチェンジセットはプッシュされません。

hg phase -r new-stuff --secret --force

詳しい回答ありがとうございます!私は本当にこれらの(通常の)問題のワークフローを読むのが好きです。
エリック

これはこの状況だけmqは少し複雑すぎると思いますが、これを含めて十分に幅広い用途があるため、流暢になるために時間を費やす価値はあります。
ノーマングレイ、

12

ローカルでコミットされていない変更を保持するには、パッチファイルとして保存するのが最も簡単な方法です。

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

前の状態に戻る必要がある場合:

hg up <REV_WHERE_SAVED>
hg patch --no-commit /tmp/<REV_WHERE_SAVED>.patch

私はストリップ/tmpしてhg id -i、Windozeでも動作します。
anatly techtonik 2014

そしてhg upそこには必要ありません。
anatly techtonik 2014

1
@techtonik別のリビジョンにパッチを適用するとどうなりますか?特に、パッチが適用されたファイルが変更された場合。
mapcuk 2014

Mercurialはそれをマージしようとしますが、とにかく紛争に対処する必要があります。
anatly techtonik 2014

6

リポジトリを複数回複製するだけです。私はルートクローンを作成し、そこから複数の子を作成する傾向があります。例:

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

4つの子はすべてルートから複製され、ルートにプッシュ/プルされます。その後、ルートはネットワーク/インターネット上のどこかにあるマスターリポジトリからpush / pullします。ルートは、一種の個人的なステージング領域として機能します。

したがって、あなたの場合、新しいリポジトリを複製して作業を開始するだけです。他のレポであなたの「シェルフ」作業をそのままにしておきます。とても簡単です。

唯一の欠点はディスク容量の使用ですが、それが問題である場合は、とにかくDVCSをまったく使用しません;)ああ、それは一種のVisual Studioの「最近のプロジェクト」リストを汚染しますが、ちょっと。

[次のコメントを編集]:-

結論としては...あなたがやっていることは完全に正常で正常です。私はそれが次の条件に当てはまる場合に最良の方法であると主張します:1)短命である2)他の開発者と協力する必要がない3)変更はコミットするまでPCを離れる必要がない/プッシュ時間。


ブランチを使用しない理由はありますか?これが目的であり、レポクローニングよりもかなり高速です。
アダムホールズワース2012

私の質問で私は次のように述べました:私の通常の方法はクローンを使用して新しいブランチを作成することでしたが、もっと良い方法があるかもしれません。
エリック

1
@AdamHouldsworth、技術的にはこれらはブランチです...寿命の短いブランチです。短命の作品に対して名前付きブランチを作成することは完全に愚かです。それは、長命の仕事の物語であるブランチという名前の目的を乱用します。
nbevans

@NathanE存続期間の短い作業の名前付きブランチが「完全に愚か」であると思われる場合、他の軽量オプションとして匿名のブランチ、シェルビング、またはパッチキューもあります。私の意見では、再クローニングは他のオプションに直面しても同様に愚かです-1つの潜在的な利点は、2つのVSインスタンスで2セットのコードを開くことですが、これを行う必要はほとんどないので、当然のことながらクローンを使用しても私に仕えない。明確にするために、私は反対投票者ではありませんでした。
アダムホールズワース

@NathanE彼らはまた、「長命の仕事の物語」だけに限定されているわけではありません。ドキュメントから直接:「開発ラインが分岐すると分岐が発生します」、何かを作業するために作業項目を棚上げしている場合、これは、存続期間に関係なく分岐のように聞こえます。
アダムホールズワース
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.