“git init”和“git init --bare”有什么区别?

时间:2011-10-22 17:08:05

标签: git version-control

git initgit init --bare之间的区别是什么?我发现很多博客帖子需要--bare用于他们的Git服务器?

来自the man page,它说:

--bare
     

创建一个裸存储库。如果未设置GIT_DIR环境,则将其设置为当前工作目录

但它究竟意味着什么?是否需要为Git服务器设置--bare

6 个答案:

答案 0 :(得分:129)

Non-Bare Git Repo

此变体创建一个包含工作目录的存储库,以便您可以实际工作(git clone)。创建它之后,您将看到该目录包含一个.git文件夹,其中包含历史记录和所有git管道。您在.git文件夹所在的级别工作。

Bare Git Repo

另一个变体创建一个没有工作目录(git clone --bare)的存储库。您没有获得可以工作的目录。现在,目录中的所有内容都是上述情况下.git文件夹中包含的内容。

为什么你会使用一个与另一个

对没有工作目录的git repos的需求是你可以将分支推送到它并且它不管理某人正在处理什么。你仍然可以推送到一个非裸露的存储库,但是你会被拒绝,因为你可能会移动某人在该工作目录中工作的分支。

所以在没有工作文件夹的项目中,你只能看到git存储它们的对象。它们被压缩和序列化并存储在其内容的SHA1(哈希)下。为了在裸存储库中获取对象,您需要git show然后指定要查看的对象的sha1。你不会看到像项目一样的结构。

裸存储库通常是中央存储库,每个人都将工作转移到其中。没有必要操纵实际的工作。这是一种在多人之间同步工作的方法。您将无法直接查看项目文件。

如果您是唯一一个从事该项目或者您不想/需要“逻辑中心”存储库的人,则可能不需要任何裸存储库。在这种情况下,人们更喜欢来自其他存储库的git pull 。这避免了git在推送到非裸存储库时出现的异议。

希望这有帮助

答案 1 :(得分:98)

简短回答

裸存储库是没有工作副本的git存储库,因此.git的内容是该目录的顶级存储库。

使用非裸存储库在本地工作,使用裸存储库作为中央服务器/集线器与其他人共享您的更改。例如,当您在github.com上创建存储库时,它将被创建为裸存储库。

所以,在你的电脑里:

git init
touch README
git add README
git commit -m "initial commit"

在服务器上:

cd /srv/git/project
git init --bare

然后在客户端上推送:

git push username@server:/srv/git/project master

然后,您可以通过将其添加为遥控器来保存自己的输入。

服务器端的存储库将通过pull和push获取提交,而不是由您编辑文件然后在服务器计算机中提交它们,因此它是一个裸存储库。

详细

您可以推送到不是裸存储库的存储库,git会发现那里有一个.git存储库,但由于大多数“hub”存储库不需要工作副本,因此使用它是裸的存储库,因为在这种存储库中有一个工作副本是没有意义的。

但是,如果你推送到非裸存储库,你正在使工作副本不一致,git会警告你:

remote: error: refusing to update checked out branch: refs/heads/master
remote: error: By default, updating the current branch in a non-bare repository
remote: error: is denied, because it will make the index and work tree inconsistent
remote: error: with what you pushed, and will require 'git reset --hard' to match
remote: error: the work tree to HEAD.
remote: error: 
remote: error: You can set 'receive.denyCurrentBranch' configuration variable to
remote: error: 'ignore' or 'warn' in the remote repository to allow pushing into
remote: error: its current branch; however, this is not recommended unless you
remote: error: arranged to update its work tree to match what you pushed in some
remote: error: other way.
remote: error: 
remote: error: To squelch this message and still keep the default behaviour, set
remote: error: 'receive.denyCurrentBranch' configuration variable to 'refuse'.

您可以跳过此警告。但推荐的设置是:使用非裸存储库在本地工作,使用裸存储库作为集线器或中央服务器来推送和拉出。

