我一直在阅读Git中的裸库和非裸库/默认库。我还不能很好地(从理论上)理解它们之间的区别,以及为什么我应该“推送”到一个裸库。事情是这样的:

目前,我是唯一一个在3台不同计算机上从事项目的人,但以后会有更多人参与其中,所以我使用Git进行版本控制。我在所有计算机上克隆裸回购,当我完成对其中一台计算机的修改时,我提交并将更改推到裸回购。据我所知,裸库没有“工作树”,所以如果我克隆裸库,我就不会有“工作树”。

我猜工作树存储了来自项目的提交信息、分支等。这不会出现在裸回购中。因此,对我来说,用工作树将提交“推”到repo似乎更好。

那么,为什么我应该使用裸库,为什么不呢?实际的区别是什么?我想,这对更多人参与一个项目没有好处。

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


当前回答

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

裸存储库只能通过从其他存储库传输更改来更改。

其他回答

默认/非裸的Git repo包含两段状态:

存储库中所有文件的快照(这就是Git术语中“工作树”的含义) 对存储库中所有文件所做的所有更改的历史记录(似乎没有一个简洁的Git术语包含所有这些内容)

快照就是您可能认为的项目:您的代码文件、构建文件、助手脚本以及其他使用Git进行版本管理的东西。

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

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

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

Why would you want this? Well, if you're only going to interact with your files using Git (that is, you're not going to edit your files directly or use them to build an executable), you can save space by not keeping around the snapshot. In particular, if you're maintaining a centralized version of your repo on a server somewhere (i.e. you're basically hosting your own GitHub), that server should probably have a bare repo (you would still use a non-bare repo on your local machine though, since you'll presumably want to edit your snapshot).

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

$ git帮助存储库布局

Git存储库有两种不同的风格: 在工作树的根目录下有一个.git目录; 一个.git目录是一个裸存储库(即没有自己的工作树),通常用于通过推入和从中获取与他人交换历史。

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

裸存储库只能通过从其他存储库传输更改来更改。

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

使用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也是一样:

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/

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