你如何使用 "git --bare init" 仓库?

377

我需要创建一个中央Git仓库,但我有点困惑...

我已经在我的Git服务器(机器2)上创建了一个裸仓库:

$ mkdir test_repo
$ git --bare init

现在我需要将本地仓库(机器1)中的文件推送到裸仓库(机器2)中。我可以通过SSH访问机器2。问题是,我认为我不理解裸仓库的概念...

在裸仓库中存储代码的正确方法是什么?如何将本地仓库中的更改推送到裸仓库中?

拥有一个中央仓库的正确方式是拥有一个裸仓库吗?

我对这个主题有点困惑。请给我一些线索。

10个回答

452

首先,为了确认,请在运行git init --bare之前更改到您创建的目录中。此外,惯例是给裸仓库添加.git扩展名。因此可以执行以下操作:

git init --bare test_repo.git

对于 Git 版本< 1.8 ,您可以执行以下操作:

mkdir test_repo.git
cd test_repo.git
git --bare init

回答你后面的问题,赤裸仓库(按定义)没有工作树附加到它们上面,因此无法像在普通的非裸仓库中那样轻松地添加文件到其中(例如使用git add <file>和随后的git commit)。

你几乎总是通过从另一个仓库推送到它(使用git push)来更新一个裸仓库。

请注意,在这种情况下,您需要首先允许其他人向您的仓库推送。当在test_repo.git内部时,请执行以下操作:

git config receive.denyCurrentBranch ignore

社区编辑

git init --bare --shared=group

如prasanthv所评论的那样,如果您是在工作中进行此操作而不是私人家庭项目,则这正是您想要的。


9
如果你打算让其他人也能推送到这个仓库,可以在init命令中加上--shared选项。它会自动添加组写权限到仓库中。- 链接 - prasanthv
18
我认为这三行命令的效果与以下一行命令相同:git --bare init test_repo.git至少在我当前使用的 Git 版本(1.8.2.2)中是如此。 - Fran Marzoa
2
如果您想了解裸库和非裸库之间的区别,这篇文章很有用:https://dev59.com/fGsz5IYBdhLWcg3wfn66 - Guille Acosta
如果没有工作树,Git如何找到东西?我以为在Git对象存储中有一个工作树,这就是暂存SHA和提交所指向的内容。 - akantoword
如果你使用了 --shared=group,那么你是否需要执行 git config ... 呢? - GreenAsJade
显示剩余5条评论

312

我添加了这个答案,因为在来到这里(有相同的问题)后,没有一个答案真正描述了从零开始到完全可用的远程(裸)仓库所需的所有步骤。

注意:此示例使用本地路径作为裸仓库的位置,但其他 Git 协议(如 OP 指出的 SSH)应该也能很好地工作。

我尝试在途中添加一些注释,以供那些不太熟悉 Git 的人参考。

1. 初始化裸仓库...

> git init --bare /path/to/bare/repo.git
Initialised empty Git repository in /path/to/bare/repo.git/

这将创建一个文件夹(repo.git),并用git文件填充它,以表示一个git库。就目前而言,这个库是无用的-它没有提交记录,更重要的是,没有分支。虽然你可以克隆这个库,但你不能从中取回(pull)。

接下来,我们需要创建一个工作文件夹。根据你是否有现有文件,有几种方法可以实现这一点。

2a. 通过克隆空仓库来创建新的工作文件夹(没有现有文件)

git clone /path/to/bare/repo.git /path/to/work
Cloning into '/path/to/work'...
warning: You appear to have cloned an empty repository.
done.

只有当/path/to/work不存在或为空文件夹时,此命令才有效。注意警告 - 在这个阶段,你还没有任何有用的东西。如果你cd /path/to/work并运行git status,你会得到如下结果:

On branch master

Initial commit

nothing to commit (create/copy files and use "git add" to track)
但这是一个谎言。您实际上并不在分支master上(因为git branch没有返回任何内容),到目前为止还没有提交。 接下来,在工作文件夹中复制/移动/创建一些文件,将它们添加到Git并创建第一个提交。
> cd /path/to/work
> echo 123 > afile.txt
> git add .
> git config --local user.name adelphus
> git config --local user.email adelphus@example.com
> git commit -m "added afile"
[master (root-commit) 614ab02] added afile
 1 file changed, 1 insertion(+)
 create mode 100644 afile.txt

git config 命令只有在你还没告诉 Git 你是谁的情况下才需要。注意,如果你现在运行 git branch,你将看到 master 分支已列出。现在运行 git status

On branch master
Your branch is based on 'origin/master', but the upstream is gone.
  (use "git branch --unset-upstream" to fixup)

nothing to commit, working directory clean

这也是具有误导性的——上游并没有“消失”,只是尚未创建,git branch --unset-upstream也无法帮助。但这没关系,现在我们有了第一个提交,我们可以推送,主分支将在裸仓库中创建。

> git push origin master
Counting objects: 3, done.
Writing objects: 100% (3/3), 207 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To /path/to/bare/repo.git
 * [new branch]      master -> master

此时,我们拥有一个完全功能的裸仓库,可以在主分支上被克隆到其他地方以及一个本地的工作副本,可以进行拉取和推送操作。

> git pull
Already up-to-date.
> git push origin master
Everything up-to-date

