将目录添加到.gitignore后,从远程存储库中删除目录


596

我提交并推送了一些目录到github。在那之后,我修改了.gitignore文件,添加了应该忽略的目录。一切正常,但是(现在已忽略)目录保留在github上。

如何从github和存储库历史记录中删除该目录?


Answers:


1062

.gitignore文件中的规则仅适用于未跟踪的文件。由于该目录下的文件已在您的存储库中提交,因此您必须取消暂存它们,创建提交并将其推送到GitHub:

git rm -r --cached some-directory
git commit -m 'Remove the now ignored directory "some-directory"'
git push origin master

您不能在不重写存储库历史记录的情况下从历史记录中删除文件-如果其他人正在使用您的存储库,或者您正在多台计算机上使用它,则不应这样做。如果您仍然想这样做,可以git filter-branch用来重写历史记录- 这里有一个有用的指南

另外,请注意来自的输出git rm -r --cached some-directory将类似于:

rm 'some-directory/product/cache/1/small_image/130x130/small_image.jpg'
rm 'some-directory/product/cache/1/small_image/135x/small_image.jpg'
rm 'some-directory/.htaccess'
rm 'some-directory/logo.jpg'

rm是有关存储库git的反馈; 文件仍在工作目录中。


3
如果其他人拉动,会为他们删除现在忽略的文件还是保持原状?
Martin Konicek 2012年

3
@Martin Konicek:如果拉动那些更改的用户对这些文件没有修改,则它们将被删除。
Mark Longair 2012年

@MarkLongair是什么-r--cached。谢谢。
Labanino

12
@Labanino:-r表示递归,如果要执行整个目录,则必须使用。--cached覆盖git从工作目录中删除它们并将其暂存进行提交的常规行为,并使git仅在准备提交的暂存区域上操作。这是告诉git您要保留文件的本地副本的方式。
entheh

2
这工作不错,但我必须首先做:git reset name_of_file对于什么是上述工作
爱德华·格兰

248

我这样做:

git rm --cached `git ls-files -i --exclude-from=.gitignore` 
git commit -m 'Removed all files that are in the .gitignore' 
git push origin master

这将删除git忽略中的所有文件/文件夹,省去了手动选择每个文件/文件夹的麻烦


这似乎已停止为我工作,我现在这样做:

 git rm -r --cached . 
 git add .
 git commit -m 'Removed all files that are in the .gitignore' 
 git push origin master

4
谢谢,这对我有很大帮助!如果您使用Windows Powershell,可以执行foreach ($i in iex 'git ls-files -i --exclude-from=.gitignore') { git rm --cached $i }
Matthew

10
尝试了第二种方法,它从本地git中删除了所有文件!
artnikpro

2
我认为您应该导航到该子目录并执行该操作。如我错了请纠正我。

那么,孩子们,我们今天学到了什么?“不要运行在堆栈溢出中找到的随机代码!”
乔纳森·兰德鲁姆

49

按照我在这里的答案:如何从git存储库中删除目录?

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


删除目录的步骤

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

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

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

.gitignore文件将如下所示

/FolderName

删除目录


1
这正是我想要的。谢谢:)
罗希特·辛格

我很高兴它对@Rohit Singh
有所

9

布伦德尔的第一个答案对我不起作用。但是,它向我展示了正确的方法。我做过同样的事情:

> for i in `git ls-files -i --exclude-from=.gitignore`; do git rm --cached $i; done
> git commit -m 'Removed all files that are in the .gitignore'
> git push origin master

我建议您先运行以下语句来检查要删除的文件:

git ls-files -i --exclude-from=.gitignore

我在Visual Studio中使用默认的.gitignore文件,但我注意到它正在删除项目中的所有日志和bin文件夹,这不是我的预期操作。


5

注意:此解决方案仅适用于Github Desktop GUI

通过使用Github Desktop GUI,它非常简单。

  1. 临时将文件夹移到另一个位置(移出项目文件夹)。

  2. 编辑.gitignore文件并删除文件夹条目,该条目将在github页面上删除主存储库。

  3. 提交并同步项目文件夹。

  4. 将文件夹重新移到项目文件夹中

  5. 重新编辑.gitignore文件。

就这样。


5

布伦德尔的答案应该起作用,但出于某些奇怪的原因,它与我无关。我必须先将第一个命令输出的文件名通过管道传送到文件中,然后遍历该文件并逐个删除该文件。

git ls-files -i --exclude-from=.gitignore > to_remove.txt
while read line; do `git rm -r --cached "$line"`; done < to_remove.txt
rm to_remove.txt
git commit -m 'Removed all files that are in the .gitignore' 
git push origin master

4

此方法应用标准的.gitignore行为,不需要手动指定需要忽略的文件

不能再使用--exclude-from=.gitignore了:/-这是更新的方法:

一般建议:从干净的仓库开始 -提交的所有东西,工作目录或索引中没有待处理的东西,然后进行备份

#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

如果您还需要从分支的提交历史记录中清除新忽略的文件,或者您不希望从以后的请求中删除新忽略的文件,请参见此答案


0

如果您使用的是PowerShell,请尝试以下命令作为单个命令。

PS MyRepo> git filter-branch --force --index-filter
>> "git rm --cached --ignore-unmatch -r .\\\path\\\to\\\directory"
>> --prune-empty --tag-name-filter cat -- --all

然后,git push --force --all

文档:https : //git-scm.com/docs/git-filter-branch


使用git filter-branch与使用git rm有何不同?我本来以为我必须使用的版本,git filter-branch但此处的大多数评论建议使用git rm。据我了解,git rm只能将其从当前工作目录和索引中删除。但是,如果之前添加了多个提交,它将仍在存储库中。
alpha_989 '18

对。git rm将从将来的最新提交中删除该文件。git filter-branch让我们将其从整个历史记录中删除。参见:help.github.com/articles/...
肖恩Luttin
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.