ChatGPT解决这个技术问题 Extra ChatGPT

从 Git 存储库中删除文件而不从本地文件系统中删除它

我的初始提交包含一些日志文件。我已将 *log 添加到我的 .gitignore,现在我想从我的存储库中删除日志文件。

git rm mylogfile.log

将从存储库中删除文件,但也会将其从本地文件系统中删除。如何在不删除文件的本地副本的情况下从存储库中删除此文件?

值得注意的是,最受支持的答案对某些人来说是危险的。如果您使用的是远程存储库,而不是推送本地存储库,则将仅从 git 中删除的那些文件拉到其他地方。其中一个回复中提到了这一点,但没有发表评论。
以正确的方式做到这一点:stackoverflow.com/questions/57418769/…
严重警告:请在粘贴已接受的答案之前阅读此答案。 stackoverflow.com/a/67793572/6073148

S
Sam

man file

当给出 --cached 时,暂存的内容必须匹配分支的尖端或磁盘上的文件,从而允许仅从索引中删除文件。

因此,对于单个文件:

git rm --cached mylogfile.log

对于单个目录:

git rm --cached -r mydirectory

很容易错过,因为它不像 svn rm --keep-local 那样易于解释。
但是如何保存远程服务器上的文件呢?这保留了我的本地文件,但如果我从另一台服务器推送和拉取,该文件将被删除。我还为该文件添加了一个 .gitignore,但它仍然被删除
如果您在 git rm 之后提交,这仍然会删除 git pull 上的文件
值得注意的是,运行答案中的命令后,需要使用git commit -m "Commit message"git push。如果您有任何其他分阶段的更改(检查 git status),它们也会在此时提交。
由于这是最被接受的答案并且没有做,所以要求什么,我会告诉我我做什么。我使用命令 git rm --cached mylogfile.log 并从存储库中删除该文件。为了避免在生产系统上丢失文件,我对文件进行了备份并在此之后拉取。如前所述,该文件已被删除,需要从备份中复制回来。这很痛苦,但我没有找到更好的解决这个问题的方法。
k
konsolenfreddy

要从 repo 中删除整个文件夹(如 Resharper 文件),请执行以下操作:

git rm -r --cached folderName

我已经提交了一些 resharper 文件,并且不希望这些文件保留给其他项目用户。


只是为未来的访问者添加的注释:不要使用 GUI 将提交“同步”回 repo。这会将文件拉回您的本地存储库。您必须执行 Git Push repo branch 才能真正从远程删除文件。
B
Bruno Brant

您还可以根据您的 .gitignore 从存储库中删除文件,而无需从本地文件系统中删除它们:

git rm --cached `git ls-files -i -X .gitignore`

或者,在 Windows Powershell 上:

git rm --cached $(git ls-files -i -X .gitignore)

不适用于 Windows。 git ls-files -i -X .gitignore 有效,但我不知道如何将文件发送到“git rm”。你知道怎么做吗?
如果您使用 Git Bash 而不是 cmd-console,则适用于 Windows
喜欢这个。工作除了我有一些文件最终在文件名中有空格。我在这里修改了解决方案:git ls-files -i -X .gitignore | xargs -I{} git rm --cached "{}"。请考虑在此处修改或将此解决方案添加到答案中,因为它是一个很棒的工具...
我没有尝试,但应该测试它是否还会删除像 .gitkeep 这样的文件,这些文件在存储库中保留了一个空文件夹。例如。 .gitignore 包含文件夹 uploads,并且 repo 被迫跟踪 .gitkeep。通过从 uploads 下的 repo 中删除所有内容,它也将删除 .gitkeep
这个建议在powershell中完美运行: git rm --cached $(git ls-files -i -X .gitignore)
C
Community

根据我的回答:https://stackoverflow.com/questions/6313126/how-to-remove-a-directory-in-my-github-repository

要仅从 git 存储库而不是从本地删除文件夹/目录或文件,请尝试 3 个简单步骤。

删除目录的步骤

git rm -r --cached File-or-FolderName
git commit -m "Removed folder from repository"
git push origin master

在下一次提交中忽略该文件夹的步骤

