Mercurialでは、プッシュする前に一連のチェンジセットを1つに「圧縮」する方法を教えてください。


96

ローカルとリモートのMercurialリポジトリがあるとします。今、私は機能に取り組み始めます。私はそれに取り組み、それが完了したと思ったら、チェンジセットをコミットします。もう少しテストすると、コードを調整することでこの機能をさらに改善できることがわかりました。変更を加えてコミットします。20分後、この新機能にバグがあるので、修正してコミットします。

たとえば、リモートリポジトリにプッシュしたいチェンジセットが3つあります。たとえば、「Implementing feature X」というメッセージの付いた1つのチェンジセットとしてプッシュします。

手間をかけずにこれを行うにはどうすればよいですか?パッチでできると思いますが、大変な作業のようです。


40
明らかに、チェンジセットを圧縮しようとすることについて話し合うのは私の場所ではありませんが、バージョン管理の価値の半分が、「何故」何カ月も何年も後ではなく「なぜ」に答えていることを考慮した方がいいかもしれません。機能がどのようにして生まれ、どの段階で機能するかを正確に表現することは、将来的に価値があるかもしれません。それを捨てるのはそう思われる... unversioncontrolly。
Ry4an Brase 2009

これは別の質問につながります... 'histedit'と 'collapse'の違いは何ですか
sylvanaar

1
collapseはhisteditの機能のサブセットを提供し、histeditははるかに直感的なUXを備えています。
Stefan Rusek

1
また、マージされたチェンジセットメッセージを編集するメカニズムも提供します。
Stefan Rusek

1
@ Ry4an:実際には、押しつぶす/折りたたむとバージョン管理に関連性が追加される場合があります。スカッシュがなければ、機能やバグ修正とは何の関係もない2つのコミットが毎日発生しますが、ラップトップからデスクトップに、またはその逆にコードを移動するためのものです。バージョン履歴にノイズを追加するだけです。
ジョンレイノルズ

回答:


39

どの程度崩壊拡張


20
未来からのご挨拶!私は同じ機能をググっただけで、どうやら今日ではhgがでそのままこれをサポートしていますhg rebase --collapserebaseコマンドのhg wikiをチェックしてください。この質問は3番目の全体的な検索結果であり、stackoverflowの最初の質問なので、情報が役立つと思いました。
-a.peganz

1
これからもよろしくお願いします!! リベース拡張は、チェンジセットをあるブランチから別のブランチに移動することのみを目的としているようです。はい、--collapseオプションがありますが、ブランチ間で一連のチェンジセットを移動する場合にのみ適用できるようです。< mercurial-scm.org/wiki/… >を参照
Brad Oestreicher

3
あなたは使うことができhg rebase--collapse、単一の枝の中に。
UuDdLrLrSs

52

HISTEDITの拡張機能は、あなたが探しているものを正確にです。

hg histedit -o

または

hg histedit --outgoing

発信チェンジセットのリストが表示されます。リストからできること

  • 2つ以上のチェンジセットを折りたたんで、1つのチェンジセットを作成する
  • 変更セットをドロップして履歴から削除する
  • 変更セットを好きなように並べ替えます。

histeditは、折りたたまれた変更セットの新しいコミットメッセージを要求します。デフォルトでは、2つのメッセージに「\ n *** \ n」で区切られています。

mq拡張を使用しても同様の結果を得ることができますが、それははるかに困難です。

また、折りたたみ拡張機能を使用して折りたたみを実行することもできますが、UIがあまり良くなく、結果のコミットメッセージを編集する方法がありません。結果のコミットメッセージを編集すると、最終的にメッセージをクリーンアップすることもできます。これは、私がいつも利用するものです。


おかげで、まさにそれが必要でした。TortoiseHg内から実行できると便利ですが、コマンドラインは十分に単純です。
シルバナー09/10/13

21

はい、あなたはパッチでそれを行うことができます:あなたの作業が100から110までのチェンジセットにあるとしましょう

  1. パッチを作成します。

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

  2. 99に更新:

    % hg update 99

  3. --no-commitを使用してパッチを適用します(そうしないと、すべての変更セットが返されます):

    % hg import --no-commit mypatch

  4. すべての変更を一度にコミットします。

    % hg commit

  5. これで、2つのヘッド(110と111)が作成されました。これらは、作業ディレクトリに生成されるファイルに関して同等であるはずです。古いものを取り除く前に、正常性のためにそれらを比較できます。

    % hg strip 100

わかりました、すべてを綴ったので、長いように見えますが、自分で何度もやったので、あまり面倒ではないと思います...


1

バイナリファイルにも変更を含めるには、必ず--gitオプションを使用してください。例: "hg export -o mypatch 100:110 --git"詳細については、stackoverflow.com / a / 12537738 /を参照してください。367663 私は自由を取り、回答を修正しました。
ハルロスドミンゲス2014

1
複雑すぎるようですが、なぜhg strip --keep1つのコミットですべてをコミットしないのですか?
G.デメッキ2014年

@ G.Demeckiそれは潜在的に非常に損失の大きい操作だからです。MQはやりすぎです(そして、多くの場合は推奨されません)が、そのようなワークフローが必要な場合を除きます。
user2864740 2015年

