Mercurialでコミットをスカッシュできますか?


109

私は実際には1つだけであるはずのコミットのペアを持っています。gitを使用している場合は、次のように使用します。

git rebase -i <some-commit-before>

そして、それらを押しつぶします。

水銀でできますか?もしそうなら、どうですか?

回答:


88

はい、変更セット連結することにより、拡張子なしのmercurialを使用してこれを行うことができます。

あるいは、拡張機能を使用したい場合は、次のように使用できます。


ええ、私は一般的な質問に対する私のコメントで私が好きな重複した質問からその答えを見つけました。それはあなたの答えだと思います。
Ry4an Brase 2009年

4
ちなみに、Histedit拡張機能はMercurial 2.3以降で配布されています。有効にする必要があります。
Paidhi、2015

1
連結変更セットのドキュメントでは、「リポジトリ」の抽象的な概念を使用していますが、それらを参照するにはどうすればよいですか?例:hg -R oldrepo export ...は "abort:repository oldrepo not found!
Aleksandr Levchuk

13
2つのコミットを潰そうとしているだけです。10以上のコマンドまたは代替の拡張機能が含まれたWikiページが本当に必要ですか?
Aleksandr Levchuk 2015

3
コメントを参照してください。Histeditが組み込まれました。有効にする必要があります(デフォルトのコマンドでは履歴が変更されないため)
Ry4an Brase

43

私のお気に入りはhg strip --keepコマンドです。そして、すべての変更を1つのコミットでコミットします。

毎日の作業中に小さなコミットをたくさんしたいので、これは私にとって最も速くて快適な方法です;)


注1:有効にstripするには組み込みの拡張機能が必要mqです。
注2:私のお気に入りのGit / Mercurialクライアント(SmartGit / Hg)は、デフォルトの--keepパラメータを中に追加しますstrip。そしてさらに便利なのは、join commits:] というオプションを提供することです。


4
hg stripの完全なコマンドは、次のとおりです。 最後のコミットとスカッシュしたい最初のコミットのリビジョン番号はhg strip --keep --rev [rev] どこですかrev
Nicolas Forney 14

3
@NicolasForney正確に--revは、オプションですが、完全なコマンドはhg strip --keep [rev]
G. Demecki

リビジョンは、3.3.3での私のために必須である:hg help strip与えhg strip [-k] [-f] [-n] [-B bookmark] [-r] REV...、およびリビジョンを省略することは、私を与えますabort: empty revision set
Roman Starkov

3
を使用することhg stripは最良のアイデアではありません。正確には安全ではありません。を試してみてくださいhg histedit。おそらく、evolve拡張機能を使用してみてください。
Martin Thomson、

gitの人々にとって最も自然な方法のようです;)
foo

32

リベースの拡張子は魅力のように働きました。2つのコミットをスカッシュするには:

$ hg rebase --dest .~2 --base . --collapse

ドットは現在のリビジョンのショートカットです。

ブランチにいくつかのコミットがあり、それらをすべて1つにまとめたい場合は、さらに簡単です。

$ hg rebase --dest {destination branch (e.g. master)} --base . --collapse

仕組み:

ここに画像の説明を入力してください

http://mercurial-scm.org/wiki/RebaseExtension#Collapsingから)


1
2つのコミットの「〜2」はどこで見つけましたか?
Mi-La

1
revsetsトピックで説明されています。hghelp revsetsを参照してください。
マルカンド、2016

13

この回答を読んでいる場合は、この回答で言及されている他のすべてのオプションを忘れてfoldevolve拡張機能のコマンドを使用できます。

evolve水銀の拡張であり、安全で変更可能な履歴を持つことができますが、まだ実験段階です。リポジトリからクローンを作成し、次のように.hgrcに追加することで使用できます。

[extensions]
evolve = ~/evolve/hgext/evolve.py

あなたがあなたのホームディレクトリにevolve repoをクローンしたと仮定します。これで準備完了です。ヘルプを探すこともできますhg help fold

フォールドコマンド

あなたfoldは壊れていないコミットの線形チェーンをスカッシュ/フォールドするように言います。foldが行うことは、すべてのチェンジセットからの変更を含む新しいチェンジセットを作成し、それらのコミットをすべて廃止としてマークすることです。あなたはdocsでこれについてより深い見解を持つことができます。

次の履歴があるとします。

a -> b -> c -> d -> e -> f -> g

あなたはスカッシュにしたいefg。できるよ

hg up g
hg fold -r e

結果は

a -> b -> c -> d -> h

どこhすべての3つのコミットからの変更を含むチェンジがあるefg

履歴の途中からチェンジセットを折りたたむこともできます。つまり、必ずしもチップを含むチェーンを選択する必要はありません。あなたがフォールドしたいと仮定しbcそしてd。できるよ

hg up d
hg fold -r b
hg evolve --all

これは

a -> i -> j

どこiの折り返しチェンジでbcdj同じチェンジですhEvolveユーザーガイドは必読です。


rebaseはその拡張機能のほとんど(多分すべて?)のユースケースをカバーしているようで、確かにこの質問で尋ねられているものです。その拡張機能のキラー機能は、置き換えるリビジョンを(削除するのではなく)非表示にすることですが、--keepリベースのオプションはこれをカバーします(結果としてリビジョンをシークレットとしてマークするか、結果を確認したらストリップを削除します)。2つのrebaseコマンドのシーケンスを使用して、他のリビジョン間でリビジョンを移動することもできます。
Arthur Tacca 2017

...さらに、何か非常に複雑なことをしている場合は、常にローカルリポジトリのクローンを作成して、バックアップとして使用できます。それがどれほどまれに(うまくいけば!)考えられるかを考えると、まったく新しい拡張機能の使い方を学ぶよりも手間がかかりません。
Arthur Tacca 2017

