Bare和非Bare存储库之间的实际区别是什么?

时间:2011-04-04 15:38:42

标签: git repository git-bare

我一直在阅读Git中的裸机和非裸机/默认存储库。我无法理解(理论上)它们之间的差异,以及为什么我应该“推”到一个裸存储库。这是交易:

目前,我是唯一一个在3台不同计算机上进行项目的人,但稍后会有更多人参与其中,所以我使用Git进行版本控制。我在所有计算机上克隆了裸仓库,当我在其中一台计算机上完成修改后,我提交并将更改推送到裸仓库。根据我的阅读,裸存储库没有“工作树”,所以如果我克隆裸存储库,我将没有“工作树”。

我猜测工作树存储项目中的提交信息,分支等。这不会出现在裸仓库中。因此,对于我来说,使用工作树将提交“推送”到repo似乎更好。

然后,为什么我应该使用裸存储库,为什么不呢?实际的差异是什么?我认为这对于更多从事项目的人来说并没有好处。

这种工作的方法是什么?建议?

11 个答案:

答案 0 :(得分:82)

裸存储库和非裸存储库之间的另一个区别是裸存储库没有默认的远程存储库:

~/Projects$ git clone --bare test bare
Initialized empty Git repository in /home/derek/Projects/bare/
~/Projects$ cd bare
~/Projects/bare$ git branch -a
* master
~/Projects/bare$ cd ..
~/Projects$ git clone test non-bare
Initialized empty Git repository in /home/derek/Projects/non-bare/.git/
~/Projects$ cd non-bare
~/Projects/non-bare$ git branch -a
* master
  remotes/origin/HEAD -> origin/master
  remotes/origin/master

来自git clone --bare的手册页:

  

此外,分支机构也在遥控器上   被直接复制到相应的   当地分公司负责人,没有映射   他们来refs /遥控/起源/。什么时候   此选项均未使用   远程跟踪分支也不是   相关的配置变量是   创建

据推测,当它创建一个裸存储库时,Git假定裸存储库将作为几个远程用户的源存储库,因此它不会创建默认的远程源。这意味着基本git pullgit push操作将无法工作,因为Git假设没有工作空间,您不打算对裸存储库进行任何更改:

~/Projects/bare$ git push
fatal: No destination configured to push to.
~/Projects/bare$ git pull
fatal: /usr/lib/git-core/git-pull cannot be used without a working tree.
~/Projects/bare$ 

答案 1 :(得分:53)

裸露和非裸露Git存储库之间的区别是人为的和误导性的,因为工作空间不是存储库的一部分,存储库不需要工作空间。严格地说,Git存储库包括描述存储库状态的那些对象。这些对象可能存在于任何目录中,但通常存在于工作空间顶级目录的.git目录中。工作空间是一个目录树,表示存储库中的特定提交,但它可能存在于任何目录中或根本不存在。环境变量$GIT_DIR将工作空间链接到它所源自的存储库。

Git命令git clonegit init都有选项--bare,它们创建没有初始工作空间的存储库。不幸的是,Git将两个独立但相关的工作空间和存储库概念混为一谈,然后使用混淆的术语 bare 来分离这两个想法。

答案 2 :(得分:48)

裸存储库只是 .git 文件夹本身,即裸存储库的内容与本地工作存储库中 .git 文件夹的内容相同。

  • 在远程服务器上使用裸存储库,以允许多个贡献者推动他们的工作。
  • 非裸 - 具有工作树的那个在您项目的每个贡献者的本地机器上都有意义。

答案 3 :(得分:38)

我知道,已经晚了5年,但实际上没有人回答这个问题:

  

然后,我为什么要使用裸存储库,为什么不呢?什么是   实际差异?这对更多人没有好处   我想,在一个项目上工作。

     

这种工作的方法是什么?建议?

直接引用Loeliger / MCullough书(978-1-449-31638-9,p196 / 7):

  

裸存储库似乎没什么用处,但它的作用是   至关重要:作为协作的权威焦点   发展。来自裸露的其他开发者clonefetch   存储库和push更新它...如果您设置存储库   哪些开发人员push发生了变化,应该是裸露的。实际上,这是   一个特殊的案例,更公正的最佳实践,发表   存储库应该是裸露的。

答案 4 :(得分:17)

非裸存储库只有一个签出的工作树。工作树不存储有关存储库状态(分支,标记等)的任何信息;相反,工作树只是repo中实际文件的表示,它允许您处理(编辑等)文件。

答案 5 :(得分:12)

裸存储库有好处

  • 减少磁盘使用量
  • 与远程推送相关的问题较少(因为没有工作树不同步或有相互冲突的变化)

答案 6 :(得分:10)

非裸存储库允许您(进入工作树)通过创建新提交来捕获更改。

只有通过传输来自其他存储库的更改才能更改裸存储库。

答案 7 :(得分:6)

我当然不是Git“专家”。我已经使用过TortoiseGit一段时间了,当它问我是否想要创建一个“裸”回购时,我想知道它在说什么。我正在阅读本教程:https://www.atlassian.com/git/tutorials/setting-up-a-repository/git-init它解决了这个问题,但我仍然不太了解这个概念。这个帮了很多忙:http://bitflop.com/tutorials/git-bare-vs-non-bare-repositories.html。现在,第一个也有意义!

