如何从Git仓库中删除文件?

2512

我该如何从我的代码仓库中删除"file1.txt" 文件?


116
git rm 是正确的答案,但请记住该文件仍然会留在历史记录中。 如果您希望删除一个包含敏感信息的文件,则需要采取更严厉的措施。(改变历史记录,尤其是对于您已经推送的内容,是一项激烈的行动,如果可能的话应该避免。) - Keith Thompson
11
注意:在GitHub上,您现在可以直接从Web界面中删除文件(甚至无需克隆存储库)。请参见下面的我的答案 - VonC
7
如果我非常想这样做,@KeithThompson 需要采取哪些步骤? - lessthanl0l
7
@lessthanl0l:https://dev59.com/questions/73NA5IYBdhLWcg3wrPyq - Keith Thompson
相关内容:https://help.github.com/articles/removing-sensitive-data-from-a-repository/ - Trevor Boyd Smith
显示剩余2条评论
27个回答

4193

使用git rm命令。

如果你想要从Git仓库和文件系统中删除该文件,请使用:

git rm file1.txt
git commit -m "remove file1.txt"

但如果你只想从Git仓库中删除文件而不是从文件系统中删除,可以使用:

git rm --cached file1.txt
git commit -m "remove file1.txt"

要推送更改到远程仓库

git push origin branch_name

154
还有一个方便的命令:git rm -r directory // 用于删除目录及其内容。 - Reg
18
这并不能彻底删除其他提交中的那个文件。 - VaTo
13
没问题。要从先前的提交中删除文件(改变过去的历史记录),请参阅GitHub的“删除敏感数据”帮助页面。链接:https://help.github.com/articles/remove-sensitive-data/ - Greg Hewgill
22
注意,这将同时删除本地文件。如果你只想从仓库中删除它,请执行以下操作:git rm --cached file1.txt。 - Weston Ganger
8
值得注意的是,如果该文件包含敏感信息(例如凭据),您应立即更改这些凭据。引用GitHub的话:“一旦您将提交推送到GitHub,您应将其包含的任何数据视为已受损。如果您提交了密码,请更改它!如果您提交了密钥,请生成一个新的。” - c1moore
显示剩余15条评论

659

git rm file.txt可以将文件从版本库中删除,但也会从本地文件系统中删除

要从版本库中删除文件,而不删除它们在本地文件系统中的副本,请使用:
git rm --cached file.txt

以下是我使用git来管理我的企业网站版本控制的确切情况,但“mickey”目录是一个tmp文件夹,用于与CAD开发人员共享私有内容。当他需要巨大的文件时,我创建了一个私人、未链接的目录,并通过浏览器ftpd文件供他提取。后来忘记了这一点,我从网站的基本目录执行了git add -A。随后,git status显示需要提交新文件。现在我需要从git的跟踪和版本控制中删除它们...

下面是我刚刚遇到的情况的示例输出,其中我无意中删除了.003文件。谢天谢地,我不关心.003的本地副本发生了什么,但其他一些当前更改的文件是我刚刚更新的网站,并且如果它们被删除了本地文件系统,那就太糟糕了!"本地文件系统"=实际的现场网站(不是很好的做法,但这是现实)

[~/www]$ git rm shop/mickey/mtt_flange_SCN.7z.003
error: 'shop/mickey/mtt_flange_SCN.7z.003' has local modifications
(use --cached to keep the file, or -f to force removal)
[~/www]$ git rm -f shop/mickey/mtt_flange_SCN.7z.003
rm 'shop/mickey/mtt_flange_SCN.7z.003'
[~/www]$ 
[~/www]$ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#   deleted:    shop/mickey/mtt_flange_SCN.7z.003
#
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#   modified:   shop/mickey/mtt_flange_SCN.7z.001
#   modified:   shop/mickey/mtt_flange_SCN.7z.002
[~/www]$ ls shop/mickey/mtt_flange_S*
shop/mickey/mtt_flange_SCN.7z.001  shop/mickey/mtt_flange_SCN.7z.002
[~/www]$ 
[~/www]$ 
[~/www]$ git rm --cached shop/mickey/mtt_flange_SCN.7z.002
rm 'shop/mickey/mtt_flange_SCN.7z.002'
[~/www]$ ls shop/mickey/mtt_flange_S*
shop/mickey/mtt_flange_SCN.7z.001  shop/mickey/mtt_flange_SCN.7z.002
[~/www]$ 
[~/www]$ 
[~/www]$ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#   deleted:    shop/mickey/mtt_flange_SCN.7z.002
#   deleted:    shop/mickey/mtt_flange_SCN.7z.003
#
# Changed but not updated:
#   modified:   shop/mickey/mtt_flange_SCN.7z.001
[~/www]$

