什么是裸存储库,为什么我需要一个?

What is a bare repository and why would I need one?

这可能已经得到解答,但我没有找到好的答案。
我来自集中式存储库,例如 SVN,通常您只执行检出、更新、提交、还原、合并等操作。

Git 快把我逼疯了。有很多命令,但最难理解的是为什么很多事情都是这样工作的。

根据"What is a bare git repository?"

Repositories created with git init --bare are called bare repos. They are structured a bit differently from working directories. First off, they contain no working or checked out copy of your source files.

A bare repository created with git init --bare is for… sharing. …developers will clone the shared bare repo, make changes locally in their working copies of the repo, then push back to the shared bare repo to make their changes available to other users.
– Jon Saints, http://www.saintsjd.com/2011/01/what-is-a-bare-git-repository/

然而,从 "what's the difference between github repository and git bare repository?" 接受的答案:

Git repos on GitHub are bare, like any remote repo to which you want to push to [sic].
– VonC,

但是,在GitHub 中有源文件。我能看到他们。如果我创建一个裸存储库,则没有源文件,只有工作存储库的 .git 目录的内容。

这怎么可能?我不明白什么?

您能否举例说明为什么我需要一个裸存储库以及它以这种方式工作的动机?

更新

Edward Thomson 的回答部分是我想知道的。不过,我会重新表述我的问题:

首先 link 我发布了 states("What is a bare git repository?"):

they [bare repositories] contain no working or checked out copy of your source files.

VonC 的回答:

Git repos on GitHub are bare

两种说法都暗示

Github has no working copy.

爱德华汤姆森说:

it renders the web page based on the data as you navigate through it - pulling the data directly out of the repo and out to your web browser, not writing it to a disk on the fileserver first

不知何故,裸存储库必须包含所有数据和源代码。如果没有,渲染任何东西都不是不可能的,因为我可以看到所有源代码更新(提交)、所有分支(及其各自的源代码)、repo 的整个日志等。

是否总是在 .git 目录中(或在裸仓库中)以某种能够随时呈现所有文件的格式存储库的全部数据?这是裸仓库的原因,而工作副本只有给定时间的文件吗?

Is there the whole data of a repository always within .git directory (or in a bare repo), in some kind of format which is able to render all files at any time?

是的,这些文件及其完整历史存储在 .git/packed-refs and .git/refs, and

当您克隆一个存储库(裸或非裸)时,您总是 拥有 .git 文件夹(或带有 .git 扩展名的文件夹用于裸repo,按照命名约定)及其 Git 管理和控制文件。 (see glossary)

Git可以unpack at any time what it needs with git unpack-objects.

诀窍是:

从裸仓库中,您可以查询日志(git log 在 git 仓库中工作得很好:不需要工作树), 或 list files in a bare repo.
或者 show the content of a file from a bare repo.
这就是 GitHub 无需检出 full 存储库即可呈现包含文件的页面的方式。

我不知道 GitHub 确实 确实如此,因为回购协议的绝对数量迫使 GitHub engineering team 进行各种优化.
例如参见 [​​=34=].
使用 DGit,那些裸仓库实际上是跨多个服务器复制的。

Is this the reason of bare repository, while working copy only has the files at a given time?

对于 GitHub,维护一个工作树会在磁盘 space 和更新(当每个用户请求不同的分支时)方面花费太多。最好从 unique bare repo 中提取渲染页面所需的内容。

一般情况下(在 GitHub 约束之外),使用裸仓库进行推送,以避免出现 working tree out of sync with what has just been pushed. See "but why do I need a bare repo?" 的具体示例。

也就是说:

但这对于 GitHub 来说是不可能的,它不能为它必须存储的每个 repo 维护一个(或服务器)工作树。


文章“Using a bare Git repo to get version control for my dotfiles " from Greg Owen, originally reported by aifusenno1增加:

A bare repository is a Git repository that does not have a snapshot.
It just stores the history. It also happens to store the history in a slightly different way (directly at the project root), but that’s not nearly as important.

A bare repository will still store your files (remember, the history has enough data to reconstruct the state of your files at any commit).
You can even create a non-bare repository from a bare repository: if you git clone a bare repository, Git will automatically create a snapshot for you in the new repository (if you want a bare repository, use git clone --bare).

Greg 补充道:

So why would we use a bare Git repository?Permalink

Almost every explanation I found of bare repositories mentioned that they’re used for centralized storage of a repository that you want to share between multiple users.

参见Git repository layout

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

Basically, if you wanted to write your own GitHub/GitLab/BitBucket, your centralized service would store each repo as a bare repository.
But why? How does not having a snapshot connect to sharing?

The answer is that there’s no need to have a snapshot if the only service that’s interacting with your repo is Git.
Basically, the snapshot is a convenience for humans and non-Git tools, but Git only interacts with the history. Your centralized Git hosting service will only interact with the repos through Git commands, so why bother materializing snapshots all the time? The snapshots only take up extra space for no gain.

GitHub generates that snapshot on the fly when you access that page, rather than storing it permanently with the repo (this means that GitHub only needs to generate a snapshot when you ask for it, rather than keeping one updated every time anybody pushes any changes).

为什么我需要一个?

link“but why do I need a bare repo?" from the 可以用我最近发现的两个用例来完成。

第一个对于了解恕我直言是必不可少的,而第二个可能会受到批评。

A - 同步您的主页文件

不再有指向您 git 存储库的符号 link。只需使用:

git init --bare $HOME/.myconf
alias config='/usr/bin/git --git-dir=$HOME/.myconf/ --work-tree=$HOME'
config config status.showUntrackedFiles no

我的 ~/.myconf 目录是一个 git 裸仓库。然后主文件夹中的任何文件都可以使用普通命令进行版本控制,例如:

    config status
    config add .vimrc
    config commit -m "Add vimrc"
    config add .config/redshift.conf
    config commit -m "Add redshift config"
    config push

其中一个主要好处是它可以防止嵌套 git 回购。有关 source

的更多详细信息

B - 在云同步文件夹中托管 Git 项目

在云同步文件夹中创建 .git/ 目录不是一个好主意,因为同步可能会搞砸一切。但是使用与上述相同的技术,您可以在同步目录 之外使用裸存储库 来使用版本控制,并且仍然可以享受同步目录的舒适性。