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

fiei3ece  于 2022-12-25  发布在  Git
关注(0)|答案(6)|浏览(211)

git initgit init --bare有什么不同?我发现很多博客文章需要--bare作为他们的Git服务器?
the man page,它说:

--bare

创建空存储库。如果未设置GIT_DIR环境,则将其设置为当前工作目录
但它实际上意味着什么?Git服务器设置需要--bare吗?

laawzig2

laawzig21#

非裸Git存储库

这个变体创建了一个仓库,里面有一个工作目录(git clone),创建后你会看到这个目录包含一个.git文件夹,历史记录和所有git管道都存放在这个文件夹里,你可以在.git文件夹所在的层级上工作。

裸Git存储库

另一个变体创建了一个没有工作目录的仓库(git clone --bare)。你没有一个可以工作的目录。目录中的所有内容现在都包含在上面例子中的.git文件夹中。

为什么使用一个而不是另一个

没有工作目录的git repos的必要性在于你可以将分支推送到工作目录中,但它并不管理其他人正在处理的内容。你仍然可以推送到一个非空的仓库中,但你会被拒绝,因为你可能会将其他人正在处理的分支移到工作目录中。
所以在没有工作文件夹的项目中,你只能看到git存储的对象。它们被压缩、序列化并存储在其内容的SHA1(哈希值)下。为了在裸仓库中获取对象,你需要git show,然后指定你想要看到的对象的shA1。你不会看到项目的结构。
裸存储库通常是每个人都可以将工作移到其中的中央存储库。不需要操作实际工作。这是一种在多个人之间同步工作的方法。您将无法直接查看项目文件。
如果你是唯一一个在项目中工作的人,或者你不想/不需要一个“逻辑中心”的仓库,你可能不需要任何裸仓库。在这种情况下,你会倾向于使用git pull,而不是其他仓库。这就避免了git在推送非裸仓库时的异议。

gj3fmq9x

gj3fmq9x2#

简短的回答

裸仓库是指没有工作副本的git仓库,因此. git的内容是该目录的顶层。
Use a non-bare repository to work locally and a bare repository as a central server/hub to share your changes with other people. For example, when you create a repository on github.com, it is created as a bare repository.
所以,在你的电脑里:

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仓库,但是由于大多数"hub"仓库不需要工作副本,因此使用裸仓库是正常的,建议使用裸仓库,因为在这种仓库中没有工作副本。
然而,如果你推送到一个非裸仓库,你会使工作副本不一致,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'.

您可以跳过此警告。但建议的设置是:使用非裸存储库在本地工作,使用裸存储库作为中心或中央服务器进行推送和拉取。
如果您想直接与其他开发人员的工作副本共享工作,您可以从彼此的存储库中拉取而不是推送。

mwg9r5ms

mwg9r5ms3#

当我前段时间读到这个问题时,我感到很困惑。我刚开始使用git,就有了这些工作副本(在当时没有任何意义)。我将试着从一个人的Angular 来解释这一点,他刚开始使用git时对术语一无所知。

  • 以下是一个很好的差异示例 *:

--bare只给你一个存储空间(你不能在那里开发)。没有--bare,它给你在那里开发的能力(并有一个存储空间)。
git init从你当前的目录创建一个git仓库,它会在仓库中添加.git文件夹,这样你就可以打开你的修订历史了。
git init --bare还创建了一个存储库,但它没有工作目录,这意味着您不能在该存储库中编辑文件、提交更改或添加新文件。

**什么时候--bare可以提供帮助?**您和其他几个人正在使用git开发项目。您将项目托管在某个服务器上(amazon ec2)。你们每个人都有自己的机器,并且在ec2上推送代码。实际上,你们没有人在ec2上开发任何东西(你使用你的机器)-你只是推送你的代码。所以你的ec2只是你所有代码的存储器,应该创建为--bare和你所有没有--bare的机器(很可能只有一个,其他的只会克隆所有内容)。工作流如下所示:

px9o7tmv

px9o7tmv4#

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

w41d8nur

w41d8nur5#

非裸存储库是默认的,它是在运行git init时创建的,或者是从服务器克隆(不使用bare选项)时获得的。
当你使用这样的仓库时,你可以查看和编辑仓库中的所有文件,当你与仓库交互时--比如提交一个修改-- Git会将你的修改保存在一个名为.git的隐藏目录中。
当你有一个git服务器时,你不需要文件的工作副本,你只需要存储在.git中的Git数据。一个空仓库就是.git目录,没有修改和提交文件的工作区。
当你从一个服务器克隆时,Git在.git目录中有创建你的工作副本所需的所有信息。

mzaanser

mzaanser6#

--bare和Working Tree仓库的另一个区别是,在第一种情况下,**不会存储丢失的提交,而只会存储属于分支跟踪的提交。另一方面,Working Tree会永久保存所有提交。
我创建了第一个存储库(名称:git-bare),它是服务器,在左边,没有远程分支,因为这是远程仓库本身。
我创建了第二个存储库(名称:git-working-tree),从第一个开始就是git clone,在右边,它有本地分支和远程分支。
(The文本'first','second','third','fourth','alpha','beta'和'delta'是提交注解。名称'master'和'greek'是分支名称。)

现在我将删除 git-bare 中名为'greek'的分支(命令:git push --delete origin greek)和本地 git-working-tree(命令:git branch -D greek)。树的外观如下:

  • git-bare* 仓库同时删除分支和所有引用的comit,在图中我们看到它的树也因此被缩小了。

另一方面,git-working-tree 仓库(相当于常用的本地仓库)不会删除提交,现在只能通过git checkout 7fa897b7命令直接引用提交,这就是为什么它的树没有修改过的结构。

简而言之:提交不会在 working-tree 存储库中删除,但会在 bare 存储库中删除。

实际上,您只能在服务器上恢复已删除的分支(如果它存在于本地存储库中)。

**但非常奇怪的是,在删除远程分支后,bare 存储库的磁盘大小并没有减少。也就是说,文件仍然在那里。**要通过删除不再引用或永远不能引用的内容(后一种情况)来转储存储库,请使用git gc --prune命令

相关问题