更新:这个答案正在受到一些关注,所以我想提一下我的其他Git答案分享了一些很棒的资源:这个页面有一个图形可以帮助我解密Git。"Pro Git"书籍在线上对我也有很大帮助。


6
然后,您需要使用类似于 git commit -m "Just removing file1.txt" 的命令提交更改。如果您有一个远程代码库,那么您需要使用类似于 git push origin master 的命令将提交推送到该代码库中。 - ban-geoengineering

103

首先,如果你正在使用git rm,特别是对于多个文件,请注意任何通配符都将由shell解析,而不是git命令。

git rm -- *.anExtension
git commit -m "remove multiple files"

如果你的文件已经在GitHub上,自2013年7月以来你可以直接从Web GUI中删除它!

只需查看代码库中任何文件,在顶部点击垃圾桶图标,然后提交删除操作,就像进行任何其他基于Web的编辑一样。

然后在本地仓库中执行“git pull”,这也会将该文件从本地删除。
这使得这个答案成为了从git仓库中删除文件的(迂回)方法?
(更不用说GitHub上的文件已经在一个“git repo”中了)


delete button

(提交记录将反映删除该文件):

commit a deletion

就这样,它消失了。

如需了解有关这些功能的帮助,请务必阅读我们的帮助文章:创建移动重命名删除文件。

注意:由于它是一个版本控制系统,如果需要稍后恢复该文件,Git总会帮你的忙。

最后一句话意味着已删除的文件仍然是历史记录的一部分,您可以轻松地恢复它(但目前还不能通过GitHub Web界面实现):

请参见“在Git仓库中恢复已删除的文件”。


4
您需要向下滚动并点击“提交更改”以确认删除! - LevinsonTechnologies
1
这对于大型文本文件不起作用。服务器尝试呈现屏幕截图中的文件,然后失败并显示500错误。 - CapeCoder
12
这个回答是关于 GitHub 的,问题是关于 Git 存储库的。不是关于如何使用 GitHub 界面的。 - Peter Marshall
1
@Sergo,这样做并不能从以前的提交中删除文件。为此,请使用git-filter-repo,如此处所示。然后使用git push --force(因此请确保其他协作者知道您的新存储库历史记录)。 - VonC
1
@Sergo 好的,那就不用过滤仓库了。 - VonC
显示剩余2条评论

87

这是唯一对我奏效的选项。

git filter-branch -f --index-filter 'git rm --cached --ignore-unmatch *.sql'

注意:将*.sql替换为您的文件名或文件类型。请非常小心,因为这将遍历每个提交并删除此文件类型。

编辑: 注意 - 在运行此命令后,您将无法推送或拉取 - 您将看到'不相关历史记录'的拒绝消息,您可以使用'git push --force -u origin master'来推送或拉取。


15
这是一个很好的答案,但需要注意与其他答案不同的是,这个命令会重写提交历史并删除所有匹配模式的文件的痕迹。如果你发现自己无意中提交了一些敏感信息,这将特别有用(如果需要,可以使用 --force 成功地重写已推送到任何远程仓库的历史记录)。 - yoniLavi
3
我曾遇到的问题就是这个,需要一些尝试和错误才能解决。我与一个同事合作时,他将多个大型数据库转储提交到存储库中,涵盖了许多次提交。这就是我在示例中使用.sql的原因。我的存储库变得非常臃肿和庞大,以至于GitHub无法再接受推送。 - Jason Glisson
3
如果你正在使用远程主分支,你需要强制提交并通过 git push --force -u origin master 推送上去。 - AlbertMarkovski
2
@AlbertMarkovski 抱歉我没有说得太清楚。实际上,Github无法接受推送,因为存储库超出了其大小限制。至少有几个GB。他们切断了我的连接并通过电子邮件通知了我。因此,不幸的是,在那一点上,强制推送也无济于事。 - Jason Glisson
2
@JasonGlisson 我也遇到过这样的问题,即视频意外地被添加到了代码库中。 - AlbertMarkovski
显示剩余4条评论

42

此外,如果要删除一个文件夹及其所有子文件夹或文件,请使用:

git rm -r foldername

6
这将同时从本地删除该文件夹!请使用命令 git rm --cached -r <文件夹名称>。 - Axis

24

更一般地说,git help将帮助解决至少像这样简单的问题:

zhasper@berens:/media/Kindle/documents$ git help
usage: git [--version] [--exec-path[=GIT_EXEC_PATH]] [--html-path] [-p|--paginate|--no-pager] [--bare] [--git-dir=GIT_DIR] [--work-tree=GIT_WORK_TREE] [--help] COMMAND [ARGS]

