どうすればgitにファイルの今後のリビジョンを無視させることができますか?


140

gitリポジトリに含まれるファイルのデフォルトバージョンを作成しました。誰かがリポジトリのクローンを作成するときに、このファイルのコピーを入手することが重要です。ただし、後でこのファイルへの変更を無視するようにgitを設定したいと思います。 .gitignore追跡されていないファイルでのみ機能します。

私の動機は、このファイルにマシン固有の情報が含まれていることです。私はデフォルト値を提供する一方で、元のリポジトリにプッシュバックされないローカル変更をユーザーが行えるようにし、新しい変更をプルするときにマージの競合を作成します。

私たちは一般的にかなり怠惰でgit add .たくさん使用しているので、このファイルを無視するようにgitに指示できない場合、私はかなり確信しています。

要約する、

  1. 私はファイルを作成し、それdefault_values.txtを私のgitリポジトリに追加され、誰かがそのリポジトリのクローンを作成するときに含まれるファイルと呼びます。
  2. git add .default_values.txtコミットに追加しないでください。
  3. この動作は、リポジトリのクローンに渡される必要があります。

1
gitフックを使用して、変更されたファイルがdefault_values.txt(たとえば)の場合にコミットを中止するpre-commitフックを使用できますか?
sateesh 2010

1
Gitの純粋主義者は、怠惰ではなく、ステージングエリアを正しく使用する、と言っています。
Xint0

Gitの純粋主義者は、スマッジ/クリーンスクリプトを使用すると言います。これは、最も保守しやすいソリューションです。
Adam Dymitruk、2011年

1
Xint0:true。しかし、他の人が誤ってチェックインしないようにするにはどうすればよいですか?
2014年

回答:


115

他の多くの人が述べたように、優れた最新のソリューションは次のとおりです。

git update-index --skip-worktree default_values.txt

ローカルとアップストリームの両方のファイルへの変更は、次のように再度許可するまで無視されます。

git update-index --no-skip-worktree default_values.txt

スキップとマークされたファイルのリストを取得できます:

git ls-files -v . | grep ^S

とは異なり--skip-worktree--assume-unchanged上流の変更がプルされると、ステータスが失われることに注意してください。


2
他の誰かがリポジトリをプルしてファイルを編集した場合、そのディレクトリの変更は無視されますか?--no-skip-worktree変更を追加するために入力する必要があると思います。
neaumusic

3
彼らの変更で行われることは彼らによって制御されます。つまり、変更をプッシュしたくない場合は、リポジトリのファイルにskip-worktreeを設定する必要があります。それが全員に送信され、その後のすべての変更を無視することを意図したファイルである場合、全員が同じ手順に従う必要があります。
moodboom 2017

3
--skip-worktree同じファイルが他のブランチで追跡されている場合、ブランチを切り替える前に、ファイルのステータスを元に戻す必要があることに注意してください。
moodboom 2018

3
うーん、動作します...ファイルに変更を加えた後、には表示されませんでしたgit statusが、別のブランチにチェックアウトしようとしたときerror: Your local changes to the following files would be overwritten by checkout: 、-fでもerror: Entry 'wix-stores-merchant-app/demo/credentials.js' not uptodate. Cannot merge.
役に立た

1
これらはとにエイリアスされgit ignoreていgit unignoreます。
マイケル-クレイシャーキー

48

あなたが探しているのはgit update-index --assume-unchanged default_values.txtです。

詳細については、ドキュメントを参照してください:http : //www.kernel.org/pub/software/scm/git/docs/git-update-index.html


11
これは動作しません。git addしますが。ローカルブランチ上のファイルを無視します。アーカイブのクローンにはこの動作はありません(クローンされたアーカイブのdefault_values.txtを変更すると、「git add。」を使用してコミットに追加されます)
Marc

6
はい、ローカルリポジトリ用に設定しているためです。この種の情報をプッシュすることはできません。
tamasd 2010

8
@Indradhanush-このソリューションは基準3を満たしていません-「動作はリポジトリのクローンに渡されるべきです」-これが私が受け入れなかった理由です。それが良い答えではないという意味ではありません。
マルク・

3番目の基準に気づかなかった。探していなかったから。:)
Indradhanush Gupta 2014

3
プライベートアプリ設定を含むローカル構成ファイルの場合は、詳細情報のskip-worktree代わりに使用する可能性があります。stackoverflow.com/ questions / 13630849assume-unchanged
アーロンホフマン

22

私が一般的に見たアプローチは、別の名前でファイルを作成することです。例:default_values_template.txtとdefault_values.txtを.gitignoreに入れます。ローカルワークスペースのdefault_values_template.txtをdefault_values.txtにコピーし、必要に応じて変更するように指示します。


うーん...多分私はdefault_valuesが存在しない場合にdefault_values_templateをdefault_valuesに自動的にコピーするフックを書くことができますか?
Marc

2
これは私の経験ではこれを解決する最も一般的な方法です。それは「うまくいく」という点でほとんど抵抗のないパスであり、ローカル構成ファイルが存在するかどうかをコードに簡単にチェックさせ、存在しない場合に役立つエラーを提供できます。
Jani Hartikainen

