git,如何使用git hooks删除大文件

时间:2016-07-20 14:01:29

标签: git

我在一个月前愚蠢地检查了一个200 + M无用文件到我的仓库,现在我的所有同事(国际)现在都有大文件。我想知道是否有一种很好的方法可以使用git hooks透明地清除这个大文件。

我可以在git hook中使用bfg或git filter-branch删除大文件,但之后似乎需要强制推送,这对repo来说是有风险的。这里有没有人这样做过,整个工作流程和配置是什么样的?

比使用git hook更好吗?

提前致谢!

3 个答案:

答案 0 :(得分:2)

简单的答案是否定的,如果没有每个人的共同努力,就没有办法重写历史。服务器端挂钩不会修改其本地克隆。无论你是否可以使用客户端钩子自动化任何东西,你都不应该这样做。您必须处理每个可能的更新未经删除的本地更改和额外分支等情况。

最重要的是,每个人都必须将他们的本地存储库更新为一个全新的树(至少从引入文件的提交开始,以及随后的所有内容)。一个200 MB的文件很烦人,但它可能并不像每个人都必须重写本地历史记录来删除它一样烦人。如果您不能单独跟踪每个团队成员,那么就没有安全性,并且它实际上并没有导致阻塞问题(例如,回购现在超出了您的主机的大小限制,你可能只是提交一个文件删除(所以它不再在磁盘上检查)并保留历史记录。

如果引入它的提交最近非常,您可以考虑创建一个新分支,但前提是您可以让每个人无缝切换到它。这听起来不像你的问题。

另一种选择是,如果您可以在修改历史记录后让每个人都克隆 new repo。但这需要每个人将他们的更改移植到回购的新副本。

答案 1 :(得分:1)

更改历史记录带来了很多痛苦,您可以通过以下几种方法使用public class StructureMapFilterProvider : FilterAttributeFilterProvider { public override IEnumerable<Filter> GetFilters(ControllerContext controllerContext, ActionDescriptor actionDescriptor) { var filters = base.GetFilters(controllerContext, actionDescriptor); foreach (var filter in filters) { MvcApplication.StructureMapDependencyScope.CurrentNestedContainer.BuildUp(filter.Instance); } return filters; } }

从历史记录中删除该文件

注意:每个人都需要更新自己的工作以反映修改后的更改

git filter-branch

在上面将git filter-branch --tree-filter "rm -f yourfilename.ext" -- --all替换为您的文件,例如yourfilename.ext这样做会通过您的仓库中的每个提交进行,并删除文件tutorial.mp4

yourfilename.ext将确保应用的命令将遍历所有分支。

或者,您可以使用-- --all来运行类似的命令。它的作用是通过工作目录而不是检查每个提交,它将在暂存区域执行繁重的工作(只执行命令而不检查提交的内容)。这种方法可以更快。

--index-filter

如前所述,只需确保将git filter-branch --index-filter "git rm --cached --ignore-unmatch filename.ext" -- --all 替换为您的文件名+扩展名。

希望有所帮助

答案 2 :(得分:1)

如果你想去钩子的路线,有https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks所描述的服务器端钩子。您可能会尝试使用这些来检查推送的提交并验证旧的大文件不存在于那里。查看.git / hooks / update.sample文件。 Chacon在他的书中也有很好的写作,见https://git-scm.com/book/en/v2/Customizing-Git-An-Example-Git-Enforced-Policy

鉴于其他人都在说什么,似乎你不能保证人们不会搞砸你并重新压缩文件(或其他一些大文件),所以钩子将是唯一可以防止这种情况发生的保险进入你的回购