572

リポジトリにコミットしたくないファイルにローカルな変更があります。サーバー上でアプリケーションを構築するための構成ファイルですが、異なる設定でローカルに構築したいと思います。当然、ステージングするものとして「git status」を実行すると、ファイルは常に表示されます。この特定の変更を非表示にし、コミットしないようにします。ファイルに他の変更を加えることはありません。

明確にするために、.gitignoreを使用することは、新しいファイルが追加されるのを防ぐだけなので、私が望んでいることではありません。すでにリポジトリにあるファイルへの変更を無視したい。

少し掘り下げてみると、2つのオプションがあります:assume-unchangedskip-worktreeここでの前の質問はそれらについて話しますが、実際にはそれらの違いを説明していません。

2つのコマンドはどのように異なりますか?なぜ誰かがどちらかを使用するのでしょうか?

4

2 に答える 2

824

あなたが欲しいskip-worktree

assume-unchangedファイルのグループが変更されているかどうかを確認するのに費用がかかる場合のために設計されています。ビットを設定すると、git(もちろん)インデックスのその部分に対応するファイルが作業コピーで変更されていないことを前提としています。したがって、stat呼び出しの混乱を回避します。このビットは、インデックス内のファイルのエントリが変更されるたびに失われます(つまり、ファイルがアップストリームで変更されると)。

skip-worktreeそれだけではありません。ファイルが変更されている(またはなどで変更する必要がある)ことがgit わかっている場合でも、reset --hard代わりにインデックスのバージョンを使用して、変更されていないふりをします。これは、インデックスが破棄されるまで続きます。

この違いの影響と典型的なユースケースの良い要約がここにあります:http://fallengamer.livejournal.com/93321.html

その記事から:

  • --assume-unchanged開発者がファイルを変更してはならないことを前提としています。このフラグは、SDKのような変更されないフォルダーのパフォーマンスを向上させることを目的としています。
  • --skip-worktree開発者が特定のファイルを変更する必要があるため、特定のファイルに触れないようにgitに指示する場合に便利です。たとえば、メインリポジトリのアップストリームが本番環境に対応した構成ファイルをホストしていて、それらのファイルへの変更を誤ってコミットしたくない場合--skip-worktreeは、まさに必要なものです。
于 2012-11-29T17:39:42.173 に答える
135

注:fallengamerは2011年にいくつかのテストを行いました(したがって、それらは古くなっている可能性があります)。ここに彼の調査結果があります:

オペレーション

  • ファイルはローカルリポジトリとアップストリームの両方で変更されます
    git pull
    Gitはとにかくローカルの変更を保持します。
    したがって、フラグでマークしたデータを誤って失うことはありません。
    • フラグ付きのファイルassume-unchanged:Gitはローカルファイルを上書きしません。代わりに、競合を出力し、それらを解決する方法をアドバイスします
    • フラグ付きのファイルskip-worktree:Gitはローカルファイルを上書きしません。代わりに、競合を出力し、それらを解決する方法をアドバイスします

  • ファイルはローカルリポジトリとアップストリームの両方で変更され、とにかくプルしようとします。結果を 使用すると余分な手作業が発生しますが、少なくともローカルで変更があった場合でもデータが失われることはありません。
    git stash
    git pull
    skip-worktree
    • フラグ付きのファイルassume-unchanged:ローカルの変更をすべて破棄し、復元することはできません。効果は「<code>gitreset--hard」のようなものです。'<code>gitpull'呼び出しは成功します
    • フラグ付きのファイルskip-worktree:Stashはファイルでは機能しませんskip-worktree。'<code> git pull'は、上記と同じエラーで失敗します。開発者はskip-worktree、失敗を隠して完了することができるように、フラグを手動でリセットする必要がありpullます。

  • ローカル変更なし、アップストリームファイル変更 両方のフラグは、アップストリーム変更の取得を妨げることはありません。Gitは、あなたが約束を破ったことを検出し、フラグをリセットすることで現実を反映することを選択します。
    git pull
    assume-unchanged
    • フラグ付きのファイルassume-unchanged:コンテンツが更新され、フラグが失われます。
      '<code> git ls-files -v'は、フラグがH(からh)に変更されたことを示します。
    • フラグ付きのファイルskip-worktree:コンテンツが更新され、フラグが保持されます。
      '<code> git ls-files -v'はS、前と同じフラグを表示しpullます。

  • ローカルファイルが変更されると、 Gitはファイルに触れず、ファイルの現実(変更されないと約束されたファイルが実際に変更された)を反映します。
    git reset --hard
    skip-worktreeassume-unchanged
    • フラグ付きassume-unchangedのファイル:ファイルの内容が元に戻されます。フラグはH(からh)にリセットされます。
    • フラグ付きskip-worktreeのファイル:ファイルの内容はそのままです。フラグは同じままです。

