ChatGPT解决这个技术问题 Extra ChatGPT

如何停止跟踪并忽略 Git 中文件的更改?

git

我克隆了一个包含一些 .csproj 文件的项目。我不需要/不喜欢 Git 跟踪我的本地 csproj 文件(或在创建补丁时提出),但显然项目中需要它们。

我已将 *.csproj 添加到我的本地 .gitignore,但文件已在存储库中。

当我输入 git status 时,它会显示我对 csproj 的更改,我对跟踪或提交补丁不感兴趣。

如何从我的个人存储库中删除这些文件的“跟踪”(但将它们保留在源中以便我可以使用它们),以便在我执行状态(或创建补丁)时看不到更改?

是否有正确/规范的方法来处理这种情况?

一个非常有用的问题,但我很好奇您为什么不想跟踪对 .csproj 文件的更改,这是任何项目的重要组成部分。对 .csproj.user 文件或任何 .Publish.XML 文件的更改我完全可以理解不跟踪,但我很好奇您为什么不想跟踪 .csproj
也许他们使用不同的 IDE?
具有讽刺意味的是,我来到这个线程是因为我希望从存储库中删除 .suo 文件,但将它们保存在本地。对于后代,.Net 开发要求您将 .csproj 文件保留在 repo 中,并且应始终跟踪这些更改,除非您想感受项目中任何其他开发人员的愤怒。如果不确定,请查看 GitHub 上的 gitignore 文件存储库:github.com/github/gitignore/blob/master/VisualStudio.gitignore

W
WonderLand

只需对要从修订控制中删除的每个文件调用 git rm --cached 就可以了。只要您的本地忽略模式是正确的,您就不会在 git status 的输出中看到这些文件。

请注意,此解决方案会从存储库中删除文件,因此所有开发人员都需要维护自己的本地(非修订控制)文件副本

为了防止 git 检测到这些文件中的更改,您还应该使用以下命令:

git update-index --assume-unchanged [path]

您可能想做的事情:(从下面的 @Ryan Taylor answer 开始)

这是告诉 git 你想要你自己的独立版本的文件或文件夹。例如,您不想覆盖(或删除)生产/暂存配置文件。 git update-index --skip-worktree <路径名>

完整答案在此 URL 中:http://source.kohlerville.com/2009/02/untrack-files-in-git/


“git rm --cached ”将从版本控制中删除 ,同时将其保留在工作存储库中。不管是你想要的...
但是当其他人拉取存储库时,他们自己的 *.csproj 文件会被删除吗?因为如果我们希望文件不被跟踪,但不被删除。
如果您尝试删除目录中的所有文件,请将其与 git ls-files: git ls-files | xargs git rm --cached 结合使用——这将从给定目录中的 git 索引中删除所有内容,而不会删除实际文件。
git rm --cached -r <dir> 以递归方式作用于文件夹及其中的所有文件。
这将停止对文件的跟踪,将其保存在本地,但会导致任何拉取文件的人将其删除
M
Michael

有3个选项;你可能想要#3

这将为您保留本地文件,但会在其他任何人拉取时将其删除。 git rm --cached 或 git rm -r --cached 这是为了优化,就像一个包含大量文件的文件夹,例如可能永远不会改变的 SDK。它告诉 Git 每次都停止在本地检查那个巨大的文件夹是否有变化,因为它不会有任何变化。如果文件/文件夹有上游更改(当您拉取时),假设未更改的索引将被重置并覆盖文件。 git update-index --assume-unchanged 这是告诉 Git 你想要你自己的独立版本的文件或文件夹。例如,您不想覆盖(或删除)生产/暂存配置文件。 git update-index --skip-worktree 重要的是要知道 git update-index 不会随 Git 传播,因此每个用户都必须独立运行它。


这个答案是最完整的 - 它提供了各种解决方案以及每种解决方案的影响。我正在使用的特定案例在配置文件中嵌入了密码。我想传播一个模板文件,然后将密码添加到我的副本中。带有密码的副本应该被忽略而不是被覆盖。
如何在我的本地检查哪些文件适用于“假设不变”或“跳过工作树”?
@SupawatPusavanno 要查看您之前为假设未更改或跳过工作树选择的文件,请查看此答案 stackoverflow.com/questions/42363881/… - 它使用 grepgit ls-files
很好的答案。但是当我尝试切换到不同的分支时,git会抛出错误:错误:“您对以下文件的本地更改将被结帐.....”并且解决方案是在切换之前存储更改并在何时取消存储你回到分支。
@RyanTaylor 是否可以保留您自己的本地文件版本,而不是推送您自己的更改,同时仍将更改推送到存储库?
C
CharlesB