要从下一次提交中忽略该文件夹,请在根目录中创建一个名为 .gitignore 的文件,并将该文件夹名称放入其中。你可以放多少你想放多少

.gitignore 文件看起来像这样

/FolderName

https://i.stack.imgur.com/mJYfF.png


但是,当他们拉下您的更改时,这会删除其他人的本地文件吗?
M
Math Bob

更通用的解决方案:

编辑 .gitignore 文件。 echo mylogfile.log >> .gitignore 从索引中删除所有项目。 git rm -r -f --cached 。重建索引。混帐添加。进行新的提交 git commit -m "Removed mylogfile.log"


这实际上会删除文件吗?
来自 GitHub?不。如果您已经推送到 github,它不会将其从站点中删除。但它会更新您的本地 git 存储库。
您删除的评论实际上被删除了更多:) 解决方案 rm --cashed 的问题是它最终会在拉动时删除文件 - 对吗?当人们说“从存储库中删除文件而不从本地文件系统中删除它”时,这并不是人们想要的。现在为什么上面接受的解决方案超出了我的范围 - 可能是 OP 独自工作并且从未拉过?不知道。我了解 github“曾经一直推到那里”的问题 ofc
除非您询问 github 本身,否则我认为没有 100% 的解决方案。现在坚持这一点。复制文件,添加到 gitignore,执行实际的 git rm -r,提交,推送,恢复文件。您是否设法找到另一个解决方案?
我的问题不是 github - 它是 当他们拉动时文件实际上会从同事那里删除。我希望删除该文件。这在过去给我带来了很大的问题。所以我想知道是否真的有一个真正删除文件的解决方案。另请参阅已接受答案的评论:stackoverflow.com/questions/1143796/…
B
BoD

此外,如果您提交了敏感数据(例如包含密码的文件),您应该将其从存储库的历史记录中完全删除。以下是说明如何执行此操作的指南:http://help.github.com/remove-sensitive-data/


此答案应包括完成此任务所需的命令,而不是链接到另一个网站。
我还要指出,我发现使用 git bfg repo cleaner tool 更容易、更快捷。
R
Rystraum

Git 允许您通过假设它们未更改来忽略这些文件。这是通过运行 git update-index --assume-unchanged path/to/file.txt 命令来完成的。一旦将文件标记为这样,git 将完全忽略该文件上的任何更改;它们不会在运行 git status 或 git diff 时出现,也不会被提交。

(来自 https://help.github.com/articles/ignoring-files

因此,不要删除它,而是永远忽略对它的更改。我认为这仅在本地有效,因此除非他们运行与上述相同的命令,否则同事仍然可以看到对其的更改。 (但仍需要验证这一点。)

注意:这不是直接回答问题,而是基于其他答案评论中的后续问题。


嗯,我这样做了,但我看到如果其他人在 repo 上对其进行更改,该文件可能会被覆盖。
A
Afraz Ahmad

如果您只想取消跟踪文件而不是从本地和远程仓库中删除,请使用以下命令:

git update-index --assume-unchanged  file_name_with_path

虽然这是一个很好的答案,但重要的是要注意这不会“取消跟踪”文件,因为人们通常在 Git 中使用该词,其中未跟踪的文件是不在存储库历史记录中且从未出现过的文件.这个答案的作用是将文件保留在存储库中,但防止 Git 注意到已对其进行了更改。这有一些显着的差异——最重要的是,该文件仍然存在于其他人手中,如果其他人对其进行了更改并且您提取了该文件,则您的本地副本可能会被覆盖而无需确认。
A
Arthur Bowers

忽略文件,从 git 中删除文件,更新 git(用于删除)。

注意:这不涉及敏感信息的历史记录。

这个过程肯定需要对 git 发生的事情有所了解。随着时间的推移,获得了这一点,我学会了执行以下流程:

1)忽略文件

添加或更新项目 .gitignore 以忽略它们 - 在许多情况下,例如您的,父目录,例如 log/ 将是要使用的正则表达式。

提交并推送该 .gitignore 文件更改(不确定是否需要推送,请注意,如果完成则无害)。

2)从 git 中删除文件(仅)。