The most commonly used git commands are:
   add        Add file contents to the index
   :
   rm         Remove files from the working tree and from the index

6
对于更复杂的事情,我发现git help很令人困惑,但对于简单的事情来说还是不错的 :) - James Polley
11
对于 Git 新手来说,“索引”并不是一个熟悉的概念,因此这个功能并不是他们所期望的那么好用。我是从自己作为 Git 新手的经验中得出这个结论的 :) 另外,我认为更好的表述方式是 rm 命令会将文件“标记为删除”,而不是“从索引中删除”(尽管对于新手来说这仍然没有意义)。 - Roman Starkov
同意romkyns的观点:描述“从工作树和索引中删除文件”对我来说听起来不像是一种从仓库中删除文件的方式。也许如果我更了解git,就会明白了。相反,它听起来像是你只是取消暂存文件(并可选择将其从工作树中删除——这是否必然会影响仓库?) - LarsH

17

Greg Hewgill的回答,被Johannchopin编辑过,对我很有帮助,因为我并不关心完全从历史记录中删除文件。 在我的情况下,它是一个目录,所以我做的唯一更改就是使用:

git rm -r --cached myDirectoryName

使用"git rm --cached file1.txt" 的替代方法是:

git commit -m "deleted myDirectoryName from git"
git push origin branch_name

感谢Greg HewgillJohannchopin


16
如果您想从仓库中删除文件,但在文件系统中保留它(将不会被跟踪):
bykov@gitserver:~/temp> git rm --cached file1.txt
bykov@gitserver:~/temp> git commit -m "remove file1.txt from the repo"

如果你希望从代码库和文件系统中删除文件,则有两个选项:

  1. 如果文件没有在索引中被暂存更改:

    bykov@gitserver:~/temp> git rm file1.txt
    bykov@gitserver:~/temp> git commit -m "remove file1.txt"
    
    如果文件在索引中有已暂存的更改:
  2. bykov@gitserver:~/temp> git rm -f file1.txt
    bykov@gitserver:~/temp> git commit -m "remove file1.txt"
    

15

git rm 命令只会从当前分支移除文件,但文件依然存在于历史记录中,Git 会记住它。

正确的做法是使用 git filter-branch,如其他回答所述。这将重写该分支历史上的每个提交以删除该文件。

但即使这样做了,Git 仍可记忆该文件,因为在 reflog、远程、标签等处可能仍有对它的引用。

如果您想一次性完全删除它,我建议您使用 git forget-blob

https://ownyourbits.com/2017/01/18/completely-remove-a-file-from-a-git-repository-with-git-forget-blob/

很容易,只需执行 git forget-blob file1.txt

这将删除所有引用、执行 git filter-branch,最后运行 Git 垃圾回收器 git gc 以彻底清除您 repo 中的此文件。


在2021年,我尝试过这个方法,但好像并没有起作用。我仍然可以看到文件的历史记录。相反,我最终使用git mv重命名了该文件,并清空了所有内容后提交了它。 - Harsha N Hegde
这是一次钓鱼攻击。请勿点击链接! - Marcin Chady

11
注意:如果您只想从Git中删除文件,请使用以下方法:
git rm --cached file1.txt

如果你想从硬盘中删除:

git rm file1.txt

如果您想删除一个包含少量文件的文件夹,您需要使用递归命令来删除,如下所示:

git rm -r foldername

如果你想删除另一个文件夹内的文件夹:
git rm -r parentFolder/childFolder

然后,您可以像往常一样提交(commit)推送(push)。但是,如果您想恢复已删除的文件夹,您可以按照以下步骤操作:从Git中恢复已删除的文件是可能的。

From doc:

git rm [-f | --force] [-n] [-r] [--cached] [--ignore-unmatch] [--quiet] [--] <file>…​

OPTIONS

<file>…​

Files to remove. Fileglobs (e.g. *.c) can be given to remove all matching files. If you want Git to expand file glob characters, you

may need to shell-escape them. A leading directory name (e.g. dir to remove dir/file1 and dir/file2) can be given to remove all files in the directory, and recursively all sub-directories, but this requires the -r option to be explicitly given. -f --force

Override the up-to-date check.

-n --dry-run

Don’t actually remove any file(s). Instead, just show if they exist in the index and would otherwise be removed by the command.

-r

Allow recursive removal when a leading directory name is given.

--

This option can be used to separate command-line options from the list of files, (useful when filenames might be mistaken for

command-line options). --cached

Use this option to unstage and remove paths only from the index. Working tree files, whether modified or not, will be left alone.

--ignore-unmatch

Exit with a zero status even if no files matched.

-q --quiet

git rm normally outputs one line (in the form of an rm command) for each file removed. This option suppresses that output.

点击阅读官方文档了解更多。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接