Git - 为什么“共享存储库应该是裸存储库”?这是过时的建议吗?

时间:2015-11-12 22:37:47

标签: git github

我是git和Github的新手。我已经学习了许多术语(推,拉,提交,分支等),但我将主要使用常用的说法来解释我最初的期望。

我认为这个过程是:

1.) Create a git repo out of my existing files.
2.) Copy those to my Github account to create a central "hub".
3.) Anyone who works on the project will check it out from Github, do work on their computers, then upload the changes to the hub.
4.) Anyone else working on the same branch can easily upload their changes as well, and will be warned if there are any conflicts. They can also easily download changes since their last download to update their local copy.

所以我做了第1步和第2步。然后我创建了一些分支。我做了一些提交并将更改推送到Github。我还在另一台机器上克隆了主分支,然后分支出来。我把新分支推到了Github。一切似乎都很好。但是现在,当我准备将其他开发人员添加到项目中时,我偶然发现了“中央”存储库应该“裸露”的警告。

Herehere(“不建议推入非裸存储库”),atlassian says“中央存储库应始终是裸存储库”,以及其他几个地方。显然,如果它不是裸露的,而其他人推送一个新文件,那么当我推送时,我的本地版本会认为自己删除了该文件。我最终会撤消其他开发人员的工作,这是我试图用git解决的问题!

这让我很担心,因为我已经用一堆文件设置了我的Github项目。我正准备找出将我的集线器转换为裸仓的方法,当我发现一些信息表明使用较新版本的Git时,你不需要在集线器上有一个裸存储库。我认为这与version 2.3更新了git push的行为有关。这是真的吗?为什么?

如果我的本地Windows机器有2.7版本,但另一台CentOS机器使用的是1.7.1,该怎么办?

3 个答案:

答案 0 :(得分:6)

非裸存储库的问题在于它们有一个签出分支,如果有人推送到那个分支,那么事情就变得奇怪了:工作副本和索引将在分支后面。这不应该发生在正常的工作流程中:想象如果在非裸主仓库中收到推送分支之后会发生什么,你会进行一行提交?您的提交实际上会回滚所有收到的更改,甚至不会向索引添加任何文件。

GitHub回购是裸的。虽然你可以看到文件和分支,但实际上并没有检出(你不能直接在github分支中提交!)。

答案 1 :(得分:3)

GitHub存储库总是裸露的,所以你无需担心。

建议仍然有效。版本2.3的更改与默认情况下推送的分支有关。

答案 2 :(得分:3)

我看到rodrigo has already given the right answer and the reason for it,但是考虑到问题("这是过时的")我想添加一些东西。它不是过时的建议(可能永远不会),但是git 已经添加了一个新的能力"开箱即用"原样:

  

receive.denyCurrentBranch
  [剪断]
  另一种选择是" updateInstead"这将更新工作    树如果推入当前分支。此选项是有意的    当一方不容易同步工作目录时    可以通过交互式ssh访问(例如,一个实时网站,因此    要求工作目录清洁)。这种模式也    在VM内部开发以测试和修复代码时派上用场    不同的操作系统。

换句话说,如果您有一个非裸存储库,您希望将用作存储库(不仅仅是原始部署)作为部署(但是没有编辑过的树,你现在可以这样做了。 1 自从git版本2.3以来,这已经存在,在版本2.4中有一个小修复 2

使用它的方法比人们在后接收挂钩中使用的花哨部署机制简单简单,因此保留完整存储库可能需要额外的空间成本。您只需克隆您希望树结束的存储库,检查您要在此部署的分支(或将-b添加到克隆命令),然后使用git config设置receive.denyCurrentBranchupdateInstead

$ git clone -b staging <url>
$ cd <repo>
$ git config receive.denyCurrentBranch updateInstead

现在,任何推送到此新克隆中的staging的人都会更新已签出的staging分支,前提是没有人接触它会导致它变得肮脏&#34;。

1 从技术上讲,通过将receive.denyCurrentBranch设置为false并编写一个后接收或更新挂钩&#34;做了正确的事情&#34,它始终是可能的。 34;,但它有点容易出错。

2 问题在于你现在可以推送到未出生的分支机构。也就是说,如果您执行git clone然后执行了git checkout -b来创建分支,但尚未对其进行提交,那么您现在可以使该分支成为a&#34;真正的分支&#34; 3 git push,只要满足剩余条件(清洁索引和工作树)。

3 一个新的但未出生的&#34; branch仅作为HEAD文件中的符号引用存在,而不是fill-refs文件中的refs/heads/<branch>文件或条目。这意味着如果你对另一个分支做另一个git checkout,那么未出生的分支就会消失,没有任何迹象表明它曾经存在过。在这个意义上,人们可能称之为“虚拟”和“虚拟”。分支,或者至少&#34;不太真实&#34;。