web-dev-qa-db-ja.com

Mercurialの単一ファイルの履歴を削除する方法はありますか?

私はすでにこれに対する答えを知っていると思いますが、とにかく尋ねると思いました:

Mercurialリポジトリに機密情報が含まれているファイルが追加されました。リポジトリ全体を削除せずに、そのファイルとその変更履歴を削除する方法はありますか?

47
Matt Spradley

いいえ、できません。それについてのMercurialレッドブックの決してあるべきではなかった変更セクションを読んでください。特にエスケープする機密性の高い変更についてはどうですかサブセクションには、次の段落が含まれています。

Mercurialは、ファイルまたはチェンジセットを履歴から完全に消去する方法も提供していません。これは、その消去を強制する方法がないためです。誰かがMercurialのコピーを簡単に変更して、そのようなディレクティブを無視することができます。さらに、Mercurialがそのような機能を提供したとしても、単に「このファイルを非表示にする」チェンジセットをプルしなかった人は、その影響を受けず、Webクローラーが間違った時間にアクセスしたり、ディスクのバックアップやその他のメカニズムを利用したりすることもありません。 。実際、分散型リビジョン管理システムでは、データを確実に消滅させることはできません。そのような制御の錯覚を提供することは、簡単に誤った安心感を与える可能性があり、まったく提供しないよりも悪いことです。

コミットされた変更を元に戻す通常の方法は、backoutコマンドを介してMercurialによってサポートされています(ここでも、Mercurialの本: コミットされた変更の処理 )ただし、情報はリポジトリから消えません。リポジトリを正確に複製したのは誰かわからないため、上記で説明したように、誤った安心感が得られます。

22
Nicolas Dumazet

Mercurialから特定のファイルを簡単に削除できないのは正しいことです。そうすると、リポジトリ内のすべてのチェンジセットIDが中断されます。チェンジセットIDを変更すると、全員がリポジトリのクローンを再作成する必要があります。 Mercurialで履歴を変更した場合の結果については、 履歴の編集に関するWikiページ を参照してください。

それで問題がない場合(会社の内部リポジトリ)、 拡張子の変換 を見てください。 hg→hg変換を実行でき、-filemap引数がありますこれは、とりわけ、ファイルを除外するために使用できます。

58
Martin Geisler

ローカルでは可能ですが、グローバルでは不可能であり、ファイルが追加された時点以降、各コミットのIDが変更されます。変更を維持するには、リポジトリのすべてのコピー、特にプルまたはプッシュされたものにアクセスする必要があります。

そうは言っても、Mercurial wikiで説明されている Editing History シーケンスに従って、リポジトリの1つからファイルを削除しました。このシーケンスは、リビジョン1301:5200a5a10d8bがファイルpath/to/badfile.cfgを追加したことを前提としています。このファイルは、後続のリビジョンでは変更されていません。

  1. .hgrcでMQ拡張機能を有効にします。

    [extensions]
    mq =
    
  2. 最近の変更をアップストリームからプルします。

    hg pull
    
  3. ファイルの追加以降、すべてをMQにインポートします。

    hg qimport -r 1301:tip
    hg qpop -a
    
  4. ファイルを追加したコミットからファイルを削除します。

    hg qpush 1301.diff
    hg forget path/to/badfile.cfg
    hg qrefresh
    
  5. パッチを新しいMercurialリビジョンに変換します。

    hg qpush -a
    hg qfinish -a
    
  6. 新しいリビジョンをアップストリームにプッシュします。

    hg Push -f
    
  7. アップストリームリポジトリおよび他のすべてのコピーで、古いリビジョンを削除します。

    hg strip 5200a5a10d8b
    

警告:注意しない限り、この手順により作業が破壊される可能性があります。前回アップストリームからプルしたときから誰かが何かをコミットした場合は、ストリッピングする前にその作業をリベースする必要があります。残念ながら、ここではrebase拡張子は役に立ちません。 MQを再度使用して、新しいコミットを新しいヒントに適用するパッチに変換する必要があります。

幸運を。

7
eswald

それは10分以内に行うことができます。結果はありますが、単一のリポジトリにあります。

方法: この優れたガイド で説明されているようにhgconvertを使用します。基本的に、Hgリポジトリを新しいHgリポジトリに「変換」しますが、変換中に除外するファイルのリストを指定することができます。これは重要なステップの抜粋です。

Make sure all your teammates have pushed their local changes to the central repo (if any)
Backup your repository
Create a "map.txt" file:

# this filemap is used to exclude specific files
exclude "subdir/filename1.ext"
exclude "subdir/filename2.ext"
exclude "subdir2"

Run this command:
hg convert --filemap map.txt c:/oldrepo c:/newrepo
NOTE: You have to use "forward-slash" in paths, even on windows.
Wait and be patient
Now you have a new repo at c:\newrepo but without the files

結果については...

  • 除外するファイルが追加された後のすべてのチェンジセットIDは異なります
  • 新しい「クリーンな」メインリポジトリは、既存のリポジトリの代わりに手動で配置する必要があります
  • すべてのチームメンバーは、メインリポジトリの新しいクローンを作成する必要があります
  • hgと統合するその他のサービスには、注意が必要な場合があります(たとえば、問題トラッカー、コードレビューシステムなど)。