「NameError:name 'execfile' is not defined」-これは、evolveが基本的に石器時代であるPython 2で書かれていることを意味します。
Neil G

1
@NeilG mercurialはまだPython 3をサポートしていません。
Pulkit Goyal

2
@NeilGうん、水銀コミュニティはpy3サポートをできるだけ早く得るために一生懸命働いています。
Pulkit Goyal

1

Mercurial 4.8(2018年11月、9年後)では、新しいコマンドを検討できますhg absorb(これは以前試験的な機能でした)。

「を参照してください。Mercurialの4.8での変更点をコミット吸収

吸収拡張は、作業ディレクトリの各変更を取得し、シリーズのどのコミットがその行を変更したかを把握し、そのコミットの変更を自動的に修正します。
あいまいな場合(つまり、複数のコミットが同じ行を変更した場合)、吸収はその変更を無視し、作業ディレクトリに残して手動で解決します。

技術レベルでhg absorbは、コミットされていないすべての変更を検出し、変更された各行を明確な以前のコミットにマップしようとします。
きれいにマッピングできるすべての変更について、コミットされていない変更は、適切な以前のコミットに吸収されます。操作の影響を受けるコミットは自動的にリベースされます。
変更を明確な以前のコミットにマッピングできない場合、変更はコミットされずに残り、ユーザーは既存のワークフローにフォールバックできます(例:を使用hg histedit)。

の自動書き換えロジックはhg absorb、行の履歴をたどることによって実装されます。これは、hg histeditor によるアプローチとは根本的に異なりgit rebase3ウェイマージに基づくマージ戦略に依存して、複数の入力が指定されたファイルの新しいバージョンを導出する傾向があります。バージョン。

このアプローチとあいまいなアプリケーションコミットでhg吸収が変更をスキップするという事実を組み合わせると、hg吸収がマージの競合に遭遇することはありません!

ここで、あいまいなアプリケーションターゲットを含む行を無視すると、パッチは常に従来の3方向マージを使用してきれいに適用されます。このステートメントは論理的に正しいように聞こえます。しかしそれはそうではありません:hg absorbによって実行されたマージが失敗しhg histeditたりgit rebase -i失敗したりするときにマージの競合を回避できます。


0

chistedit(Mercurial 2.3以降に組み込まれている)はそれに最も近いrebase -i純粋なMercurial(chisteditインタラクティブバージョンのhistedit)だと思います。HISTEDITに一度foldのコマンドは、リベースのにマップsquashし、rollリベースのにコマンドマップfixup。詳細については、histedit docsを参照してください。

これは簡単な例です。次のものがあり、1e21c4b1のすべての変更を以前のリビジョンに移動し、以前のリビジョンのメッセージを保持したいとします。

@  1e21c4b1 drees tip
|  A commit you want to squash
o  b4a738a4 drees
|  A commit
o  788aa028 drees
|  Older stuff

実行するhg chistedit -r b4a738a4と、履歴を編集してb4a738a4に戻すことができます。chisteditでカーソルを下に移動して1e21c4b1に移動し、ヒットrしてそのリビジョンをロールすることを示します。histeditの順序(古いものから新しいものへ)がhg log(新しいものから古いものへ)逆になっていることに注意してください。

#0  pick   160:b4a738a49916   A commit
#1  ^roll  161:1e21c4b1500c

変更を選択した後、cそれらをコミットすることを選択します。結果は次のとおりです。

@ bfa4a3beドリーのヒント| コミットo 788aa028ドリー| 古いもの

それらに比較的慣れていない場合は、参照用にhisteditファイルにコマンドの説明が記載されているので、histedit選択するよりも良いでしょうchistedit。通常のテキスト編集(通常のリベースと同様)を使用してコマンドを設定するには、もう少し編集が必要です。

どちらかを使用するには、histeditまたは〜/ .hgrcの拡張機能にchistedit追加histeditする必要があります。

[extensions]
histedit =

歴史にchistedit最も近く、rebase -iどこでも機能するので、提案しました。あなたが本当に現在のリビジョンを以前のリビジョンに包含/微調整したい場合は、@ G。strip何が起こっているのかは明らかであるため、デメッキの提案は良いことです。Mercuria 2.8以降に組み込まれています。上記と同等の結果を得るには、次のようにします。

hg strip .
hg add
hg commit --amend

striphisteditと同様に、〜/ .hgrcで有効にする必要があることに注意してください。

[extensions]
strip =

0

最近の2つのコミットを押しつぶす(統合する)と仮定します。

  1. リビジョン番号を見つける

    hg log -G -l 3
    

    可能な出力:

    @  changeset:   156:a922d923cf6f
    |  branch:      default
    |  tag:         tip
    |  user:        naXa!
    |  date:        Thu Dec 13 15:45:58 2018 +0300
    |  summary:     commit message 3
    |
    o  changeset:   155:5feb73422486
    |  branch:      default
    |  user:        naXa!
    |  date:        Thu Dec 13 15:22:15 2018 +0300
    |  summary:     commit message 2
    |
    o  changeset:   154:2e490482bd75
    |  branch:      default
    ~  user:        naXa!
       date:        Thu Dec 13 03:28:27 2018 +0300
       summary:     commit message 1
    
  2. ソフトリセットブランチ

    hg strip --keep -r 155
    
  3. 変更を再度コミット

    hg commit -m "new commit message"
    

ノート

strip組み込みの拡張機能を有効にする必要があります。~/.hgrc次の内容の構成ファイルを作成/編集します。

[extensions]
strip = 

-1

私が使う:

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