使用时
git rm --cached myfile
它不会从本地文件系统中删除,这是目标。但是,如果您已经对文件进行了版本控制和提交,将其推送到中央存储库,然后再将其拉入另一个存储库,则在使用该命令之前,它将从该系统中删除该文件。
有没有一种方法可以仅从版本控制中删除文件而不从任何文件系统中删除它?
编辑:澄清,我希望。
使用时
git rm --cached myfile
它不会从本地文件系统中删除,这是目标。但是,如果您已经对文件进行了版本控制和提交,将其推送到中央存储库,然后再将其拉入另一个存储库,则在使用该命令之前,它将从该系统中删除该文件。
有没有一种方法可以仅从版本控制中删除文件而不从任何文件系统中删除它?
编辑:澄清,我希望。
Answers:
我认为Git提交不会记录“停止跟踪此文件,但不要删除它”之类的意图。
要实现这样的意图,将需要在Git之外对合并(或基于)删除该文件的提交的任何存储库进行干预。
可能最简单的方法是告诉您的下游用户保存文件的副本,撤消删除,然后还原文件。如果它们通过重新设置拉动并且正在“修改”文件,则它们将发生冲突。要解决此类冲突,请使用git rm foo.conf && git rebase --continue
(如果冲突的提交除了对已删除文件所做的更改之外),或者git rebase --skip
(如果冲突的提交仅对已删除文件进行了更改)。
如果他们已经撤消了删除提交,他们仍然可以使用git show恢复文件的先前版本:
git show @{1}:foo.conf >foo.conf
或使用git checkout(William Pursell的每条评论;但请记住将其从索引中删除!):
git checkout @{1} -- foo.conf && git rm --cached foo.conf
如果他们在撤消删除操作之后采取了其他措施(或者正在将rebase撤消到分离的HEAD中),则他们可能需要@{1}
。他们可以git log -g
在删除您的删除之前找到提交。
在评论中,您提到您要“取消跟踪但保留”的文件是运行软件(直接在存储库外)所需的某种配置文件。
如果并非完全不能继续在存储库中保留配置文件的内容,则可以将跟踪的文件从(例如)重命名foo.conf
为foo.conf.default
,然后cp foo.conf.default foo.conf
在应用重命名提交后指示用户进行操作。或者,如果用户已经使用存储库的某些现有部分(例如脚本或由存储库中的内容配置的其他程序(例如Makefile
,类似文件))启动/部署软件,则可以将默认机制纳入启动/部署中。部署过程:
test -f foo.conf || test -f foo.conf.default &&
cp foo.conf.default foo.conf
有了这样的默认机制,用户应该能够提取重命名foo.conf
为的提交,foo.conf.default
而无需执行任何额外的工作。另外,如果以后再进行其他安装/存储库,则可以避免手动复制配置文件。
如果将信息内容保存在存储库中是不可接受的,那么您可能会想使用诸如之类的东西彻底消除历史记录中的内容git filter-branch --index-filter …
。这相当于重写历史记录,需要对每个分支/存储库进行手动干预(请参见git rebase联机帮助页中的“从上游资源恢复” )。配置文件所需的特殊处理只是从重写中恢复时必须执行的另一步骤:
无论使用哪种方法,您都可能希望将配置文件名.gitignore
包含在存储库中的文件中,以使任何人都不会git add foo.conf
再次疏忽(可能,但是需要-f
/ --force
)。如果您有多个配置文件,则可以考虑将它们全部“移动”到一个目录中,而忽略整个内容(“移动”是指更改程序期望找到其配置文件的位置,并获取用户(或(启动/部署机制)以将文件复制/移动到其新位置;您显然不希望将文件git mv到要忽略的目录中。
--{,no-}assume-unchanged
纯粹是局部的:其状态未直接记录在提交中。它可以帮助防止存储库将新的更改提交到文件,但不会将其从版本控制中删除。如果您可以为所有相关的相关非裸存储库设置它,那么它可能会帮助您解决问题,但是您不能直接将+推拉/重新设置到其他相关的非裸存储库中(尤其是那些根据原始问询者对问题的澄清评论,您无法控制:请参阅“人民制度” /“外国制度”)。
I do not think a Git commit can record an intention like “stop tracking this file, but do not delete it”.
-现在可以了git rm --cached foo.conf
当我意外提交时,本周发生了同样的问题,然后尝试从共享存储库中删除构建文件,并且:
http://gitready.com/intermediate/2009/02/18/temporarily-ignoring-files.html
对我来说很好,到目前为止没有提及。
git update-index --assume-unchanged <file>
要从版本控制中删除您感兴趣的文件,然后照常使用所有其他命令。
git update-index --no-assume-unchanged <file>
如果您想放回去。
编辑:请查看Chris Johnsen和KPM的评论,该评论仅在本地有效,如果其他用户也没有这样做,则该文件仍受其他用户的版本控制。接受的答案提供了更完整/正确的方法来处理此问题。如果使用此方法,还可以从链接中获得一些注意事项:
显然,对此有很多注意事项。如果您直接git添加文件,它将被添加到索引中。合并带有此标志的提交将导致合并失败,因此您可以手动进行处理。
要从索引中删除文件,请使用:
git reset myfile
这不应影响您的本地副本或任何其他人的副本。
reset
仅在文件不在当前HEAD提交中时才从索引中删除文件,否则只会将索引版本还原为当前HEAD版本。
git rm --cached remove_file
git add .gitignore
git commit -m "Excluding"
上述解决方案在大多数情况下都可以正常工作。但是,如果您还需要删除该文件的所有痕迹(例如,敏感数据,例如密码),您也将希望从整个提交历史记录中删除它,因为仍然可以从该文件中检索该文件。
这是一个解决方案,可以从整个提交历史记录中删除文件的所有痕迹(好像它从未存在过),但仍将文件保留在系统中。
https://help.github.com/articles/remove-sensitive-data/
如果您位于本地git存储库中,则实际上可以跳至步骤3,而无需执行空运行。就我而言,我只需要第3步和第6步,因为我已经创建了.gitignore文件,并且位于我要处理的存储库中。
要查看您的更改,您可能需要转到存储库的GitHub根目录并刷新页面。然后,通过链接导航到曾经拥有该文件的旧提交,以查看该文件已被删除。对我来说,仅刷新旧的提交页面并没有显示更改。
一开始它看起来很吓人,但实际上很简单,而且就像一个魅力一样起作用!:-)