web-dev-qa-db-ja.com

Mercurial:最後のコミットを修正する方法は?

Mercurialのgit commit --amendのカウンターパート、つまり、作業コピーがリンクされているコミットを変更する方法を探しています。私は、任意の以前のコミットではなく、最後のコミットにのみ興味があります。

この修正手順の要件は次のとおりです。

  • 可能であれば、拡張機能は必要ありません。 デフォルト以外の拡張機能は不要、つまり、公式のMercurialインストールに付属していない拡張機能である必要があります。

  • 修正するコミットが現在のブランチのヘッドの1つである場合、新しいヘッドなしを作成する必要があります。コミットがヘッドでない場合、新しいヘッドが作成される場合があります。

  • プロシージャはsafeである必要があります。何らかの理由で修正が失敗した場合、修正前と同じ作業コピーとリポジトリの状態を復元する必要があります。つまり、修正自体が失敗する可能性がある場合は、作業コピーとリポジトリの状態を復元するためのフェイルセーフ手順が必要です。ファイルシステム関連の問題(アクセス制限、書き込み用にファイルをロックできないなど)ではなく、修正手順の性質(競合など)にある「失敗」に言及しています... )

更新(1):

  • この手順は自動化可能である必要があるため、ユーザーの操作を必要とせずにGUIクライアントで実行できます。

更新(2):

  • 作業ディレクトリ内のファイルは変更しないでください(特定の変更されたファイルでファイルシステムがロックされている可能性があります)。これは特に、可能なアプローチでは、クリーンな作業ディレクトリを必要としないことを意味します。
204
mstrap

Mercurial 2.2 のリリースでは、--amendオプションとhg commitを使用して、現在の作業ディレクトリで最後のコミットを更新できます。

コマンドラインリファレンス から:

--amendフラグを使用して、現在のhgステータスによって報告された変更(存在する場合)に加えて、親の変更を含む新しいコミットで作業ディレクトリの親を変更できます。古いコミットは、.hg/strip-backupのバックアップバンドルに保存されます(復元方法については、hg help bundleおよびhg help unbundleを参照してください)。

メッセージ、ユーザー、および日付は、指定されない限り、修正されたコミットから取得されます。コマンドラインでメッセージが指定されていない場合、修正されたコミットのメッセージを使用してエディターが開きます。

すばらしいのは、このメカニズムが「安全」であることです。これは、ローカルリポジトリの外部で既に利用可能になっている履歴を変更する更新を防ぐために比較的新しい「フェーズ」機能に依存しているためです。

281
Chris Phillips

Mercurialでコミットを編集するには、3つのオプションがあります。

  1. hg strip --keep --rev -1は最後の(1)コミットを取り消しますので、再度実行できます(詳細については この回答 を参照してください)。

  2. MQ拡張 を使用します。これはMercurialに同梱されています

  3. Mercurialに同梱されていなくても、 Histedit 拡張は言及する価値があります

Mercurial wikiの 編集履歴 ページもご覧ください。

要するに、編集履歴は本当に難しく、discouragedです。また、既に変更をプッシュしている場合、他のすべてのクローンを完全に制御できる場合を除いて、できることはほとんどありません。

git commit --amendコマンドについてはあまり詳しくありませんが、私の知る限り、Histeditは最も近いアプローチのようですが、残念ながらMercurialには同梱されていません。 MQの使用は本当に複雑ですが、ほとんど何でもできます。

51
krtek

hg commit --amendに相当するGUI:

これはTortoiseHGのGUIでも動作します(v2.5を使用しています)。

「コミット」ビューに移動するか、ワークベンチビューで「作業ディレクトリ」エントリを選択します。 [コミット]ボタンには、[現在のリビジョンを修正]という名前のオプションがあります(ボタンのドロップダウン矢印をクリックして見つけます)。

enter image description here

          ||
          ||
          \/

enter image description here

注意事項

この追加オプションは、Mercurialバージョンが少なくとも2.2.0であり、現在のリビジョンがパブリックでない場合、パッチではなく、子がない場合にのみ有効になります。 [...]

