您如何使用“ git --bare init”存储库?


320

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

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

$ mkdir test_repo
$ git --bare init

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

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

具有中央存储库和裸存储库的正确方法是吗?

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

Answers:


391

首先,仅需检查,您需要在运行之前切换到您创建的目录git init --bare。同样,通常给裸仓库扩展名.git。所以你可以做

git init --bare test_repo.git

对于<1.8的Git版本,您可以

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所评论的那样,这是您在工作中而不是在私人住宅项目中想要的。


7
如果您打算让其他人推送到此存储库,也可以添加该--shared选项init。它会自动向存储库添加组写权限- 链接
prasanthv 2014年

17
我认为这三行与仅这一行具有相同的效果:git --bare init test_repo.git至少与我当前的git版本(1.8.2.2)
Fran Marzoa 2014年

1
有用的,如果你想知道裸露和非裸回购之间的差异stackoverflow.com/questions/7861184/...
吉尔·阿科斯塔

如果没有可用的树,git如何找到东西?我以为git对象存储区中有一棵正在工作的树,这就是暂存SHA指向并提交的内容
akantoword

@akantoword:git将有关提交和分支的所有信息存储在某个地方。提交可能主要是文件的先前版本与新版本之间的区别。工作树只是其在特定时间的真实内容的快照。无论如何,有了工作树,您就可以在提交和分支之间来回切换。如果需要,您甚至可以在其他工作树上签出。
user276648 '16

246

我添加此答案是因为到达此处(具有相同问题)后,没有一个答案真正描述了从无到有完全可用的远程(裸机)存储库所需的所有必需步骤。

注意:此示例使用本地路径作为裸仓库的位置,但是其他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 repo的git文件填充该文件夹。就目前而言,这个仓库是无用的-它没有提交,更重要的是,没有分支。尽管可以克隆此存储库,但不能从中提取。

接下来,我们需要创建一个工作文件夹。有两种方法可以执行此操作,具体取决于您是否已有文件。

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将无济于事。但是没关系,现在我们有了第一个提交,我们可以推送并在裸仓库中创建master。

> 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

至此,我们有了一个功能齐全的裸仓库,可以在master分支上的其他地方克隆它,以及可以拉入和推入的本地工作副本。

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

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

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

至此,我们有了第一个提交和一个本地master分支,我们需要将其变成远程跟踪的上游分支。

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

请注意-ugit push上的标志以设置(新)跟踪的上游分支。和以前一样,我们现在有一个功能齐全的裸仓库,可以在主分支上的其他位置克隆它,也可以将其拉入和推入本地工作副本。

所有这些对某些人来说似乎都是显而易见的,但是git在最好的情况下使我感到困惑(这是错误消息,并且状态消息确实需要重做)-希望对其他人有所帮助。


4
有趣。当然比我的答案更详细。+1
VonC

13
这个答案解决了我的问题,应该是公认的答案,希望越来越多的人可以投票赞成。
2015年

11
您应该为这样的答案收取费用
Arthur Tarasov

2
作为新的git用户,此答案对我有极大的帮助,感谢您撰写本文!
sidewinderguy

1
这是一个绝妙的答案。对我们单位有很大帮助。
wobsoriano

33

一一回答您的问题:

裸仓库是没有工作树的仓库。这意味着它的全部内容就是.git目录中的内容。

您只能commit通过push从本地克隆访问存储库来裸露存储库。它没有工作树,因此没有修改文件,也没有更改。

拥有中央存储库的唯一方法就是拥有一个bare存储库。


22

您还可以要求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
是Barry

17

这应该足够了:

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

查看更多详细信息“ GIT:如何更新裸仓库? ”。
笔记:

  • 您可以origin为裸仓库回传远程引用使用不同于“ ”的名称。
  • 这不会推送您的标签,为此您需要一个单独的标签git push --tags origin

5

很好地验证您推送的代码是否已提交。

通过使用--relative选项显式设置路径,可以在裸存储库上获取更改日志。

$ cd test_repo
$ git log --relative=/

这将向您显示已提交的更改,就好像这是常规的git repo。


5

根据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

那个config命令:它最终如何应用于您刚刚创建的.git目录?
GreenAsJade

我不确定我是否理解您的问题?你能更精确吗?既然你有你的git仓库初始化,您可以将其配置多达你想用命令“混帐配置” ..
杰克

@GreenAsJade这是因为您仍在git存储库的文件夹中,因此它适用于此(git config的默认值类似于--local选项)。
BlueCoder

2

--bare标志创建的存储库没有工作目录。裸存储库是中央存储库,您不能在此处编辑(存储)代码来避免合并错误。

例如,当您在本地存储库(计算机1)中添加文件并将其推送到裸存储库时,您在裸存储库中看不到该文件,因为它始终为“空”。但是,您确实将某些内容推送到存储库,并且可以通过在服务器(计算机2)中克隆另一个存储库来清楚地看到它。

机器1中的本地存储库和机器2中的“副本”存储库都是非裸机。 裸仓库和非裸仓库之间的关系

该博客将帮助您理解它。https://www.atlassian.com/git/tutorials/setting-up-a-repository


0

您可以执行以下命令来初始化本地存储库

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存储库的各个方面。 初学者入门

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.