如何从本地创建一个远程Git仓库?

314

我有一个本地的Git仓库。我想在一个支持ssh的远程服务器上将它变成可用状态。我该怎么做?

9个回答

357

我认为你需要在远程端创建一个裸仓库,使用命令git init --bare,把远程端作为本地仓库的推送/拉取跟踪器添加(git remote add origin URL),然后在本地只需要执行git push origin master。现在任何其他的仓库都可以从远程仓库进行pull操作。


@Nips:是的,没错,抱歉。你确实推送单独的分支! - Kerrek SB
6
如果 git push origin master 失败并出现 "repository not found" 错误,请在远程端尝试执行 git update-server-info 命令,该命令需要在你执行过 git init --bare 的地方执行。 - HongKilDong
8
@KerrekSB 我能否在本地运行 git push origin master 后,自动在服务器上创建一个裸仓库? - Rishabh Agrawal
1
@HongKilDong,我尝试了git update-server-info,但是出现了错误:“fatal: Unable to look up Volumes (port 9418) (nodename nor servname provided, or not known)” - Nayef
我发现在做完这个之后,我必须使用--set-upstream 标志来与我的第一个 push 进行连接。 - chb
显示剩余3条评论

94
为了最初设置任何Git服务器,您必须将现有存储库导出到一个新的裸存储库 - 一个不包含工作目录的存储库。这通常很容易做到。为了克隆您的存储库以创建一个新的裸存储库,您需要使用 --bare 选项运行克隆命令。按照惯例,裸存储库目录以 .git 结尾,如下所示:
$ git clone --bare my_project my_project.git
Initialized empty Git repository in /opt/projects/my_project.git/

这个命令只取Git仓库本身,没有工作目录,并为它单独创建一个目录。

现在您有了一个裸仓库的副本,您只需要将其放在服务器上并设置协议即可。假设您设置了一个名为git.example.com的服务器,并且您具有SSH访问权限,您想将所有Git仓库存储在/opt/git目录下。您可以通过复制裸仓库来设置新的仓库:

$ scp -r my_project.git user@git.example.com:/opt/git

此时,其他具有SSH访问权限且对/opt/git目录具有读取权限的用户可以通过运行以下命令来克隆你的仓库:

$ git clone user@git.example.com:/opt/git/my_project.git

如果用户通过SSH进入服务器并对/opt/git/my_project.git目录具有写访问权限,则他们也将自动具有推送访问权限。如果您使用--shared选项运行git init命令,Git会自动将组写权限正确地添加到存储库中。
$ ssh user@git.example.com
$ cd /opt/git/my_project.git
$ git init --bare --shared

将Git存储库制作成裸版本并放置在一个您和协作者都有SSH访问权限的服务器上非常容易。这样,您就可以开始协作完成同一项目了。


6
在实际使用中,我认为scp解决方案比init --bare更好。但是,首先在本地克隆,然后复制到服务器上仍然感觉有点丑陋...希望Git有一个命令可以一次性完成它。 - leftaroundabout
1
+1是因为--shared对我有用。我想知道如果你使用git init --shared而不创建--bare会发生什么... - icedwater
1
在本地创建一个裸仓库,然后使用 scp 将其传输到远程,如果远程不支持 git init --bare(就像我使用的 git 1.5.5, 2008 版本一样),这种方法会更好。我认为即使远程没有安装 git,这种方法也应该可以工作。 - Yaroslav Nikitenko
2
参考链接:https://git-scm.com/book/en/v1/Git-on-the-Server-Getting-Git-on-a-Server - berbt
1
一个小提示:解决方案中的scp步骤是正确的,但它只适用于远程用户拥有常规shell的情况,如果用户使用git-shell,则无法正常工作。 - user1708042
1
这个,在我看来,应该是被接受的答案。表述得很好,更加清晰明了。谢谢。 - PKCLsoft

15

以上两种常用解决方案之间有一个有趣的区别:

  1. 如果您像这样创建裸仓库:

    cd     /outside_of_any_repo
    mkdir  my_remote.git
    cd     my_remote.git
    git init --bare
    

然后执行其它操作。

cd  /your_path/original_repo
git remote add origin /outside_of_any_repo/my_remote.git
git push --set-upstream origin master

然后 git 使用这种关系在 'original_repo' 中设置配置:

original_repo origin --> /outside_of_any_repo/my_remote.git/

采用第一种方法作为上游远程仓库,而上游远程仓库没有其他远程仓库的设置。

  1. 但是,如果你反过来做:

    (在原始仓库所在目录内)
    cd ..
    git clone --bare original_repo  /outside_of_any_repo/my_remote.git
    

那么'my_remote.git'将会在其配置中有'origin'指向回一个远程'original_repo',其中remote.origin.url等于本地目录路径,如果它将要被移动到服务器上,这可能不合适。

虽然稍后可以轻松删除掉这个“远程”引用,但是'original_repo'仍然必须设置为指向'my_remote.git'作为上游远程仓库(或指向它将要共享的任何位置)。 因此,在使用第二种方法时需要更多步骤才能达到相同的结果。但是第一种方法似乎更直接,只涉及较少的步骤,适用于从本地创建一个“中心裸共享仓库”,适用于移动到服务器上,我认为这取决于您希望远程仓库扮演的角色。(是的,这与文档中的描述不一致。)