ボタンをクリックすると、「commit --amend」が呼び出され、リビジョンが「修正」されます。

これに関する詳細情報 THG devチャネル上

38

変更をまだ伝播していないと仮定すると、次のことができます。

  • .hgrcに追加します。

    [extensions]
    mq =
    
  • リポジトリ内:

    hg qimport -r0:tip
    hg qpop -a
    

    もちろん、リビジョン0で開始したり、すべてのパッチをポップしたりする必要はありません。最後の1つのポップ(hg qpop)で十分です(以下を参照)。

  • .hg/patches/seriesファイルの最後のエントリ、または気に入らないパッチを削除します。並べ替えも可能です。

  • hg qpush -a; hg qfinish -a
  • まだ.hg/patchesにある.diffファイル(未適用のパッチ)を削除します(この場合は1つである必要があります)。

パッチの必要ではないからすべてを取り戻すの場合は、hg qimport -r0:tip(または同様の)を使用して編集し、内容を編集してhg qrefreshを使用して変更をマージできますスタックの一番上のパッチに。 hg help qrefreshをお読みください。

.hg/patches/seriesを編集することにより、複数のパッチを削除したり、いくつかのパッチを並べ替えたりすることもできます。最後のリビジョンが99の場合、hg qimport -r98:tip; hg qpop; [edit series file]; hg qpush -a; hg qfinish -aを使用できます。

もちろん、この手順非常にがっかりして危険ですバックアップを作成するこれを行う前にすべてのものを!

補足として、私はプライベート専用リポジトリーで何十回もそれを行ってきました。

7
hochl

私はkrtekが書いたことにチューニングしています。より具体的な解決策1:

仮定:

  • 1つの(!)チェンジセットをコミットしたが、まだプッシュしていない
  • この変更セットを変更する(たとえば、ファイルやコミットメッセージを追加、削除、変更する)

解決策:

  • hg rollbackを使用して最後のコミットを取り消す
  • 新しい変更を適所に入れて再度コミットする

ロールバックは最後の操作を実際に取り消します。その動作方法は非常に簡単です。HGの通常の操作はファイルにのみ追加されます。これにはコミットが含まれます。 Mercurialは最後のトランザクションのファイル長を追跡するため、ファイルを元の長さに切り戻すことにより、1つのステップを完全に取り消すことができます。

7
Lucero

Mercurialの最近のバージョンには、hg amendコマンドを提供するevolve拡張が含まれています。これにより、バージョン管理の修正前の履歴を失うことなくコミットを修正できます。

hg amend [オプション] ... [ファイル] ...

エイリアス:更新

チェンジセットとアップデートを組み合わせて、新しいものに置き換えます

Commits a new changeset incorporating both the changes to the given files
and all the changes from the current parent changeset into the repository.

See 'hg commit' for details about committing changes.

If you don't specify -m, the parent's message will be reused.

Behind the scenes, Mercurial first commits the update as a regular child
of the current parent. Then it creates a new commit on the parent's
parents with the updated contents. Then it changes the working copy parent
to this new combined changeset. Finally, the old changeset and its update
are hidden from 'hg log' (unless you use --hidden with log).

evolveの詳細な説明については、 https://www.Mercurial-scm.org/doc/evolution/user-guide.html#example-3-amend-a-changeset-with-evolve を参照してください拡張。

1
Karl Bartel

元の質問のすべての問題を解決できるわけではありませんが、これはMercurialが以前のコミットを修正する方法に関する事実上の投稿であると思われるため、2セント分の情報を追加します。

あなたが私のような人で、ファイルを追加せずに前のコミットメッセージを修正する(タイプミスなどを修正する)だけであれば、これは機能します。

hg commit -X 'glob:**' --amend

包含または除外パターンがない場合、hg commitはデフォルトで作業ディレクトリ内のすべてのファイルを含めます。パターン-X 'glob:**'を適用すると、考えられるすべてのファイルが除外され、コミットメッセージの変更のみが許可されます。

機能的には、インデックス/ステージにファイルがない場合はgit commit --amendと同じです。

0
kaskelotti