如果您想直接与其他开发人员的工作副本共享工作,您可以从彼此的存储库中取出而不是推送。

答案 2 :(得分:55)

前段时间,当我读到这个问题时,一切都让我感到困惑。我刚刚开始使用git,并且有这些工作副本(当时没有任何意义)。我将尝试从这个人的角度来解释这一点,他刚开始使用git而不知道术语。

差异的一个很好的例子可以通过以下方式描述

--bare只为您提供一个存储位置(您无法在那里开发)。如果没有--bare,它就可以在那里开发(并有一个存储位置)。

git init从当前目录创建一个git存储库。它在其中添加了.git文件夹,可以开始修改历史记录。

git init --bare也会创建一个存储库,但它没有工作目录。这意味着您无法编辑文件,提交更改,在该存储库中添加新文件。

--bare可以提供帮助吗?您和其他几个人正在开发该项目并使用git。您在某个服务器(amazon ec2)上托管了该项目。你们每个人都拥有自己的机器,并在ec2上推送你的代码。你们中没有人真正在ec2(你使用你的机器)上开发任何东西 - 你只需要推动你的代码。因此,您的ec2只是所有代码的存储空间,应该创建为--bare,所有机器都不会--bare(很可能只有一个,其他只会克隆所有代码)。工作流程如下所示:

enter image description here

答案 3 :(得分:13)

默认的Git存储库假定您将其用作工作目录。通常,当您在服务器上时,您不需要具有工作目录。只是存储库。在这种情况下,您应该使用--bare选项。

答案 4 :(得分:11)

非裸存储库是默认存储库。它是您运行git init时创建的内容,或者是从服务器克隆(没有bare选项)时获得的内容。

使用此类存储库时,您可以查看和编辑存储库中的所有文件。当您与存储库交互时 - 例如通过提交更改 - Git会将您的更改存储在名为.git的隐藏目录中。

当你有一个git服务器时,不需要有文件的工作副本。您所需要的只是存储在.git中的Git数据。裸存储库正是.git目录,没有用于修改和提交文件的工作区。

从服务器克隆时,Git在.git目录中拥有所需的所有信息,以创建工作副本。

答案 5 :(得分:1)

--bare和工作树存储库之间的另一个区别是,在第一种情况下,不存储丢失的提交,而仅存储属于分支轨道的提交。另一方面,工作树将永久保留所有提交。见下文...

我用git init --bare创建了第一个存储库(名称: git-bare )。是服务器。在左侧,没有远程分支,因为这是远程存储库本身。

我从第一个仓库创建了第二个存储库(名称: git-working-tree ),git clone。这是在右边。它具有链接到远程分支的本地分支。

(文本“第一”,“第二”,“第三”,“第四”,“ alpha”,“ beta”和“ delta”是提交注释。名称“ master”和“ greek”是分支名称)

Local and remote repositories

现在,我将删除 git-bare (命令:git push --delete origin greek)和本地 git-working-tree 中名为“ greek”的分支(命令:git branch -D greek)。这是树的样子:

The git-bare repository deletes what is no longer referenced

git-bare 存储库将删除分支和所有引用的comits。在图片中,我们看到它的树由于这个原因而被缩小。

另一方面,等同于常用本地存储库的 git-working-tree 存储库不会删除提交,该提交现在只能由您的哈希直接使用git checkout 7fa897b7命令。这就是为什么它的树没有修改的结构。

简要说明:提交从未在工作树存储库中删除,而是在 bare 存储库中删除。

实际上,您只能在服务器上已删除的分支(如果它存在于本地存储库中)进行恢复。

但是奇怪的是, bare 存储库的大小在删除远程分支后不会减小磁盘大小。也就是说,文件仍然以某种方式存在。要通过删除不再引用的内容或永远不能引用的内容(后一种情况)来转储存储库,请使用git gc --prune命令