2b. 从现有文件创建工作文件夹 如果您已经有一个文件夹中有文件(因此无法克隆到该文件夹中),则可以初始化一个新的git存储库,添加第一个提交,然后将其链接到裸存储库。

> cd /path/to/work_with_stuff
> git init 
Initialised empty Git repository in /path/to/work_with_stuff
> git add .
# add git config stuff if needed
> git commit -m "added stuff"

[master (root-commit) 614ab02] added stuff
 20 files changed, 1431 insertions(+)
 create mode 100644 stuff.txt
...

目前,我们已经有了第一次提交和本地主分支,我们需要将其转换为远程跟踪的上游分支。

> git remote add origin /path/to/bare/repo.git
> git push -u origin master
Counting objects: 31, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (31/31), done.
Writing objects: 100% (31/31), 43.23 KiB | 0 bytes/s, done.
Total 31 (delta 11), reused 0 (delta 0)
To /path/to/bare/repo.git
 * [new branch]      master -> master
Branch master set up to track remote branch master from origin.

注意在 git push 命令中添加 -u 标志以设置(新的)上游跟踪分支。 和以前一样,我们现在有一个完全功能的裸仓库,可以作为主干分支在其他地方进行克隆,以及一个本地工作副本,可以进行拉取和推送。

所有这些对一些人来说可能很明显,但是在大多数时候,git 会让我感到困惑(它的错误和状态消息真的需要重新制定)- 希望这将对其他人有所帮助。


7
有趣,肯定比我的回答更详细。+1 - VonC
18
这个答案解决了我的问题,应该被采纳为最佳答案,希望越来越多的人能够点赞支持它。 - inix
13
你应该就像这样的答案收费。 - Arthur Tarasov
5
作为一个新的 Git 用户,这个回答对我非常有帮助,感谢你写下这篇文章! - sidewinderguy
2
这是一个非常出色的答案。将会对我们的团队有很大帮助。 - wobsoriano
显示剩余6条评论

35

逐一回答你的问题:

裸仓库是指没有工作树的仓库,也就是说它的所有内容都在 .git 目录中。

你只能通过从本地克隆仓库向裸仓库 push 来将其提交到裸仓库中。由于裸仓库没有工作树,因此它没有修改文件,也没有变更。

要拥有中央仓库,唯一的方法是拥有一个 bare 仓库。


23

你也可以让git为你创建目录:

git init --bare test_repo.git

20

通常的做法是将中央存储库作为一个裸库进行推送。

如果您具有SVN背景,可以将SVN存储库与Git裸库相关联。它没有以原始形式在存储库中的文件。而您的本地存储库将包含形成您的“代码”的文件。

您需要向裸库添加一个远程仓库,并将您的“代码”推送到它。

它会是这样的:

git remote add central <url> # url will be ssh based for you
git push --all central

使用 git remote add central <url>,在 SSH 的情况下,这是否也包括路径呢?例如:git remote add central ssh://user@server/home/user/repo.git - Yes Barry

17

这应该就足够了:

git remote add origin <url-of-bare-repo>
git push --all origin

更多细节请参见 "GIT:如何更新我的裸仓库?"。
注:

  • 你可以使用不同于 'origin' 的名称作为裸仓库远程引用。
  • 这不会推送你的标签,你需要单独运行 git push --tags origin 来完成。

6

根据Mark Longair和Roboprog的回答:

如果git版本>=1.8

git init --bare --shared=group .git
git config receive.denyCurrentBranch ignore

或者:

如果git版本小于1.8

mkdir .git
cd .git
git init --bare --shared=group 
git config receive.denyCurrentBranch ignore

那个配置命令:它是如何应用于你刚创建的.git目录的? - GreenAsJade
我不确定我理解你的问题?你能更明确一些吗?由于您已经初始化了git存储库,因此可以使用命令“git config”对其进行任意配置。 - Jack'
@GreenAsJade 这是因为您仍然在 git 仓库的文件夹内,因此它适用于该仓库(git 配置的默认选项类似于 --local 选项)。 - BlueCoder

5

验证你提交的代码已经被成功提交是很好的。

你可以通过显式设置路径并使用--relative选项来获取裸仓库上的更改日志。

$ cd test_repo
$ git log --relative=/

这将显示已提交的更改,就像这是一个常规的Git存储库一样。

3
您可以执行以下命令来初始化您的本地代码库。
mkdir newProject
cd newProject
touch .gitignore
git init
git add .
git commit -m "Initial Commit"
git remote add origin user@host:~/path_on_server/newProject.git
git push origin master

你应该从本地仓库开始处理项目,并将服务器用作中央仓库。

你也可以参照这篇文章,它详细解释了创建和维护Git仓库的每个方面。 Git入门


2
“--bare”标志创建一个没有工作目录的仓库。裸仓库是中央仓库,您不能在此处编辑(存储)代码以避免合并错误。
例如,当您在本地仓库(机器1)中添加文件并将其推送到裸仓库时,您无法在裸仓库中看到该文件,因为它始终是“空”的。但是,您确实向仓库推送了一些内容,并且可以通过克隆服务器(机器2)上的另一个仓库来隐式地看到它。
机器1中的本地仓库和机器2中的“副本”仓库都是非裸的。 裸仓库和非裸仓库之间的关系 这篇博客将帮助您理解它。 https://www.atlassian.com/git/tutorials/setting-up-a-repository

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接