検索

ホームページ  >  に質問  >  本文

git忽略已经被提交的文件

现在项目的根目录放了 .gitignore 文件,并且git远程仓库的项目根目录已经有了 logs文件夹。

由于每次本地运行项目,都会生成新的log文件,但是我并不想提交logs文件夹里面的内容,所以要在.gitignore写logs的规则。

我尝试过添加以下规则
logs/*.log
logs/
/logs/

但是运行git status的时候,始终能看到modified:logs/xx.log 。

请问是我的规则编写错误,还是我某个地方有理解错误?

高洛峰高洛峰2844日前732

全員に返信(5)返信します

  • 阿神

    阿神2017-04-24 16:02:46

    tl;dr: 正しいアプローチは次のとおりです: git rm --cached logs/xx.log を実行し、.gitignore ターゲット ファイルを無視し、最後に git commit -m "これ以上 Git に追跡させたくないです!" git rm --cached logs/xx.log,然后更新 .gitignore 忽略掉目标文件,最后 git commit -m "We really don't want Git to track this anymore!"

    具体的原因如下:

    被采纳的答案虽然能达到(暂时的)目的,但并非最正确的做法,这样做是误解了 git update-index 的含义,而且这样做带来的最直接(不良)后果是这样的:

    1. 所有的团队成员都必须对目标文件执行:git update-index --assume-unchanged <PATH>。这是因为即使你让 Git 假装看不见目标文件的改变,但文件本身还是在 Git 的历史记录里的,所以团队的每个人在 fetch 的时候都会拉到目标文件的变更。(但实际上目标文件是根本不想被 Git 记录的,而不是假装看不见它发生了改变)

    2. 一旦有人改变目标文件之后没有 git update-index --assume-unchanged <PATH> 就直接 push 了,那么接下来所有拉取了最新代码的成员必须重新执行 update-index,否则 Git 又会开始记录目标文件的变化。这一点实际上很常见的,比如说某成员换了机器或者硬盘,重新 clone 了一份代码库,由于目标文件还在 Git 的历史记录里,所以他/她很可能会忘记 update-index

    为什么会这样?答案就在 Git 的 man pages 里:

    首先,git update-index 的定义是:

    Register file contents in the working tree to the index(把工作区下的文件内容注册到索引区)

    这句话暗含的意思是:update-index 针对的是 Git 数据库里被记录的文件,而不是那些需要忽略的文件。

    接着看关于 --assume-unchanged 的几句相关的描述:

    When the "assume unchanged" bit is on, Git stops checking the working tree files for possible modifications, so you need to manually unset the bit to tell Git when you change the working tree file. This is sometimes helpful when working with a big project on a filesystem that has very slow lstat(2) system call (e.g. cifs).

    大致意思是:

    应用了该标识之后,Git 停止查看工作区文件可能发生的改变,所以你必须 手动 重置该标识以便 Git 知道你想要恢复对文件改变的追踪。当你工作在一个大型项目中,这在文件系统的 lstat

    具体的な理由は次のとおりです: #🎜🎜# #🎜🎜#受け入れられた回答は(一時的な)目的を達成できますが、これは最も正しいアプローチではなく、git update-index の意味を誤解しており、最も深刻な結果をもたらします。直接的な(悪影響)は次のとおりです: #🎜🎜# <オル>
  • #🎜🎜#すべてのチーム メンバーは、ターゲット ファイルに対して git update-index --assume-unchanged <PATH> を実行する必要があります。これは、Git にターゲット ファイルへの変更が表示されないふりをさせたとしても、ファイル自体は Git の履歴に残っているため、 チームの全員がフェッチするときにターゲット ファイルへの変更をプルするためです。 (しかし実際には、ターゲット ファイルは変更を見て見ぬふりをするのではなく、Git によって記録されることをまったく望んでいません) #🎜🎜#
  • #🎜🎜#誰かがターゲット ファイルを変更し、git update-index --assume-unchanged <PATH> なしで直接プッシュすると、次のすべてのメンバーが変更されます。最新のコードをプルした人​​は、update-index を再度実行する必要があります。そうしないと、Git はターゲット ファイルへの変更の記録を再度開始します。たとえば、メンバーがマシンまたはハードディスクを変更し、 コード ベースをクローンする場合、ターゲット ファイルがまだ Git 履歴に残っているため、これは実際には非常に一般的です。 >update-index は忘れられます。 #🎜🎜#
  • #🎜🎜#これはなぜですか?答えは Git のマニュアル ページにあります: #🎜🎜# #🎜🎜#まず、git update-index の定義は次のとおりです: #🎜🎜# <ブロック引用> #🎜🎜#ワーキングツリーのファイル内容をインデックスに登録 (ワークスペースのファイル内容をインデックス領域に登録) #🎜🎜#
    #🎜🎜#この文の暗黙の意味は次のとおりです: update-index は、無視する必要があるファイルではなく、Git データベースに記録されているファイルをターゲットにします。 #🎜🎜# #🎜🎜#次に、--unchanged を仮定するに関するいくつかの関連説明を見てください: #🎜🎜# <ブロック引用> #🎜🎜#「変更されていないと仮定する」ビットがオンの場合、Git は作業ツリー ファイルの変更の可能性のチェックを停止するため、作業ツリー ファイルを変更するときに Git に通知するために手動でビットの設定を解除する必要があります。これは作業中に役立つ場合があります。非常に遅い lstat(2) システムコール (cifs など) を持つファイルシステム上の大きなプロジェクトを使用します。#🎜🎜# #🎜🎜# はおおよそ次の意味です: #🎜🎜# <ブロック引用> #🎜🎜# このフラグを適用した後、Git はワークスペース ファイルに加えられる可能性のある変更の確認を停止するため、#🎜🎜#手動で #🎜🎜# フラグをリセットして、ファイル変更の追跡を再開したいことを Git に認識させる必要があります。これは、ファイル システムの lstat システム コールが非常に遅いときに大規模なプロジェクトで作業している場合に便利です。 #🎜🎜#

    Git がコードのバージョン管理に使用されているだけでなく、他の分野の多くのプロジェクトでも Git が使用されていることはわかっています。例えば、弊社のクライアントのプロジェクトでは精密部品の図面ドキュメントのバージョン管理が行われており、こちらもGitを利用していました。使用シナリオの 1 つは、いくつかの大きなファイルを変更することですが、Git を保存するたびに、ファイルの変更を計算してワークスペースを更新する必要があり、ハード ディスクが遅い場合、この遅延は非常に顕著です。

    git update-index --assume-unchanged 実際の使用法は次のとおりです: git update-index --assume-unchanged 的真正用法是这样的:

    1. 你正在修改一个巨大的文件,你先对其 git update-index --assume-unchanged,这样 Git 暂时不会理睬你对文件做的修改;
    2. 当你的工作告一段落决定可以提交的时候,重置改标识:git update-index --no-assume-unchanged,于是 Git 只需要做一次更新,这是完全可以接受的了;
    3. 提交+推送。

    另外,根据文档的进一步描述:

    This option can be also used as a coarse file-level mechanism to ignore uncommitted changes in tracked files (akin to what .gitignore does for untracked files).

    这段描述告诉我们两个事实:

    1. 虽然可以用其来达成楼主想要的结果,但这是不讲究的做法(coarse);
    2. 同样的事情更应该用 .gitignore 文件来实现(针对未追踪的文件)。

    随之而来的问题是:为什么我增加了 .gitignore 里的规则却没有效果?

    这是因为我们误解了 .gitignore 文件的用途,该文件只能作用于 Untracked Files,也就是那些从来没有被 Git 记录过的文件(自添加以后,从未 add 及 commit 过的文件)。

    之所以你的规则不生效,是因为那些 .log 文件曾经被 Git 记录过,因此 .gitignore 对它们完全无效。这也正是开头那段简短答案所做的事情:

    1. 从 Git 的数据库中删除对于该文件的追踪;
    2. 把对应的规则写入 .gitignore,让忽略真正生效;
    3. 提交+推送。

    只有这样做,所有的团队成员才会保持一致而不会有后遗症,也只有这样做,其他的团队成员根本不需要做额外的工作来维持对一个文件的改变忽略。

    最后有一点需要注意的,git rm --cached 删除的是追踪状态,而不是物理文件;如果你真的是彻底不想要了,你也可以直接 rm <オル>

  • 巨大なファイルを変更しているため、最初に git update-index --assume-unchanged を実行して、Git がファイルへの変更を一時的に無視するようにする必要があります。
  • 作業が完了し、送信する準備ができたら、変更フラグをリセットします: git update-index --no-assume-unchanged。これにより、Git は 1 回だけ更新するだけで済みます。これは完全に完了です。許容可能;
  • 送信 + プッシュ。
  • また、ドキュメントの詳細な説明によると: 🎜 <ブロック引用> 🎜このオプションは、追跡されたファイル内のコミットされていない変更を無視するための粗いファイルレベルのメカニズムとしても使用できます ( .gitignore が追跡されていないファイルに対して行うことと同様です)。 🎜 🎜この説明から 2 つの事実が分かります: 🎜 <オル>
  • 投稿者が望む結果を達成するために使用できますが、これは野暮な (粗野な) アプローチです。
  • 同じことは、.gitignore ファイルを使用して実行する必要があります (追跡されていないファイルの場合)。
  • 🎜そこで生じる疑問は、.gitignore にルールを追加したのに効果がなかったのはなぜですか? 🎜 🎜これは、.gitignore ファイルの目的を誤解しているためです。このファイルは追跡されていないファイル、つまりこれらのファイルでのみ使用できます。 Git によって使用されていない記録ファイル (追加されてから一度も追加またはコミットされていないファイル)。 🎜 🎜ルールが有効にならない理由は、これらの .log ファイルが Git によって記録されているため、.gitignore がそれらのファイルに対して完全に無効であるためです。これはまさに冒頭の短い答えが行うことです: 🎜 <オル>
  • Git データベースからファイルの追跡を削除します。
  • 無視を有効にするには、対応するルールを .gitignore に書き込みます。
  • 送信 + プッシュ。
  • 🎜これを行うだけで、副作用なくすべてのチーム メンバーの一貫性が保たれ、これを行うだけで、他のチーム メンバーはファイルへの変更を無視し続けるために余分な作業をまったく行う必要がなくなります。 🎜 🎜最後に注意すべき点は、git rm --cached は物理ファイルではなく追跡ステータスを削除することです。本当に削除したくない場合は、直接 rm を実行することもできます。コード>+無視+送信。 🎜

    返事
    0
  • 伊谢尔伦

    伊谢尔伦2017-04-24 16:02:46

    メンテナンスされているファイルの場合、gitignore を追加しても役に立ちません。
    次のコマンドを使用します:
    git update-index --assume-unchanged logs/*.log
    こうすることで、送信するたびにログの下のファイルが表示されなくなります

    返事
    0
  • 我想大声告诉你

    我想大声告诉你2017-04-24 16:02:46

    詳しく答えてください
    .gitignore は、元々追跡されていないファイルのみを無視できます。バージョン管理に一部のファイルが含まれている場合、.gitignore の変更は無効です。
    正しいアプローチは、特定のファイルへの変更をチェックしないように、クローン化された各ウェアハウスで手動で設定することです。

    リーリー

    さらに、git には同じことを行うための別の exclude メソッドも用意されています。違いは、.gitignore ファイル自体がリポジトリに送信されることです。除外する必要があるパブリック ファイルを保存するために使用されます。 .git/info/exclude は、ローカルで除外する必要があるファイルをここに設定します。 彼は他の誰にも影響を与えません。リポジトリには送信されません。

    .gitignore には、空の .gitignore ファイルをプレースホルダーとして使用できる興味深い小さな機能もあります。これは、プロジェクト用に空のログ ディレクトリを作成する必要がある場合に役立ちます。 ログ ディレクトリを作成し、その中に空の .gitignore ファイルを配置できます。このようにして、このリポジトリのクローンを作成すると、git は空のログ ディレクトリを自動的に作成します。

    返事
    0
  • 仅有的幸福

    仅有的幸福2017-04-24 16:02:46

    ログファイルを削除し、ingoreを追加して、再度コミットします

    返事
    0
  • 过去多啦不再A梦

    过去多啦不再A梦2017-04-24 16:02:46

    最も投票数の多かった回答 (n͛i͛g͛h͛t͛i͛r͛e͛) は質問をま​​ったく理解していなかったことがわかりました
    代わりに、@FatGhosta の回答が正しい回答です

    n ͛i ͛ g ͛ h ͛ t ͛i ͛ r ͛e ͛の方法に従えば、
    「ファイルをローカルに保持したまま記録する必要のないファイルを git から削除し、今後のコミットでは無視する」を達成するだけです。 "
    に到達する代わりに
    "git の既存のファイルで既にコミットする場合は無視します"

    実際には、このようなシーンになるはずです。データベースのリンク情報などの設定ファイルがあります。
    誰のリンク情報も同じではありませんが、その記入方法を示す標準テンプレートが提供されている必要があります。リンク情報を git に記録する必要があります。その後、各人が独自の状況に応じてリンク情報のコピーを設定しますが、その設定ファイルをライブラリに送信する必要はありません
    したがって、FatGhosta の答えがこの質問に対する正しい答えになります

    返事
    0
  • キャンセル返事