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


3041

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

git rm mylogfile.log

将从存储库中删除文件,但也会从本地文件系统中删除该文件。

如何在删除文件的本地副本的情况下从存储库中删除此文件?



14
值得注意的是,对于某些人来说,最不赞成的答案很危险。如果您正在使用远程仓库,而不是在推送本地仓库时,则将您从git中删除的那些文件拉到其他位置,只会被删除。答复之一中提到了这一点,但未对此发表评论。
RichieHH

Answers:


4346

man文件中

如果--cached指定,则暂存内容必须与分支的顶端或磁盘上的文件匹配,从而允许仅从索引中删除文件。

因此,对于单个文件:

git rm --cached mylogfile.log

对于单个目录:

git rm --cached -r mydirectory

150
很容易错过,因为它不像自我解释那样svn rm --keep-local
马丁

114
但是,如何将文件保存在远程服务器上?这将保留我的本地文件,但是如果我从另一台服务器推入和拉出,该文件将被删除。我还为该文件添加了一个.gitignore文件,但仍然被删除了
spankmaster79 2013年

6
git pull如果您在提交之后仍处于提交之后,这仍会删除文件git rm
Petr Peller 2014年

9
值得注意的是,在答案中运行命令后,您需要使用git commit -m "Commit message"git push。如果您有任何其他阶段性更改(请使用选中git status),则这些更改也将在此时提交。
Sinjai

9
由于这是最被接受的答案,并且不会做,所以要问我要做什么。我使用命令git rm --cached mylogfile.log并从存储库中删除文件。为了避免在生产系统上丢失文件,我对文件进行备份并在此之后进行提取。如前所述,该文件已被删除,需要从备份中复制回来。这是很痛苦的,但是我没有找到更好的解决方案。
Marcel Grolms

275

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

git rm -r --cached folderName

我已经提交了一些共享文件,并且不想让其他项目用户继续使用。


13
只是给将来的访问者的补充说明:不要使用GUI将提交“同步”回存储库。这样会将文件拉回到本地存储库中。您必须执行一次操作Git Push repo branch才能从远程删除文件。
RubberDuck

211

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

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

或者,或者,在Windows Powershell上:

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

7
在Windows上不起作用。git ls-files -i -X .gitignore可以工作,但是我不知道如何将文件发送到'git rm'。你知道怎么做吗?
Erik Z

17
如果您使用Git Bash代替cmd-console,则可在Windows上运行
Andreas Zita 2014年

17
喜欢这个。除了我的某些文件最终在文件名中包含空格之外,它的工作原理是有效的。我修改的方案在这里这样的:git ls-files -i -X .gitignore | xargs -I{} git rm --cached "{}"。请考虑在此处将解决方案修改或添加到答案中,因为它是拥有...的绝佳工具……
mpettis

我没有尝试,但是应该测试它是否还会删除文件,例如.gitkeep在存储库中保留一个空文件夹。例如。.gitignore包含文件夹uploads和存储库被迫跟踪.gitkeep。通过从回购协议下删除所有内容,uploads也将删除它.gitkeep
Vladimir Vukanac '16

这个建议在Powershell中效果很好:git rm --cached $(git ls-files -i -X .gitignore)
geekandglitter

89

根据我在这里的答案: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

删除目录


@gaurav很高兴它有所帮助!
eirenaios


64

更通用的解决方案:

  1. 编辑.gitignore文件。

    ECHO mylogfile.log >> .gitignore

  2. 从索引中删除所有项目。

    git rm -r -f --cached .

  3. 重建索引。

    git add .

  4. 进行新的提交

    git commit -m "Removed mylogfile.log"


2
这实际上会删除文件吗?
Mr_and_Mrs_D 2013年

6
来自GitHub吗?没有。如果您已经推送到github,则不会将其从站点中删除。但是它将更新您的本地git存储库。
mAsT3RpEE 2013年

5
您删除的评论实际上被消除了很多:)解决方案的问题rm --cashed是,当一个下拉菜单成功时,它最终将删除该文件?人们说“从存储库中删除文件而不从本地文件系统中删除文件”时,这并不是人们想要的。现在,为什么上面接受的解决方案超出了我的范围?可能是OP独自工作并且从未退出过?不知道。我了解github上的“一劳永逸”的问题
Mr_and_Mrs_D 2013年

除非您询问github本身,否则我认为没有100%的解决方案。现在请坚持这一点。复制文件,添加到gitignore,执行实际的git rm -r,提交,推送,还原文件。您是否找到其他解决方案?
mAsT3RpEE 2013年

9
我的问题不是github-它是文件在拉时实际上会从同事那里删除。我希望该文件被删除。过去,这给我带来了很多问题。所以我想知道是否真的有一种解决方案确实删除文件。又见评论客栈接受的答案:stackoverflow.com/questions/1143796/...
Mr_and_Mrs_D

23

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

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

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

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


2
嗯,我这样做了,但是我发现如果其他人在仓库中对其进行了更改,则可以覆盖该文件。
AlxVallejo 2014年

16

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

git update-index --assume-unchanged  file_name_with_path

2
尽管这是一个很好的答案,但重要的是要注意,它不会“取消跟踪”文件,因为人们通常会在Git中使用该词,其中未跟踪的文件不在存储库历史中,而且从未被使用过。 。这个答案的作用是将文件保留在存储库中,但防止Git注意到已对其进行了更改。这有一些显着的差异-最重要的是,该文件对于其他人仍然存在,并且如果其他人对该文件进行了更改并且您将其拉出,则无需确认即可覆盖您的本地副本。
索伦·比约恩斯塔德

8

以上答案对我没有用。我曾经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

2
这种联合git rm -r --cached NAME是招将其从本地git仓库取出,防止它影响人谁后拉(通过删除GIT中的文件或目录的历史。)
notbad.jpeg

1
这将重写git历史记录,您需要在之后推--force,这与我猜到的问题有点超出范围。在公开的著名回购协议上,您不能像那样更改历史记录,因为每个已经克​​隆回购协议的人在提取时都会遇到问题。
纪尧姆·佩罗

0

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

注意:这不处理敏感信息的历史记录。

这个过程肯定需要对git进行一些了解。随着时间的流逝,我已经学会了执行以下过程:

1)忽略文件

  • 添加或更新项目.gitignore以忽略它们-在许多情况下(例如您的情况),父目录(例如log/将成为要使用的正则表达式)。
  • 提交并推送该.gitignore文件更改(不确定推送是否需要您注意,完成后不会造成伤害)。

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

  • 现在使用以下命令从git中删除文件(仅) git remove --cached some_dir/
  • 检查它们是否仍留在本地(应该!)。

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

  • git add .
  • git commit -m"removal"
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.