彼は次の分析を追加します。

  • ローカルデータを保存するために非常に懸命に努力しているようskip-worktreeです。ただし、安全であれば、アップストリームの変更を取得することを妨げることはありません。さらに、gitはのフラグをリセットしません。ただし、「<code> reset --hard」コマンドを無視すると、開発者にとって厄介な驚きになる可能性があります。pull

  • Assume-unchanged操作中にフラグが失われる可能性がpullあり、そのようなファイル内のローカルの変更はgitにとって重要ではないようです。

見る:

彼は次のように結論づけています。

実際には、どちらのフラグも十分に直感的ではありません

  • assume-unchanged開発者がファイルを変更してはならないことを前提としています。ファイルが変更された場合、その変更は重要ではありません。このフラグは、SDKのような変更されないフォルダーのパフォーマンスを向上させることを目的としています。
    しかし、約束が破られ、ファイルが実際に変更された場合、gitは現実を反映するためにフラグを元に戻します。おそらく、一般的に変更されることのないフォルダに一貫性のないフラグが含まれていても問題ありません。

  • 一方skip-worktree、特定のファイルに触れないようにgitに指示する場合に便利です。これは、すでに追跡されている構成ファイルに役立ちます。
    アップストリームのメインリポジトリは、本番環境に対応した構成をホストしますが、構成のいくつかの設定を変更して、ローカルテストを実行できるようにします。また、このようなファイルの変更を誤ってチェックして、本番構成に影響を与えたくない場合もあります。その場合skip-worktreeは完璧なシーンになります。


Git 2.25.1(2020年2月)では、上記の「実際にはどちらのフラグも直感的ではありません」がさらに明確になります。

ブライアンmによるコミット7a2dc95コミット1b13e90(2020年1月22日)を参照してください。カールソン(bk2204( Junio C Hamano
によってマージされました---コミット53a8329、2020年1月30日)gitster
Gitメーリングリスト

doc:追跡されたファイルを無視しようとすることからユーザーを思いとどまらせる

サインオフバイ:ジェフキング
サインオフバイ:ブライアンm。カールソン

ユーザーがGitが追跡するファイルへの変更を無視したい場合は非常に一般的です。

この場合の一般的なシナリオは、IDE設定と構成ファイルです。これらは通常、追跡されるべきではなく、テンプレートメカニズムを使用して追跡されたファイルから生成される可能性があります。

ただし、ユーザーは、変更されていない仮定とスキップワークツリーのビットについて学び、とにかくこれを行うためにそれらを使用しようとします。

これらのビットが設定されると、多くの操作がユーザーの期待どおりに動作するため、これは問題がありますが、通常git checkout、ファイルを置き換える必要がある場合は役に立ちません。

この場合、特定の構成ファイルなどのデータが貴重な場合もあれば、ユーザーが喜んで破棄するのは無関係なデータである場合もあるため、適切な動作はありません。

これはサポートされている構成ではなく、ユーザーは既存の機能を意図しない目的で誤用する傾向があり、一般的な悲しみや混乱を引き起こしgit update-indexます。ユーザーが代替ソリューションを検討する必要があることをユーザーが理解できるように、既存の動作と落とし穴をドキュメントに記録しましょう。

さらに、多くの環境で正常に使用されるよく知られたアプローチがあるため、構成ファイルの一般的なケースに対処するための推奨ソリューションを提供しましょう。

git update-indexマニュアルページには次のものが含まれています。

ユーザーは、追跡されるファイルへの変更を無視するようにGitに指示するためにassume-unchangedandskip-worktreeビットを使用しようとすることがよくあります。Gitは特定の操作を実行するときに、インデックスに対して作業ツリーファイルをチェックする可能性があるため、これは期待どおりに機能しません。一般に、Gitは追跡されたファイルへの変更を無視する方法を提供しないため、代替ソリューションが推奨されます。

たとえば、変更するファイルがある種の構成ファイルである場合、リポジトリにサンプルの構成ファイルを含めることができます。このファイルは、無視された名前にコピーして変更できます。リポジトリには、サンプルファイルをテンプレートとして扱い、自動的に変更およびコピーするスクリプトを含めることもできます。

その最後の部分は、スマッジ/クリーンスクリプトに基づく典型的なコンテンツフィルタードライバーについて説明したものです。

于 2014-05-22T12:36:12.897 に答える