应用 .gitignore 到已提交的文件

600

我已经提交了很多文件,现在想要忽略它们。我该如何告诉git在以后的提交中忽略这些文件?

编辑:我确实想从仓库中删除它们。它们是每次构建后创建的文件或用于特定用户工具支持的文件。


2
可能是重复的问题:.gitignore文件没有忽略 - Wooble
8
答案可能类似,但这个问题正好描述了我当时面临的问题并需要解决。 - rjmunro
1
这是直接回答标题问题并对您的git repo进行最小更改的答案:https://dev59.com/9msz5IYBdhLWcg3w-89v#26245961 - kayleeFrye_onDeck
11个回答

712

在编辑.gitignore以匹配被忽略的文件后,您可以执行git ls-files -ci --exclude-standard来查看包含在排除列表中的文件。然后您可以执行以下操作:

  • Linux/MacOS:git ls-files -ci --exclude-standard -z | xargs -0 git rm --cached
  • Windows(PowerShell):git ls-files -ci --exclude-standard | % { git rm --cached "$_" }
  • Windows(cmd.exe):for /F "tokens=*" %a in ('git ls-files -ci --exclude-standard') do @git rm --cached "%a"

以将它们从仓库中删除(而不从磁盘上删除)。

编辑: 您还可以将此设置为别名添加到您的.gitconfig文件中,以便随时运行。只需在 [alias] 部分下添加以下行(根据需要修改 Windows 或 Mac):

apply-gitignore = !git ls-files -ci --exclude-standard -z | xargs -0 git rm --cached

xargs 中的 -r 标志可以防止在结果为空并打印其使用消息时运行 git rm,但仅可能由 GNU findutils 支持。其他版本的 xargs 可能具有类似的选项。)

现在,您只需要在您的存储库中键入 git apply-gitignore,它就会为您完成工作!


10
我认为Mac上的xargs命令没有-r选项,或者我的版本有问题/过时了,我不确定。为什么在git命令前要加上!呢?好吧,我的命令是这样的:alias apply-gitignore="git ls-files -ci --exclude-standard -z | xargs -0 git rm --cached",谢谢! - Felipe Sabino
20
在Windows上运行for /F "tokens=*" %a in ('git ls-files -ci --exclude-standard') do @git rm --cached "%a"的命令,它会列出当前Git存储库中未被忽略的所有文件,并从缓存区中删除它们。 - Luke Puplett
@Hippyjim,如果文件已经被提交(即使它们在.gitignore中被列出),而且.gitignore还没有被提交,那么这将是预期的结果,否则,在你的情况下我不确定发生了什么。 - Jonathan Callen
1
运行得非常完美,非常感谢! - Rixhers Ajazi
1
对于Mac用户来说,-r是默认的,并且不被BSD版本所接受。因此,请删除-r - Weishi Z
显示剩余11条评论

627

20
有很多文件需要处理,我不想为每一个都重复这个过程。 - user880954
1
文件是否在任何常见目录中?如果不是,则问题减少为一个shell使用问题,而不是git问题。 - Matt Ball
15
需要有一个“我忘记在提交初版之前添加.gitignore文件”的模式。 - Luke Puplett
1
我忘记在初始提交之后添加我的.gitignore文件了。下面的帖子是答案。它有效! - unom
4
它要求我添加-r标志才能这样做。 - Peter
显示剩余2条评论

207

将文件保留在存储库中,但忽略对其的未来更改:

git update-index --assume-unchanged <file>

要撤消此操作:

git update-index --no-assume-unchanged <file>

要找出哪些文件已经被设置为这种方式:

git ls-files -v|grep '^h'

感谢http://blog.pagebakers.nl/2009/01/29/git-ignoring-changes-in-tracked-files/提供的原始答案。

如果你想忽略已经被Git跟踪的文件中的更改,可以使用以下命令:

git update-index --assume-unchanged <file>

要取消此忽略并再次跟踪更改,请使用以下命令:

git update-index --no-assume-unchanged <file>

1
Chronial为在目录中递归执行此操作提供了一个很好的答案:https://dev59.com/zWQo5IYBdhLWcg3wE74J#16346756 - alana314
1
我想提交一个IDE配置,但不跟踪不必要的更改。 这个方法可行,但我不确定其他检出存储库的人是否也能使用它。 如果有帮助的话,可以与git ls-files -ci --exclude-standard -z | xargs -0 git update-index --assume-unchanged结合使用。 - dlamblin
18
这是唯一的答案完全符合标题问题的要求。完美!大多数其他答案都不必要地纠缠于文件中。 - kayleeFrye_onDeck
1
这是问题的确切答案。使用像 git rm --cached 这样的命令将会从代码库中删除文件,这并不符合测验者的需求。非常感谢你的回答,它对我帮助很大。谢谢。 - ramwin
在Windows上,最后一个命令将grep替换为findstr以获得相同的结果。 git ls-files -v | findstr '^h' - MattyMatt

203

确保你的实际代码库是最新版本且没有进行中的更改

  1. 按你的意愿编辑 .gitignore
  2. git rm -r --cached .(删除所有文件)
  3. git add .(根据 gitignore 重新添加所有文件)

然后像往常一样提交(commit)


34
这应该是被接受的答案,因为问题明确指出有很多文件需要删除。 - nbeuchat
4
请注意,如果您的存储库很大,第二步可能需要一段时间。 - brainbag
3
这导致从索引中移除了所有文件!这里的命令可以帮助你恢复:git reset HEAD(记得隐藏任何更改)。 - aksh1618
4
第二步会删除所有内容,但第三步应该将它们全部重新添加,除了由于.gitignore 失败的内容。 - ojchase
这个完美地运作。 - Blues Clues
这个完美地运作。 - undefined

12

虽然这是一个老问题,但是我们中的一些人使用的是git-posh(powershell),这是解决该问题的方法:

git ls-files -ci --exclude-standard | foreach { git rm --cached $_ }

2
  1. 将您的文件名/文件路径添加到.gitignore文件中。
  2. 现在在git bash中运行命令git rm --cached file/path/from/root/folder
  3. 现在使用git commit提交您的代码。

现在,该文件不应在git status命令中被跟踪。


1

编辑 .gitignore 文件后。

git rm -r --cached ./ &&  git add ./ && git commit -a -m "Removing ignored files" && git push

1

我经常会忘记或者懒得去读这些git命令的作用。所以我会像这样做:

  • 我将所有想要忽略的文件暂时移出仓库
  • 我在我的git GUI中提交这些“已删除的文件”(它们现在是未跟踪的)
  • 我更新.gitignore文件
  • 我将文件移回到仓库中(或者如果那是我的意图,就将它们删除)

0

如果您已经提交了,可以使用以下方法:

  1. 将文件夹路径添加到.gitignore文件中。
  2. 运行此命令以删除exe文件(对于其他文件扩展名,只需写“*扩展名”)。 git rm --cached *exe
  3. 提交更改。

您应该为要删除的每个扩展名执行此操作。


0
如果您要 git rm 很多文件(比如 100k),本帖中的答案可以通过分批处理文件列表(通过 git ls-files -ci --exclude-standard 生成)来改进。 (据我所知,由于其索引锁定机制,Git 不支持并行处理。)
PowerShell 中分批处理的示例:
$files = git ls-files -ci --exclude-standard
$batchSize = 100

for ($i = 0; $i -lt $files.Count; $i += $batchSize) {
    $batch = $files[$i..($i + $batchSize - 1)]
    git rm -f --cached $batch
}

在Windows上,$batchSize的上限是命令行长度的限制。对于较短的路径,您可以使用更大的$batchSize

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