如果您执行 git update-index --assume-unchanged file.csproj,git 将不会自动检查 file.csproj 的更改:这将阻止它们在您更改它们时以 git 状态出现。因此,您可以通过这种方式标记所有 .csproj 文件——尽管您必须手动标记上游存储库发送给您的任何新文件。 (如果您在 .gitignore.git/info/exclude 中有它们,那么您创建的将被忽略)

我不完全确定 .csproj 文件是什么......如果它们与 IDE 配置类似(类似于 Eclipse 的 .eclipse 和 .classpath 文件),那么我建议它们永远不应该在全部。另一方面,如果它们是构建系统的一部分(如 Makefiles),那么显然它们应该——并且一种获取可选本地更改的方法(例如从 local.csproj 和 la config.mk)将很有用:将构建分为全局部分和局部覆盖。


csproj 是一个 C# 项目文件,它跟踪您的项目中包含哪些文件和其他一些配置,它必须是源代码控制才能使项目工作
这是这里唯一正确的答案!我多年来一直在使用@araqnids 答案,它完全按照解决此问题的要求工作。
是否有某种方法可以检测到文件是否已完成此操作,或者已在 repo 中完成了哪些文件?我有点担心忘记我做了这个,然后想知道为什么这个文件没有得到更新,稍后!
@GreenAsJade:git ls-files -v 将使用小写指示符显示假定未更改的文件(例如 h 而不是通常的 H 用于缓存文件)。
谢谢 - 这颗小珍珠几乎值得自己提出问题! ...完成stackoverflow.com/questions/27162966/…
K
Kalle Richter

这是一个两步过程:

删除文件/文件夹的跟踪-但将它们保留在磁盘上-使用 git rm --cached 现在它们不会显示为“已更改”,但仍会在 git status -u 中显示为未跟踪的文件将它们添加到 .gitignore


不,这将从跟踪中删除文件,将其保存在本地,但会导致任何拉动的人都将其删除。
就我而言,我不小心添加了一个我不想跟踪的文件夹,所以这就是我需要的。
是的,这确实是问题的错误答案——但对于大多数在搜索结果中找到这个问题的人(比如我)来说,这可能是正确的答案。
B
Buddhika Hasthanayake

接受的答案仍然对我不起作用

我用了

git rm -r --cached 。混帐添加。 git commit -m "修复.gitignore"

here 找到答案


该链接非常有用,尤其是在递归删除 .gitignore 中的所有文件时
我已经回到这里 3 次了,希望我能在下次之前记住!
@Edward Newell 在 above answer 中的评论也适用于此处:“这将从跟踪中删除文件,将其保存在本地,但会导致任何拉动的人都将其删除”。
G
Gangnus

忘记了 .gitignore?

如果您在本地拥有整个项目但忘记添加 git ignore 并且现在正在跟踪一些不必要的文件,请使用此命令删除所有内容

git rm --cached -r .

确保您位于项目的根目录。

然后你可以照常做

添加

git add .

犯罪

git commit -m 'removed all and added with git ignore'

git push origin master

结论

希望这可以帮助那些不得不更改他们的 .gitignore 或完全忘记它的人。

它删除了整个缓存

查看您的 .gitignore

添加要跟踪的文件

推送到您的仓库


当您谈论删除或添加时,您忘记了何时何地。从曲目列表中删除?从存储库?来自本地项目空间?一拉就拆?提交时?推?唉,这里的所有作者都有同样的问题。
@Gangnus我认为没有人“澄清”您要提出的观点,因为很明显该文件实际上并未从磁盘或存储库中删除。此答案指定命令的时间顺序。正如您的评论所暗示的那样,这并不神秘或解释不清。
@Edward Newell 在 above answer 中的评论也适用于此处:“这将从跟踪中删除文件,将其保存在本地,但会导致任何拉动的人都将其删除”。
正是我要找的……谢谢分享!! ;)
t
the_new_mr

正如其他答案中指出的那样,所选答案是错误的。

另一个问题的 answer 表明它可能是需要的跳过工作树。

git update-index --skip-worktree <file>

