如何将一个裸Git仓库转换成一个正常的(就地)?

我有一个纯粹的git仓库,但需要通过ssh访问和浏览其内容(在像用户体验的文件pipe理器中)。

我想我可以克隆它:

git clone -l <path_to_bare_repo> <new_normal_repo> 

但是,我的存储库大小约为20GB,我没有空间来复制它。 有没有办法将裸仓库就地转换成最终的工作副本?

注意 :我在一个非常简单的 1-commit存储库上testing了这个。 仔细检查这个,阅读手册页 ,并始终高兴你已经备份之前遵循你在StackOverflow发现的build议。 (你做备份吧?)

要将非存储库转换为非裸:

  1. 在存储库的顶层创build一个.git文件夹。
  2. 将仓库pipe理的东西( HEAD branches config description hooks info objects refs等)移动到您刚刚创build的.git
  3. 运行git config --local --bool core.bare false将本地git-repository转换为非裸机。
  4. (通过TamásPap的评论)在步骤#3之后,您将看到您在分支master (或主要分支)上,并且您的所有文件都将被删除,并且删除将被暂存。 这很正常。 只要手动检查master ,或做一个git reset --hard ,你就完成了。

这些步骤与这个问题相反,“git-convert normal to bare repository” – 特别注意这个答案 ,它指出上述步骤(在我假设的任一方向)与做git-clone 。 不知道这是否与你有关,但是你在提问中提到了git clone

我有一个稍微不同的情况:

  • 一个非回购( 通过github的tarball )
  • 需要从该内容恢复完整的回购。

解:

  • .git目录中克隆该内容中的裸回购:
    git clone --bare https://github.com/user/project .git
  • 将其标记为非裸回购:
    git config --local --bool core.bare false
  • 重置索引(否则,它认为一切已被删除,因为一个.git 回购不包括文件' index ')。
    git reset HEAD -- .
    恢复.git/index

我已经有效地将裸露的回购变成非裸回购,同时保留了我以前得到的内容。
我一直使用多年的完整脚本涉及以下步骤:

 cd /path/to/current/worktree # That creates a .git directly at the right place git clone --bare /url/of/repo .git # restore the link between the local repo and its upstream remote repo git config --local --bool core.bare false git config --local remote.origin.fetch +refs/heads/*:refs/remotes/origin/* git fetch origin git branch -u origin/master master # reset the index (not the working tree) git reset HEAD -- . 

但是我确实重新接受了解决scheme (使用ADTC 添加的有用的git reset步骤 )更简单。

如果磁盘空间不足,则通过转换为普通存储库来扩展工作树将成为问题,但您可以在不转换的情况下浏览裸回购的内容。 在任何提交上使用git cat-file -p <commit-sha>来查看它引用的树。 使用git cat-file -p <blob-sha>查看blob引用的文件的内容。 使用git show <sha>:path其中,sha是一个提交或一个树,以查看path中blob的内容。

为了简化和结合答案中的信息:

有两个区别使得裸回购不同于正常的.git文件夹:

  • core.bare在configuration文件中设置为true
  • 索引文件和工作树不存在

所以,你可以简单地将你的裸回购成为一个新文件夹的.git子文件夹,

 mkdir clone mv bare.git clone/.git 

更改core.bare:

 cd clone git config --local --bool core.bare false 

并生成索引文件和工作树:

 git checkout master 

我推荐git checkout而不是git reset来生成这些文件,以防万一它被意外地input到错误的地方。

原来的招贴画的问题是没有足够的空间来做简单的事情。 对于那些有足够空间的人来说,答案要简单得多:

 git clone foo.git foo 

如果你不介意在不同的工作树上工作,那么

 git worktree add ../repo2 cd .. git status # now works fine 

请注意,这不是一个克隆。