从git repo中删除'.git'目录?

时间:2013-05-29 18:48:49

标签: git mercurial git-filter-branch git-rewrite-history

我正在尝试将git repo从Kiln迁移到Github。我可以添加新的遥控器,但是当我尝试将主机推送到新的遥控器时,我收到以下错误:

Counting objects: 8691, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (3000/3000), done.
remote: error: object a9ee490ac00987835de30bdbc851da5e8d45d28b:contains '.git'
remote: fatal: Error in object
error: pack-objects died of signal 13
error: failed to push some refs to 'git@github.com:Account/repo.git'

提交a9ee490ac00987835de30bdbc851da5e8d45d28b包含以下文件:

.git/
CHANGELOG.md
JSONKit.h
JSONKit.m
README.md

显然,过去使用hg的人在子目录中检入完整的git仓库。

我想完全删除该目录,但是从git历史记录中删除该文件时遇到了问题。

pushing a git repo fails with error: contains '.git'中的答案没有用,因为我把回购作为git回购,而不是一个善变的回购。

我尝试git filter-branch --index-filter 'git rm -r --cached --ignore-unmatch .git',但收到错误:

Rewrite 7dbd0970d6c79215d11994b4a9b8091b2e954cfb (326/442)error: Invalid path 'Account/Libraries/ShareKit/Submodules/JSONKit/.git/HEAD'
error: Invalid path 'Account/Libraries/ShareKit/Submodules/JSONKit/.git/config'
error: Invalid path 'Account/Libraries/ShareKit/Submodules/JSONKit/.git/description'
error: Invalid path 'Account/Libraries/ShareKit/Submodules/JSONKit/.git/hooks/applypatch-msg.sample'
error: Invalid path 'Account/Libraries/ShareKit/Submodules/JSONKit/.git/hooks/commit-msg.sample'
error: Invalid path 'Account/Libraries/ShareKit/Submodules/JSONKit/.git/hooks/post-update.sample'
error: Invalid path 'Account/Libraries/ShareKit/Submodules/JSONKit/.git/hooks/pre-applypatch.sample'
error: Invalid path 'Account/Libraries/ShareKit/Submodules/JSONKit/.git/hooks/pre-commit.sample'
error: Invalid path 'Account/Libraries/ShareKit/Submodules/JSONKit/.git/hooks/pre-rebase.sample'
error: Invalid path 'Account/Libraries/ShareKit/Submodules/JSONKit/.git/hooks/prepare-commit-msg.sample'
error: Invalid path 'Account/Libraries/ShareKit/Submodules/JSONKit/.git/hooks/update.sample'
error: Invalid path 'Account/Libraries/ShareKit/Submodules/JSONKit/.git/index'
error: Invalid path 'Account/Libraries/ShareKit/Submodules/JSONKit/.git/info/exclude'
error: Invalid path 'Account/Libraries/ShareKit/Submodules/JSONKit/.git/logs/HEAD'
error: Invalid path 'Account/Libraries/ShareKit/Submodules/JSONKit/.git/logs/refs/heads/master'
error: Invalid path 'Account/Libraries/ShareKit/Submodules/JSONKit/.git/objects/pack/pack-43fac03d375df5c1e380c5e522ba6bcb9b4e1ec1.idx'
error: Invalid path 'Account/Libraries/ShareKit/Submodules/JSONKit/.git/objects/pack/pack-43fac03d375df5c1e380c5e522ba6bcb9b4e1ec1.pack'
error: Invalid path 'Account/Libraries/ShareKit/Submodules/JSONKit/.git/packed-refs'
error: Invalid path 'Account/Libraries/ShareKit/Submodules/JSONKit/.git/refs/heads/master'
error: Invalid path 'Account/Libraries/ShareKit/Submodules/JSONKit/.git/refs/remotes/origin/HEAD'

并且历史似乎没有改变。我正处于我的git知识极限。有人可以帮忙吗?

5 个答案:

答案 0 :(得分:33)

使用BFG Repo-Cleaner,这是git-filter-branch的一种更简单,更快捷的替代方案,专门用于从Git历史记录中删除文件。

请仔细按照此处的步骤进行操作:https://rtyley.github.io/bfg-repo-cleaner/#usage - 但核心位是:下载BFG jar(需要Java 6或更高版本)并运行此命令:

$ java -jar bfg.jar --delete-folders .git --delete-files .git --no-blob-protection my-repo.git

将扫描整个存储库历史记录,并删除名为.git的任何文件或文件夹。我已经针对包含.git文件夹的特殊构造的test repo对此进行了测试,它运行得很好。

感谢Michel Jouvin为reminding me提供的文件命名为' .git'在Git中也是非法的(Git报告的错误消息并没有立即显示他们文件,而不是文件夹),我已经更新了这个答案以反映

完全披露:我是BFG Repo-Cleaner的作者。

答案 1 :(得分:1)

您是否尝试过以下命令?

git filter-branch --tree-filter 'rm -Rf .git' HEAD

git filter-branch documentation表示这比--index-filter慢,但它可以完成这项工作。

答案 2 :(得分:0)

据我所知,窑现在可以让您将存储库克隆为git或Mercurial,因此将其克隆为mercurial,使用Mercurial repo 作为新存储库的mercurial filemap solution you already found推送到了Kiln,然后将其克隆为git。那么你将有一个git repo,你可以推送到github。

答案 3 :(得分:0)

处理Mercurial(Hg)存储库中嵌入.git文件夹的另一种方法是在导出到Git之前先“修复” Hg存储库。 @laurens-holsta great way of doing this

如果.git文件夹位于项目的根目录中,则您将创建一个文本文件my-filemap,如下所示:

exclude ".git"

在.hgrc文件中启用转换扩展名:

[extensions]
convert =

然后使用Hg转换扩展名过滤掉.git文件夹:

hg convert --filemap my-filemap originalrepo newrepo

现在您可以从newrepo导出,而不会出现嵌入式.git文件夹的问题。

您还可以使用git fsck来确保新的Git存储库在推送之前是可以的。

答案 4 :(得分:0)

从git 2.2.22开始,使用git-filter-repo工具即可完成此操作。

简单快捷:

git filter-repo --force --invert-paths --path-glob '*/.git' --path '.git'