Git在推送时创建远程存储库

时间:2010-11-05 15:14:20

标签: git git-push git-remote git-config

我一直在努力想出这个,但我很难这样做。我目前正在开发一个开源项目,要求我允许用户推送到远程存储库,而不存在。我想避免手动登录服务器并运行git initgit init --bare

由于显而易见的原因,当我尝试将本地存储库推送到不指向远程服务器上的现有存储库的路径时,我收到以下错误:

fatal: '/var/repositories/myrepo' does not appear to be a git repository
fatal: The remote end hung up unexpectedly

但我希望能够运行以下命令:

git push origin master

如果它不存在,请在/myrepo中创建/var/repositories。我怎么能做到这一点?我认为它可能是某种(全局)git config 设置你可能在远程服务器上设置,或者在本地设置(特定于存储库)git config 但是我无法理解。

非常感谢任何帮助!

谢谢!

4 个答案:

答案 0 :(得分:25)

目前无法使用git push在远程数据库上创建存储库。你能做的最好的事情就是写一个像这样的单行脚本:

#!/bin/bash
ssh $1 "git init --bare $2" &&
git push ssh://$1/$2

希望你能进入;如果你不能,你可以使用某种文件系统访问,只需通过转储到适当的文件/目录结构手动创建repo(可能在本地创建并复制)。您也可以在此过程中创建一个命名的遥控器。

这实际上是2010年Git调查中最requested features之一 - 所以也许你会在明年的某个时候得到你的愿望!

答案 1 :(得分:8)

您可以在遥控器上编写包装器脚本,并将command =“/ path / to / wrapper”添加到authorized_keys的行中。

command="/usr/local/bin/gitaccess" ssh-rsa ...

在此包装器中,您将检查SSH_ORIGINAL_COMMAND。 Git发出这些命令:

git receive-pack '/path/provided' # when pushing
git upload-pack '/path/provided' # when pulling

如果SSH_ORIGINAL_COMMAND不为空并以其中一个开头,则检查路径,根据需要创建存储库,在其中安装所需的任何配置,然后执行命令。

如果SSH_ORIGINAL_COMMAND为空,并且您希望为用户提供shell访问权限,则可以调用shell。

如果SSH_ORIGINAL_COMMAND不为空但不以git命令启动,如果要允许用户具有shell访问权限,则只需执行提供的命令。

这里有一些Ruby代码要演示。请注意,我没有测试它,还有改进的余地(例如我们不应该硬编码/ bin / bash)。

#!/usr/bin/env ruby
orig_command = ENV['SSH_ORIGINAL_COMMAND']
if orig_command.nil?
    # If you want to preserve shell access
    exec '/bin/bash' # not tested, I hope it's interactive if executed this way
end

cmd_parts = orig_command.match /([a-z-]+) '([a-z0-9.\/]+)'/
if cmd_parts.nil?
    # If you want to preserve shell access
    exec '/bin/bash', '-c', orig_command
end

command = cmd_parts[1]
path = '/var/repositories/'+cmd_parts[2] # not secured (could contain '..')

if command == 'git-receive-pack' || command == 'git-upload-pack'
    if not File.directory?(path)
        `git init --bare #{path}` # not secured, I didn't escape path
        # Do any configuration here
    end
    exec 'git-shell', '-c', "#{command} '#{path}'"
end

# If you want to preserve shell access
exec '/bin/bash', '-c', orig_command

您还可以在authorized_keys中将此参数传递给此脚本,以识别用户并选择是否应具有shell访问权限。我这样做也是为了控制每个存储库的访问。如果你想把这个参数带到git钩子,只需创建一个环境变量。

答案 2 :(得分:6)

  1. 从远程登出并跟踪分支:

    git checkout -t origin\funbranch
    
  2. 分支:

    git checkout -b mybranch
    
  3. 推新你的,它将在遥控器上自动创建一个新的分支:

    git push origin mybranch
    
  4. 它应该说“创建了新的远程分支origin \ mybranch”

    如果您仍然“远程端挂起来”,这听起来像是安全的事情。您是否正确安装了SSH密钥,并且您是否具有远程服务器的写权限?

    大多数开源项目的工作方式,你必须创建一个用来完成工作的fork(一个克隆本身),因为大多数时候你没有对repo的写权限。当您进行更改时,您将向存储库所有者发送拉取请求,并且他/她将从您的分支中提取他们想要的更改。

答案 3 :(得分:2)

我知道这是一个老问题,但我在谷歌搜索其他内容时偶然发现了这个问题。

我发现能够推送到远程服务器并让它创建存储库(如果不存在)的最佳方法是使用gitolite。查看它的安装指南,它很容易设置,如果你更改了一些配置设置,你可以使用你现有的/ var / repositories来存储回购。