根据这些消息来源,简而言之,在您想要设置分发点的服务器上使用“裸”仓库。它不打算在您的本地计算机上使用。您通常将提交从本地计算机推送到远程服务器上的裸存储库,并且您和/或其他人从该裸存储库中提取到本地计算机。所以你的GitHub,Assembla等远程存储/分发回购就是一个创建“裸”仓库的例子。如果你要建立自己的类似“共享中心”,你可以自己制作一个。

答案 8 :(得分:2)

这不是一个新的答案,但它帮助我理解了上述答案的不同方面(并且对评论来说太过分了)。

使用Git Bash尝试:

me@pc MINGW64 /c/Test
$ ls -al
total 16
drwxr-xr-x 1 myid 1049089 0 Apr  1 11:35 ./
drwxr-xr-x 1 myid 1049089 0 Apr  1 11:11 ../

me@pc MINGW64 /c/Test
$ git init
Initialized empty Git repository in C:/Test/.git/

me@pc MINGW64 /c/Test (master)
$ ls -al
total 20
drwxr-xr-x 1 myid 1049089 0 Apr  1 11:35 ./
drwxr-xr-x 1 myid 1049089 0 Apr  1 11:11 ../
drwxr-xr-x 1 myid 1049089 0 Apr  1 11:35 .git/

me@pc MINGW64 /c/Test (master)
$ cd .git

me@pc MINGW64 /c/Test/.git (GIT_DIR!)
$ ls -al
total 15
drwxr-xr-x 1 myid 1049089   0 Apr  1 11:35 ./
drwxr-xr-x 1 myid 1049089   0 Apr  1 11:35 ../
-rw-r--r-- 1 myid 1049089 130 Apr  1 11:35 config
-rw-r--r-- 1 myid 1049089  73 Apr  1 11:35 description
-rw-r--r-- 1 myid 1049089  23 Apr  1 11:35 HEAD
drwxr-xr-x 1 myid 1049089   0 Apr  1 11:35 hooks/
drwxr-xr-x 1 myid 1049089   0 Apr  1 11:35 info/
drwxr-xr-x 1 myid 1049089   0 Apr  1 11:35 objects/
drwxr-xr-x 1 myid 1049089   0 Apr  1 11:35 refs/

git --bare相同:

me@pc MINGW64 /c/Test
$ ls -al
total 16
drwxr-xr-x 1 myid 1049089 0 Apr  1 11:36 ./
drwxr-xr-x 1 myid 1049089 0 Apr  1 11:11 ../

me@pc MINGW64 /c/Test
$ git init --bare
Initialized empty Git repository in C:/Test/

me@pc MINGW64 /c/Test (BARE:master)
$ ls -al
total 23
drwxr-xr-x 1 myid 1049089   0 Apr  1 11:36 ./
drwxr-xr-x 1 myid 1049089   0 Apr  1 11:11 ../
-rw-r--r-- 1 myid 1049089 104 Apr  1 11:36 config
-rw-r--r-- 1 myid 1049089  73 Apr  1 11:36 description
-rw-r--r-- 1 myid 1049089  23 Apr  1 11:36 HEAD
drwxr-xr-x 1 myid 1049089   0 Apr  1 11:36 hooks/
drwxr-xr-x 1 myid 1049089   0 Apr  1 11:36 info/
drwxr-xr-x 1 myid 1049089   0 Apr  1 11:36 objects/

答案 9 :(得分:1)

默认/非裸Git存储库包含两种状态:

  1. 存储库中所有文件的快照(这是Git行话中的“工作树”的意思)
  2. 对存储库中曾经有过的所有文件所做的所有更改的历史记录(似乎没有一个简洁的Git行话涵盖了所有这些内容)

快照是您可能会想到的项目:您的代码文件,构建文件,帮助程序脚本以及您使用Git发行的其他版本。

历史记录是允许您检出其他提交并获得添加该提交时存储库中文件外观的完整快照的状态。它由Git内部的一堆数据结构组成,您可能从未与之直接交互。重要的是,历史记录不仅存储元数据(例如“用户U在时间T作为提交C的一部分向文件F添加了这么多行”),还存储了数据(例如“用户U添加了这些确切的行< / em>到文件F“)。

裸仓库的关键思想是实际上不需要快照。 Git之所以保留快照,是因为它方便了人类和其他想要与您的代码进行交互的非Git进程,但是快照只是复制了历史中已经存在的状态。

裸存储库是没有快照的Git存储库。它只是存储历史记录。

您为什么要这个?好吧,如果仅使用Git与文件进行交互(也就是说,您将不直接编辑文件或使用它们来构建可执行文件),则可以通过不保留快照来节省空间。特别是,如果您要在某处的服务器上维护集中版本的存储库(即,您基本上是在托管自己的GitHub),则该服务器可能应该有裸存储库(您仍然会在您的仓库上使用非裸存储库)不过是本地计算机,因为您可能想编辑快照)。

如果您想更深入地解释裸仓库和另一个示例用例,我在这里写了一篇博客文章:https://stegosaurusdormant.com/blog/bare-git-repo/

答案 10 :(得分:0)

$ git help repository-layout

  

Git存储库具有两种不同的口味:

     
      
  • 工作树根目录下的.git目录;
  •   
  • .git目录,它是一个存储库(即没有其自己的工作树),通常用于通过推入并从中获取历史记录来与他人交换历史记录。
  •