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

发布于 2024-10-30 13:26:34 字数 397 浏览 6 评论 0原文

我一直在阅读有关 Git 中的裸露和非裸露/默认存储库的内容。我无法很好地(理论上)理解它们之间的差异,以及为什么我应该“推送”到裸存储库。事情是这样的:

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

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

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

您从事此类工作的方法是什么?建议?

I've been reading about the bare and non-bare / default repositories in Git. I haven't been able to understand quite well (theoretically) the differences between them, and why I should "push" to a bare repository. Here's the deal:

Currently, I'm the only one working on a project on 3 different computers, but there will be more people involved in it later, so I'm using Git for the version control. I clone the bare repo on all computers, and when I finish my modifications on one of them, I commit and push the changes to the bare repo. From what I've read, the bare repository does NOT have a "working tree", so if I clone the bare repo, I won't have a "working tree".

I'm guessing that the working tree stores the commit information, branches, etc. from the project. That wouldn't appear in the bare repo. So it seems better for me to "push" the commits to the repo with the working tree.

Then, why should I use the bare repository and why not? What's the practical difference? That would not be beneficial to more people working on a project, I suppose.

What are your methods for this kind of work? Suggestions?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(11

猫瑾少女 2024-11-06 13:26:34

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

~/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/remotes/origin/。什么时候
使用此选项,既不
远程跟踪分支机构也不
相关的配置变量有
创建。

据推测,当创建裸存储库时,Git 假定裸存储库将作为多个远程用户的源存储库,因此它不会创建默认的远程源。这意味着基本的 git pull 和 git 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$ 

Another difference between a bare and non-bare repository is that a bare repository does not have a default remote origin repository:

~/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

From the manual page for git clone --bare:

Also the branch heads at the remote
are copied directly to corresponding
local branch heads, without mapping
them to refs/remotes/origin/. When
this option is used, neither
remote-tracking branches nor the
related configuration variables are
created.

Presumably, when it creates a bare repository, Git assumes that the bare repository will serve as the origin repository for several remote users, so it does not create the default remote origin. What this means is that basic git pull and git push operations won't work since Git assumes that without a workspace, you don't intend to commit any changes to the bare repository:

~/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$ 
翻了热茶 2024-11-06 13:26:34

我知道晚了 5 年,但没有人真正回答这个问题:

那么,为什么我应该使用裸存储库,为什么不呢?什么是
实际差异?这并不会给更多人带来好处
我想是在做一个项目。

您从事此类工作的方法是什么?有建议吗?

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

裸存储库可能看起来没什么用,但它的作用是
至关重要:作为协作的权威联络点
发展。其他开发者从裸机中克隆获取
存储库并推送更新...如果您将存储库设置为
开发人员推送更改,它应该是裸露的。实际上,这是
已发表的更一般最佳实践的一个特例
存储库应该是裸露的。

5 years too late, I know, but no-one actually answered the question:

Then, why should I use the bare repository and why not? What's the
practical difference? That would not be beneficial to more people
working on a project, I suppose.

What are your methods for this kind of work? Suggestions?

To quote directly from the Loeliger/MCullough book (978-1-449-31638-9, p196/7):

A bare repository might seem to be of little use, but its role is
crucial: to serve as an authoritative focal point for collaborative
development. Other developers clone and fetch from the bare
repository and push updates to it... if you set up a repository into
which developers push changes, it should be bare. In effect, this is
a special case of the more general best practice that a published
repository should be bare.

似最初 2024-11-06 13:26:34

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

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

The distinction between a bare and non-bare Git repository is artificial and misleading since a workspace is not part of the repository and a repository doesn't require a workspace. Strictly speaking, a Git repository includes those objects that describe the state of the repository. These objects may exist in any directory, but typically exist in the .git directory in the top-level directory of the workspace. The workspace is a directory tree that represents a particular commit in the repository, but it may exist in any directory or not at all. Environment variable $GIT_DIR links a workspace to the repository from which it originates.

Git commands git clone and git init both have options --bare that create repositories without an initial workspace. It's unfortunate that Git conflates the two separate, but related concepts of workspace and repository and then uses the confusing term bare to separate the two ideas.

墨落画卷 2024-11-06 13:26:34

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

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

A bare repository is nothing but the .git folder itself i.e. the contents of a bare repository is same as the contents of .git folder inside your local working repository.

  • Use bare repository on a remote server to allow multiple contributors to push their work.
  • Non-bare - The one which has working tree makes sense on the local machine of each contributor of your project.
極樂鬼 2024-11-06 13:26:34

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

  1. 存储库中所有文件的快照(这就是 Git 术语中“工作树”的含义)
  2. 历史记录< /strong> 对存储库中所有文件所做的所有更改(似乎没有一个简洁的 Git 术语来涵盖所有这些)

快照 就是您要查看的内容可能将其视为您的项目:您的代码文件、构建文件、帮助程序脚本以及您使用 Git 进行版本控制的任何其他内容。

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

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

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

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

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

A default/non-bare Git repo contains two pieces of state:

  1. A snapshot of all of the files in the repository (this is what "working tree" means in Git jargon)
  2. A history of all changes made to all the files that have ever been in the repository (there doesn't seem to be a concise piece of Git jargon that encompasses all of this)

The snapshot is what you probably think of as your project: your code files, build files, helper scripts, and anything else you version with Git.

The history is the state that allows you to check out a different commit and get a complete snapshot of what the files in your repository looked like when that commit was added. It consists of a bunch of data structures that are internal to Git that you've probably never interacted with directly. Importantly, the history doesn't just store metadata (e.g. "User U added this many lines to File F at Time T as part of Commit C"), it also stores data (e.g. "User U added these exact lines to File F").

The key idea of a bare repository is that you don't actually need to have the snapshot. Git keeps the snapshot around because it's convenient for humans and other non-Git processes that want to interact with your code, but the snapshot is just duplicating state that's already in the history.

A bare repository is a Git repository that does not have a snapshot. It just stores the history.

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).

If you want a more in-depth explanation of bare repos and another example use case, I wrote up a blog post here: https://stegosaurusdormant.com/bare-git-repo/

深巷少女 2024-11-06 13:26:34

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

A non-bare repository simply has a checked-out working tree. The working tree does not store any information about the state of the repository (branches, tags, etc.); rather, the working tree is just a representation of the actual files in the repo, which allows you to work on (edit, etc.) the files.

一抹苦笑 2024-11-06 13:26:34

裸存储库的优点是

  • 减少磁盘使用量,
  • 减少与远程推送相关的问题(因为没有工作树会不同步或发生冲突的更改)

A bare repository has benefits in

  • reduced disk usage
  • less problems related to remote push (since no working tree is there to get out of synch or have conflicting changes)
(り薆情海 2024-11-06 13:26:34

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

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

Non bare repository allows you to (into your working tree) capture changes by creating new commits.

Bare repositories are only changed by transporting changes from other repositories.

如何视而不见 2024-11-06 13:26:34

我当然不是 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 等远程存储/分发存储库是创建“裸”存储库的示例。如果您要建立自己的类似“共享中心”,您可以自己制作一个。

I'm certainly not a Git "expert". I have used TortoiseGit for a while and wondered what it was talking about when it asked me if I wanted to make a "bare" repo whenever I created one. I was reading this tutorial: https://www.atlassian.com/git/tutorials/setting-up-a-repository/git-init and it addresses the issue, but I still was not quite understanding the concept. This one helped a lot: http://bitflop.com/tutorials/git-bare-vs-non-bare-repositories.html. Now, the first one makes sense too!

According to these sources, in a nutshell, a "bare" repo is used on a server where you want to set up a distribution point. It's not intended for use on your local machine. You generally push commits from your local machine to a bare repo on a remote server, and you and/or others pull from that bare repo to your local machine. So your GitHub, Assembla, etc. remote storage/distribution repo is an example where a "bare" repo is created. You would make one yourself if you were setting up your own analogous "sharing center".

不可一世的女人 2024-11-06 13:26:34

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

使用 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/

This is not a new answer, but it helped me to understand the different aspects of the answers above (and it is too much for a comment).

Using Git Bash just try:

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/

Same with 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/
囍孤女 2024-11-06 13:26:34

$ git 帮助存储库布局

Git 存储库有两种不同的风格:

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

$ git help repository-layout

A Git repository comes in two different flavours:

  • a .git directory at the root of the working tree;
  • a .git directory that is a bare repository (i.e. without its own working tree), that is typically used for exchanging histories with others by pushing into it and fetching from it.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文