@ user2864740私はMercurialのエキスパートではないので、あなたは正しいかもしれません。ただし、デフォルトでhg stripは、.hg/strip-backup/ディレクトリにバックアップが作成されます。それはそれほど安全ではないと思いgit reflogますが、それでも何らかの救済を提供します。
G. Demecki 2015年

19

TortoiseHgを使用している場合は、2つのリビジョンを選択し(CTRLを使用して後続のリビジョンを選択)、右クリックして[ 履歴の圧縮 ]を選択します。

その後、以前に選択した最初の変更から始まる新しい変更リストが新しいヘッドに表示され、選択したリストの間のすべての子孫変更リストが含まれます。

古い変更リストが不要になった場合は、単純に取り除くことができます。MQ拡張機能を使用してください。ここでも、TortoiseHgで、すべての子孫を削除する必要がある最初の変更リストを右クリックします。「Modify History-> Strip」


18

この折りたたみにmqを使用する私の好ましい方法は、ここで説明する TortoiseHg 使用することです。ただし、次のようにコマンドラインから簡単に実行できます。

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

(qfoldステップを実行するためのより良い方法があるかもしれませんが、私はその操作に通常TortoiseHgを使用するので、私はそれを知りません。)

最初は少し複雑に見えますが、mqの使用を開始すると、それは非常に簡単で自然なものになります。さらに、mqを使用すると、非常に便利なあらゆる種類のことを実行できます。


4

hg collapseそしてhg histedit最良の方法です。または、どちらかといえば、もしそれらが確実に機能するなら、最善の方法でしょう... histedit3分以内にスタックダンプでクラッシュしました。Collapseそれほど良くはありません。

他の2つのBKMを共有する可能性があると思いました。

  1. hg rebase --collapse

    この拡張機能はMercurialとともに配布されます。まだ問題はありません。hg rebase制限を回避するためにいくつかのゲームをプレイする必要があるかもしれません-基本的に、(名前付き)ブランチ間でリベースする場合は可能ですが、名前付きまたはデフォルトの同じブランチの祖先にリベースするのは好きではありません。

  2. リポジトリ(foo/.hg)を作業ディレクトリ(bar)とそのファイルに移動します。その逆ではありません。

一部の人々は、2つのクローンツリーを作成し、それらの間でファイルをコピーすることについて話しました。またはそれらの間のパッチ。代わりに、.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

これは、真のリポジトリである.hgツリーが作業ディレクトリとそのファイルから独立している限り機能します。

独立していない場合...


2015年にhisteditは、このタスクに最適なオプションです。私はまだgit rebase -iを実行しているので信頼していませんが、クラッシュはしません..何かがひどく間違っている場合、少なくとも新しいバージョンではtempブランチのままになり、チェンジセットが削除されるのはこのときだけです。新しいブランチがコミットされた後です。
user2864740 2015年

2

私はMercurialを使用したことがありませんが、これはマーティンファウラーが彼のブログであまり前に話していたこととよく似ています。

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


少し複雑に見えますが、リンクに感謝します。正直に言って、プルとチェリーピッキングのチャンセットを使ってフェッチと移植を行ったときのように、私が望むだけの魔法のような拡張を期待しています。
Lucas、

0

なぜただhg strip --keep命令しないのですか?

その後、すべての変更を1つのコミットとしてコミットできます。


@Strawberryは答えを提供しませんか?それは著者の質問に完全に答えると思います。ポイントを詳しく説明できますか?
G. Demecki 2015年

それは古代の歴史なので、私は発言を撤回しますが、承認された回答はより信頼できる参照のようです。
イチゴ

1
@Strawberry確かにそれは古代の糸です。しかし、Mercurialがこの仕事に別のサードパーティ拡張を必要としないため、受け入れられた回答は古くなっています。
G. Demecki 2015年

0

HistEditは必要なことを実行しますが、多分やり過ぎです。必要なのがいくつかのチェンジセットを一緒に折りたたむことだけの場合は、Collapse Extension機能します。


1
ただし、UIを使用して理解するのがはるかに簡単であり、これを使用する理由は十分以上ですが、マージされたチェンジセットメッセージを編集するメカニズムも提供します。変更セットをマージします。
Stefan Rusek

そして、UIを理解するだけの問題は、実際には理解できません。histeditは完璧です。どちらかと言えば、折りたたみ拡張機能は役に立たない。
user2864740 2015年

0

Mercurialに2つの未公開THISおよびTHATコミットがあり、それらが特定のTHIS時点で1つのコミットに参加することを好むとします。

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

コミットが公開されていないことを確認してください::

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

LASTコミットする更新::

$ hg up

コミットTHISをMQ:にインポートします。

$ hg qimport $THIS::.

すべてのパッチを適用解除し、最初にのみ適用するTHIS::

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

THAT::に参加

$ hg qfold $THATNAME

名前を見つけるには、次のTHATNAMEように使用します。

$ hg qseries

すべてのパッチを適用し、リポジトリ履歴に移動します::

$ hg qpush -a
$ hg qfinish -a

件名に関する私のブログ投稿は、Mercurialで2つのコミットに参加することです。


0

はい、strip --keep作者の質問に対しては機能します。しかし、たとえば1から30までのバージョンがあり、バージョン12〜15のみを折りたたみたい場合など、他のものとは少し異なりました。他のソリューションは機能しますが機能しませんstrip --keep

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.