现在使用 git rm --cached some_dir/ 从 git 中删除文件(仅)

检查它们是否仍然留在本地(它们应该!)。

3)添加并提交该更改(本质上这是对“添加”删除内容的更改,尽管“添加”命令令人困惑!)

混帐添加。

git commit -m“删除”


有关为什么这是一个错误答案的详细信息,请参阅此问题:stackoverflow.com/questions/57418769/…
S
Samuel Philipp

以上答案对我不起作用。我使用 filter-branch 删除了所有已提交的文件。

使用以下命令从 git 存储库中删除文件:

git filter-branch --tree-filter 'rm  file'

使用以下命令从 git 存储库中删除文件夹:

git filter-branch --tree-filter 'rm -rf directory'

这将从所有提交中删除目录或文件。

您可以使用以下命令指定提交:

git filter-branch --tree-filter 'rm -rf directory' HEAD

或范围:

git filter-branch --tree-filter 'rm -rf vendor/gems' t49dse..HEAD

要将所有内容推送到远程,您可以执行以下操作:

git push origin master --force

这与 git rm -r --cached NAME 结合使用是从本地 git 存储库中删除它并防止它影响以后拉取的任何人的技巧(通过从 git 中删除文件或目录的历史记录。)
这会重写 git 历史,之后您需要推送 --force,这有点超出我猜的问题的范围。在一个公开的著名回购中,你不能像那样改变历史记录,因为每个已经克隆了回购的人在拉取时都会遇到问题。
从手册页“git filter-branch 有很多陷阱......请使用替代历史过滤工具,例如 git filter-repo”。另外,如果您要重写历史记录,我想您可以在早期修改忽略文件,以便在整个新历史记录中忽略已删除的项目?
Z
Zahid Khan

我想补充一下 @bdonlan 的已接受答案。

不要使用此答案来删除远程存在的文件。

git rm --cached filename

答案应该做什么?

它应该从本地暂存区域中删除您在以前的某些提交中错误地提交的一些文件。

并没有推到远程。如果远程推送,其他人不会关心这些变化。

它从 Tracked 𝐭𝐨 Untracked 状态移动文件,我的意思是,它删除文件并再次添加它们。

所以,git 不再知道它们了。

会出什么问题?

为什么?

摘要:您将文件从上演中删除,然后将其推开将导致合作团队本地存储库上的文件删除(𝘸𝘩𝘪𝘭𝘦𝘸𝘩𝘪𝘭𝘦𝘩𝘢𝘷𝘦𝘧𝘪𝘭𝘦𝘴𝘪𝘯𝘵𝘩𝘦𝘶𝘯𝘵𝘳𝘢𝘤𝘬𝘦𝘥𝘴𝘵𝘢𝘨𝘦𝘴𝘵𝘢𝘨𝘦,𝘧𝘰𝘳𝘧𝘰𝘳𝘢𝘭𝘭𝘵𝘦𝘢𝘮𝘴𝘵𝘦𝘢𝘮𝘴


如果没有替代解决方案,这是一个(非常重要的)评论,但不是答案。
但是,git 不会保留此文件的历史记录吗?我的意思是,我们总是可以恢复原状?
@RaynalGobel 是的 git 有所有可用的历史记录,您可以随时恢复。但问题是你应该这样做吗?就像您在本地拥有该文件时删除了协作者的文件一样?就我而言,领导信任我并盲目地合并我的 PR。该应用程序在我的机器上运行时无法在他的机器上运行。想想这个场景!
D
Dharman

这取决于您从 git 中“删除”的意思。 :)

您可以使用 git rm --cached see for more details 取消暂存文件。当您取消暂存某些内容时,这意味着它不再被跟踪,但这不会从以前的提交中删除该文件。

如果您想做的不仅仅是取消暂存文件,例如从所有以前的提交中删除敏感数据,您需要考虑使用 BFG Repo-Cleaner 等工具过滤分支。


h
hj yan

由于 rm --cache 将删除远程存储库中的文件,因此您可以改用 update-index
请参阅:https://docs.microsoft.com/en-us/azure/devops/repos/git/ignore-files?view=azure-devops&tabs=visual-studio-2019