注意:我是通过在本地系统上进行测试并逐个文件比较结果来学习上述内容的(截至编写本文于2019年8月初)。但是!我仍在学习,所以可能有更正确的方法。但是我的测试已经帮助我得出结论,即第一种方法是我目前首选的方法。


9
对于那些在Windows上创建本地副本并想在Unix系统上创建相应的远程存储库的人,需要注意一下。在Unix-like系统上,文本文件将使用LF结尾,在Windows上将使用CRLF结尾。如果您在设置换行符转换之前创建了Windows存储库,则会遇到问题。Git的默认设置是不进行转换,因此您的工作集使用CRLF,但存储库(即保存在.git下的数据)也将文件保存为CRLF。当您推送到远程时,保存的文件被按原样复制,不进行换行符转换。 您最终会在Unix-like存储库中得到CRLF,这不是您想要的。要在远程存储库中获得LF,您必须先确保本地存储库中存在LF,方法是通过重新规范化您的Windows存储库。这对您的Windows工作集没有可见影响,仍然使用CRLF结尾,但是当您推送到远程时,远程将正确地得到LF。我不确定是否有一种简单的方法可以告诉您Windows存储库中有哪些换行符 - 我猜您可以通过设置core.autocrlf=false然后克隆来测试它(如果存储库具有LF结尾,则克隆也将具有LF结尾)。

6

远程代码库通常是一个裸仓库,即没有工作目录的Git仓库。因为该代码库只用作协作点,所以在磁盘上没有快照被检出;它只是Git数据。最简单的说,裸仓库就是你的项目的 .git 目录里面的内容,而且仅仅只有这些内容。

您可以使用以下代码创建一个裸 Git 代码库:

$ git clone --bare /path/to/project project.git

远程git仓库的一种选择是使用SSH协议:

A common transport protocol for Git when self-hosting is over SSH. This is because SSH access to servers is already set up in most places — and if it isn’t, it’s easy to do. SSH is also an authenticated network protocol and, because it’s ubiquitous, it’s generally easy to set up and use.

To clone a Git repository over SSH, you can specify an ssh:// URL like this:

$ git clone ssh://[user@]server/project.git

Or you can use the shorter scp-like syntax for the SSH protocol:

$ git clone [user@]server:project.git

In both cases above, if you don’t specify the optional username, Git assumes the user you’re currently logged in as.

The Pros

The pros of using SSH are many. First, SSH is relatively easy to set up — SSH daemons are commonplace, many network admins have experience with them, and many OS distributions are set up with them or have tools to manage them. Next, access over SSH is secure — all data transfer is encrypted and authenticated. Last, like the HTTPS, Git and Local protocols, SSH is efficient, making the data as compact as possible before transferring it.

The Cons

The negative aspect of SSH is that it doesn’t support anonymous access to your Git repository. If you’re using SSH, people must have SSH access to your machine, even in a read-only capacity, which doesn’t make SSH conducive to open source projects for which people might simply want to clone your repository to examine it. If you’re using it only within your corporate network, SSH may be the only protocol you need to deal with. If you want to allow anonymous read-only access to your projects and also want to use SSH, you’ll have to set up SSH for you to push over but something else for others to fetch from.

更多信息请查阅参考文献:Git位于服务器端的协议


4

在当前代码文件夹中。

git remote add origin http://yourdomain-of-git.com/project.git
git push --set-upstream origin master

然后由...审核

git remote --v

4
在我的设置中,它不会创建远程代码库。这篇文章对我来说似乎只是建立到现有远程代码库的连接,而不是创建它。 - Dirk Schumacher
当您在您的域上创建一个同名的空仓库,然后将本地代码推送时,此方法可行。 - Swapnil Masurekar

3
您需要在远程服务器上创建一个目录。然后使用 "git init" 命令将其设置为仓库。每个新项目(每个新文件夹)都应该这样做。
假设您已经设置并使用了 ssh 密钥的 git,我编写了一个小的 Python 脚本,当从工作目录执行时,将设置一个远程并将目录初始化为 git 存储库。当然,您将不得不编辑脚本告诉它所有存储库的服务器和根路径(仅一次)。
请查看此处 - https://github.com/skbobade/ocgi

1

我有一台树莓派,可以通过公钥访问ssh(无需密码提示)。

在树莓派上我执行了以下命令:

mkdir -p /home/pi/my/repo
cd /home/pi/my/repo
git init --bare

在我的笔记本电脑上,我执行了以下操作:
git clone  ssh://pi@raspberry/home/pi/my/repo
cd myrepo
touch README.md
git add README.md
git commit -m "First commit"
git push

这就是全部


-3
通常情况下,您可以通过使用“init”命令来设置git存储库。
git init

在您的情况下,已经有一个可用的远程仓库。根据您如何访问远程仓库(使用用户名在URL中或处理验证的SSH密钥),只需使用clone命令:

git clone git@[my.url.com]:[git-repo-name].git

还有其他克隆存储库的方法。如果您在计算机上设置了SSH密钥并在拉取存储库时进行验证,则可以使用此方式调用它。如果要包含密码和用户名以登录到远程存储库,可以使用其他URL组合。


1
多么讽刺啊……今天有人给这个答案点了个踩,现在我正在努力推送我的文件。看来我需要一些 Git 的锻炼才能再次进入状态! - Alex Cio
8
我认为问题在于原帖作者想要一个解决方案来在ssh服务器上创建远程存储库,但你描述了如何从远程ssh服务器创建本地存储库。你没有回答问题。(不是我给你的评分低)。 - peterh

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