ソリューションは確かにこのようなことをすることだと思います。できれば、プルまたはクローンを作成するたびにスクリプトを実行します。1つのアイデアは、特定の拡張子を持つファイル(たとえば.basefile)が削除された拡張子を持つファイルにコピーされ、そのファイル名がそのディレクトリの.gitignoreに追加されるというものです。そのため、ファイルdefault_values.txt.basefileを作成してコミットします。私はこれを行うためのgitやperlのチョップを持っていませんが、そうする友人に聞いて、それがどのように機能するかを知らせます。
マルク・

1
@AdamDymitruk:はい、この場合はclean / smudgeを使用できますが、それが最良のオプションであることは明らかではありません。たとえば、人々が本当にファイルを変更したい場合、クリーン/スマッジが邪魔になるため、これはかなり難しくなります。私は実際にここで説明されているアプローチを好みます。
sleske 2013

1
私はgit自体(具体的にはgitフック)からキューを取得し、.sampleサフィックスを使用します。したがって、あなたの場合default_values.txt.sample
tir38

5

smudge / cleanスクリプトを見てみましょう。このようにしてファイルをバージョン管理できますが、チェックアウトされると、汎用/プレースホルダーデータをファイル内のマシン固有のデータに置き換えることにより、ファイルを「汚す」ことになります。

コミットすると、マシン固有の情報を一般的な情報またはプレースホルダー情報に置き換えることにより、「クリーン」になります。

スマッジ/クリーンスクリプトは、それらを複数回適用するという決定論的である必要があります。異なる順序で実行すると、シーケンスの最後のスクリプトを実行するのと同じになります。

リポジトリを公開する必要がある場合、パスワードに同じことが適用できますが、コンテンツに機密情報が含まれている可能性があります。


CleanスクリプトとSmudgeスクリプトはローカルですか、それともリポジトリの一部ですか?
2014年

はい。:) ...つまり、リポジトリを介してスマッジをクリーンに共有できますが、本番パスワードなどの機密データが含まれている場合はお勧めできません。それが問題ではない場合、gitではスクリプトを明示的に有効にする必要があります。さもなければ、人々はgithubや他の共有リポジトリを介して他のユーザーに悪意のあることをする可能性があります。
Adam Dymitruk、2014年

これについてもう少し読む必要があります。基本的にuser.json、各開発者の資格情報で上書きする必要があるデフォルトのプロジェクトをセットアップしたいのですが、開発者が誤って自分の資格情報をチェックインしたくありません。
アラン

私はきれいな汚れのサンプルスクリプトを探し回ります。何が起こるか見てください。また、freenodeのgit ircルームにジャンプします。あなたはすぐに助けを得るでしょう。
Adam Dymitruk、2014年

3

「クリーン」フィルターを定義して、インデックス内のファイルのコンテンツを単純にキャットすることで、これを解決しました。

git show :path/to/myfile 指定したファイルのインデックスの内容を出力するだけでよいので、それをスクリプトで使用して、インデックス内の作業コピーをそのままのコピーで置き換えることができます。

#! /bin/sh

git show :$1

それを関係のあるファイルの「クリーン」フィルターとして設定します(「discard_changes」に配置したと想定します)。

$ git config filter.ignore_myfile.clean "discard_changes path/to/myfile"
$ echo "path/to/myfile filter=ignore_myfile" >> .gitattributes

残念ながら、クリーンスクリプト内からどのファイルを処理しているのかを判別する方法がないため、これを複数のファイルに一般化する方法を見つけることができません。もちろん、ファイルごとに異なるフィルター規則を追加することを妨げるものは何もありませんが、それは少し不器用です。


1

私のチームに役立つ解決策を見つけました。シンボリックリンクを介して私たちのgithookを共有し、テンプレートファイルをgitに追加した後、テンプレートファイルが変更されているかどうかを確認するpre-commitフックを追加しましたgit reset -- templatefile.txt。変更された唯一のファイルである場合は、コミットも中止します。


-1

サブモジュールを調べることをお勧めします。マシン固有のファイルをサブモジュールに配置した場合、git addはそれを無視する必要があります。


これは良いアイデアですが、私はgitサーバーにも単一のファイルリポジトリを配置する必要があります。これは、githubを使用していてリポジトリの数が限られているという理由だけで、最適とは言えません。
Marc

@Marcは、Visual Studio Team Services、無制限の無料のプライベートプロジェクト、およびgitリポジトリを調べています。カンバンボード、作業項目とバグ追跡、チェックインと作業項目の関連付け、スクラムまたはその他のプロジェクトタイプへのスプリントの管理。それだけでなく、複数のプラットフォームに対してビルドするための優れたビルドツールを備えており、言及しきれないほど多くはすべて無料です。一部の人々は、Microsoftであるためにそれを怠っていますが、リポジトリのホスティングだけでなく、ツールに関してgithubが提供するものを打ち負かしています。無料でできることには限界がありますが、それを超えることはめったにありません。
Aran Mulholland 2017年

@Marcもう1つ便利だと思うのは、必要なだけアカウントを設定できることです。そのため、ソース管理を所有したいクライアント用のプロジェクトを作成している場合は、アカウントを作成できます。プロジェクトの計画、設計、実行を行い、終了したらアカウントの所有権をクライアントに渡すことができます。
Aran Mulholland 2017年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.