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


162

git init和之间有什么区别git init --bare?我发现--bare他们的Git服务器需要很多博客文章?

手册页上说:

--bare

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

但这实际上是什么意思?需要--bare安装Git服务器吗?

Answers:


143

非裸Git回购

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

裸Git回购

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

为什么要使用一个与另一个

不需要工作目录就需要git repos的事实是,您可以将分支推送到该目录,并且它无法管理某人正在处理的内容。您仍然可以推送到一个光秃秃的存储库,但是您将被拒绝,因为您可能会移动某人正在该工作目录中工作的分支。

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

裸仓库通常是每个人都将工作转移到的中央仓库。无需操纵实际工作。这是在多个人之间同步工作的一种方式。您将无法直接看到您的项目文件。

如果您是唯一从事该项目的人,或者您不希望/不需要“逻辑上中央的”存储库,则可能不需要任何裸存储库。一个宁愿git pull 在这种情况下,其他存储库。这样可以避免git推送到非裸存储库时产生的异议。

希望这可以帮助


保留,抛出一个由该行- 人们可能会从其他的git喜欢拉 ... :-)
奥雅纳Rakshit

10
我发现这个答案非常不清楚和令人困惑。部分原因在这里:meta.stackoverflow.com/questions/339837/...
马尔科Avlijaš

Bare repositories are usually central repositories where everyone moves their work to.您是说一个裸仓库是其他项目合作者可以克隆项目的来源吗?也就是说,协作者将此视为remote
Minh Tran

111

简短答案

裸存储库是没有工作副本的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

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

服务器端的存储库将通过拉动和推送的方式来获取提交,而不是通过编辑文件然后在服务器计算机中进行提交来获取提交,因此它是一个裸存储库。

细节

您可以推送到不是裸存储库的存储库,并且git会发现那里有一个.git存储库,但是由于大多数“集线器”存储库不需要工作副本,因此通常使用裸存储库来进行并建议这样做,因为在这种存储库中没有工作副本是没有意义的。

但是,如果您推送到非裸仓库,则会使工作副本不一致,并且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'.

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

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


如果我想在git服务器上工作我的项目,那么就没有必要使用--bare选项,不是吗?
Kit Ho

您将bare用于远程存储库,而不用于本地存储库。
邓肯,

有一段时间,但这是另一个问题。如果我们有一个裸露的远程存储库,那么任何开发人员都可以对其进行推送,而该存储库就是“中央”存储库。但是,如果我们在没有裸仓库的情况下工作,那么开发人员应该只能相互拉动,而绝不能相互推挤。如果只有两个工作回购(也就是本地回购)的工作副本,则最后一种情况就很好。这样对吗?
阿斯图里奥

60

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

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

--bare只给您一个存储空间(您不能在那里开发)。没有--bare它,您将有能力在那里开发(并拥有一个存储位置)。

git init从当前目录创建一个git存储库。它在其中添加.git文件夹,并可以启动您的修订历史记录。

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

什么时候--bare可以提供帮助?您和其他几个人正在从事该项目并使用git。您将项目托管在某个服务器(amazon ec2)上。每个人都有自己的机器,然后将代码推送到ec2。没人真正在ec2(使用机器)上开发任何东西-只需推送代码即可。因此,您ec2只是所有代码的存储空间,应该在--bare没有任何代码的情况下将其创建为和所有计算机都创建--bare(很可能只有一个,而其他机器只会克隆所有内容)。工作流程如下所示:

在此处输入图片说明


1
因此,我们可以说,通过使用--bare存储库,我们可以像创建Subversion一样创建一种客户端-服务器体系结构?
Emiliano Sangoi 2015年

14

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


在带有--bare选项的回购中,因此我们看不到所有项目文件?看来,我失去与--bare选项我所有的项目文件..
包浩

11

默认为非裸存储库。它是您在运行时创建的git init,或者是bare从服务器克隆(不带该选项)时所获得的。

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

如果您有git服务器,则不需要文件的工作副本。您只需要存储在中的Git数据即可.git。裸存储库正是.git目录,没有用于修改和提交文件的工作区。

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


1

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

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

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

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

本地和远程存储库

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

git-bare存储库删除不再引用的内容

混帐裸仓库同时删除分支和所有引用comits。在图片中,我们看到它的树由于这个原因而被缩小。

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

简介:提交从未在工作树存储库中删除,而是在以下位置删除存储库。

实际上,仅当服务器上已删除的分支存在于本地存储库中时,您才能恢复该分支。

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


要测试git命令,请尝试:github.com/sergiocabral/App.GitPlayground
Sergio Cabral,
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.