answer 链接到一篇文章 (http://fallengamer.livejournal.com/93321.html) 并引用该文章,并很好地总结了 --assume-unchanged 和 --skip-worktree 之间的区别,如下所示:

--assume-unchanged 假定开发人员不应该更改文件。此标志旨在提高 SDK 等不更改文件夹的性能。

--skip-worktree 当您指示 git 不要碰特定文件时很有用,因为开发人员应该更改它。例如,如果上游的主存储库托管了一些生产就绪的配置文件,并且您不想意外提交对这些文件的更改,那么 --skip-worktree 正是您想要的。

所有功劳归功于 borealid 的研究和回答。在这里包含此信息纯粹是为了方便他人。


不,不是:--skip-worktree 用于将文件保留在存储库中但停止跟踪其更改。正如您的回答所说: --skip-worktree 当您指示 git 不要触摸特定文件时很有用,因为开发人员应该更改它
@ErdalG。确切地。根据问题,他们希望忽略文件中的任何更改,但将文件保留在 repo 中
同意@the_new_mr ,--assume-unchanged--skip-worktree 具有相似的效果,但它们的目的完全不同。前者是通过欺骗 git 不检查特定文件来加快 git 性能,而后者是 忽略特定文件的未来更改,适用于运行时但必不可少的文件。
s
shijin

防止通过 git 监控文件或路径

git update-index --assume-unchanged [file-path]

并将其恢复使用

git update-index --no-assume-unchanged [file-path]

用于参考类似用例的存储库 https://github.com/awslabs/git-secrets


P
Peter

为了节省一些时间,您添加到 .gitignore 的规则可用于删除多个文件/文件夹,即

git rm --cached app/**/*.xml

或者

git rm --cached -r app/widgets/yourfolder/

ETC


这是一个非常好的解决方案,因为您想逐步修复 gitignore
b
belka

很多人建议您使用 git update-index --assume-unchanged。事实上,这可能是一个很好的解决方案,但只是在短期内。

您可能想要做的是:git update-index --skip-worktree

(您可能不想要的第三个选项是:git rm --cached。它将保留您的本地文件,但会被标记为从远程存储库中删除。)

前两个选项之间的区别?

假设未更改是临时允许您隐藏文件中的修改。如果你想隐藏对文件所做的修改,修改文件,然后签出另一个分支,你必须使用 no-assume-unchanged 然后可能隐藏修改完成。

无论您签出哪个分支,skip-worktree 都会跟随您进行修改!

assume-unchanged的用例

它假定不应修改此文件,并在执行 git status 时为您提供更清晰的输出。但是当签出到另一个分支时,您需要重置标志并在此之前提交或存储更改。如果您在激活此选项的情况下进行拉取,您将需要解决冲突并且 git 不会自动合并。它实际上只隐藏修改(git status 不会显示标记的文件)。

当我只想暂时停止跟踪更改 + 提交与 same 修改相关的一堆文件 (git commit -a) 时,我喜欢使用它。

skip-worktree的用例

您有一个设置类,其中包含您的朋友必须根据他们的设置相应地更改的参数(例如,包括密码)。

1:创建此类的第一个版本,填写您可以填写的字段并将其他字段留空/null。

2:提交并推送到远程服务器。

3: git update-index --skip-worktree MySetupClass.java

4:用你自己的参数更新你的配置类。

5:回去工作另一个功能。

无论分支如何,您所做的修改都将跟随您。警告:如果你的朋友也想修改这个类,他们必须有相同的设置,否则他们的修改会被推送到远程仓库。拉动时,文件的远程版本应覆盖您的文件。

PS:做一个或另一个,但不要同时做,因为你会有不良的副作用。如果你想尝试另一个标志,你应该先禁用后者。


K
Kaka Ruto

要告诉 Git 不要跟踪对本地文件/文件夹的更改(意味着 git status 不会检测到对它的更改),请执行以下操作:

git update-index --skip-worktree path/to/file

并告诉 Git 再次跟踪对本地版本的更改(以便您可以提交更改),请执行以下操作:

git update-index --no-skip-worktree path/to/file

S
Seeni

一行回答git update-index --assume-unchanged [path]

只要您有一个位于中央仓库和本地仓库中的文件,就可以使用它。您需要在该文件中进行更改,但不得暂存/提交到中央仓库。此文件不应添加到 .gitignore。因为如果系统管理员引入文件中的新更改,高级开发人员需要分布在所有本地存储库中。

最佳示例:数据库连接的配置文件。在中央存储库中,您将拥有所有用户名、密码、主机、端口以及生产数据库服务器的值。但是在本地开发中,您应该只使用本地或任何其他开发数据库服务器(您的团队已经设置)。在这种情况下,您想在配置文件中进行更改,但不应该提交到中央仓库。

最好的


C
Community

将 .gitignore 应用于现在/未来

此方法应用标准的 .gitignore 行为,不需要手动指定需要忽略的文件。不能再使用 --exclude-from=.gitignore 了:/ - 这是更新的方法: 一般建议:从一个干净的 repo 开始 - 所有内容都已提交,工作目录或索引中没有任何待处理的内容,并进行备份!

#commit up-to-date .gitignore (if not already existing)
#this command must be run on each branch
git add .gitignore
git commit -m "Create .gitignore"

#apply standard git ignore behavior only to current index, not working directory (--cached)
#if this command returns nothing, ensure /.git/info/exclude AND/OR .gitignore exist
#this command must be run on each branch
git ls-files -z --ignored --exclude-standard | xargs -0 git rm --cached

#optionally add anything to the index that was previously ignored but now shouldn't be:
git add *

#commit again
#optionally use the --amend flag to merge this commit with the previous one instead of creating 2 commits.

git commit -m "re-applied modified .gitignore"

#other devs who pull after this commit is pushed will see the  newly-.gitignored files DELETED

如果您还需要从分支的提交历史记录中清除新忽略的文件或者如果您不希望从未来的拉取中删除新忽略的文件,请参阅this answer


N
Nisrine Bou Ghannam

git rm --fileName

git ls-files 以确保文件已被删除或未跟踪

git commit -m "UntrackChanges"

git push


V
Vraj Pandya

我假设您询问如何删除特定文件夹或 bin 文件夹中的所有文件,而不是单独选择每个文件。

您可以使用此命令:

git rm -r -f /<floder-name>\*

确保您位于该目录的父目录中。
此命令将递归地“删除”所有文件它们位于 bin/ 或 build/ 文件夹中。删除这个词我的意思是 git 会假装这些文件被“删除”并且这些文件不会被跟踪。 git 确实将这些文件标记为处于删除模式。

请确保您的 .gitignore 已为即将到来的提交做好准备。
Documentation : git rm


t
thearyong

该问题可能是由操作顺序引起的。如果你先修改了.gitignore,然后git rm --cached xxx,你可能还要继续遇到这个问题。

正确解决方案:

git rm --cached xxx 修改了 .gitignore

订单不变!

.gitignore 修改后重新加载!


P
Pankaj Sonani

我假设您正在尝试从 git tacking 中删除单个文件。为此,我建议使用以下命令。

git update-index --assume-unchanged

前 - git update-index --assume-unchanged .gitignore .idea/compiler.xml


m
mpag

要忽略对目录中所有文件(某种类型)的任何更改,我必须结合其中一些方法,否则如果文件以前不存在,则会创建这些文件。

在下面,“excludedir”是我不希望看到更改的目录的名称。

首先,从更改跟踪缓存中删除任何现有的新文件(不从文件系统中删除)。

git status | grep "new file:" | cut  --complement -d " " -f1-4 | grep "^excludedir" | xargs git rm --cache

您可以对 modified: 执行相同的操作。 renamed: 有点复杂,因为您必须查看新文件名的后 -> 位,并按照下面对 deleted: 的描述执行前 -> 位。

deleted: 文件证明有点复杂,因为您似乎无法为本地系统上不存在的文件更新索引

echo .deletedfiles >> .gitignore
git status | grep "deleted:" | cut  --complement -d " " -f1-4 | grep "^excludedir" > .deletedfiles
cat .deletedfiles | xargs -d '\n' touch
cat .deletedfiles | xargs -d '\n' git add -f
cat .deletedfiles | xargs -d '\n' git update-index --assume-unchanged
cat .deletedfiles | xargs -d '\n' rm

上面列表中的最后一个命令将再次从文件系统中删除文件,因此请随意省略它。

然后,阻止该目录的更改跟踪

git ls-files excludedir/ | xargs git update-index --skip-worktree
git update index --skip-worktree excludedir/

H
Herpes Free Engineer

在这个 answer 中给出了一个几乎 git command-free 方法

要忽略每个本地 repo 的某些文件:

创建一个文件 ~/.gitignore_global,例如通过在终端中触摸 ~/.gitignore_global。运行 git config --global core.excludesfile ~/.gitignore_global 一次。将要忽略的文件/目录路径写入 ~/.gitignore_global。例如modules/*.H,假定它在你的工作目录中,即$WORK_DIR/modules/*.H。

要忽略单个本地存储库的某些文件:

对 repo 中的文件 .git/info/exclude 执行上述第三步,即将要忽略的文件/目录路径写入 .git/info/exclude。例如modules/*.C,它会被假定在你的工作目录中,即$WORK_DIR/modules/*.C。


c
chinaanihchen

找了半天,想办法做到这一点。在 .gitconfig 中别名一个 git 命令。就像在 android studio 项目中一样,在 checkout 分支之前还原配置文件然后跳过它,在 checkout 分支之后使用 sed 将配置文件更改为我的本地配置。 checkoutandmodifylocalproperties = !git update-index --no-skip-worktree local.properties && git checkout local.properties && git checkout $1 && git update-index --skip-worktree local.properties && sed -i '' 's/.*sdk.dir.*/sdk.dir=\\/Users\\/run\\/Library\\/Android\\/sdk/g' local.properties && :