29

我一直试图弄清楚这一点,但我很难做到这一点。我目前正在开发一个开源项目,该项目要求我允许用户送到远程存储库,而该存储库尚未存在。我想避免手动登录到服务器并运行git initor git 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

4 回答 4

27

目前没有办法git push在远程创建存储库。你能做的最好的就是写一个像这样的单行脚本:

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

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

这实际上是 2010 年 Git 调查中最受要求的功能之一——所以也许你会在明年的某个时候实现你的愿望!

于 2010-11-05T17:59:00.627 回答
10

您可以在遥控器上编写一个包装脚本,并将 command="/path/to/wrapper" 附加到授权密钥的行中。

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 挂钩,只需创建一个环境变量。

于 2013-05-04T10:04:43.420 回答
4
  1. 从远程签出并跟踪分支:

    git checkout -t origin/funbranch
    
  2. 分支出来:

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

    git push origin mybranch
    

它应该说“创建了新的远程分支源/mybranch”

如果您仍然收到“远程端挂断”,这听起来像是一个安全问题。您是否正确安装了 SSH 密钥,并且您在远程服务器上是否具有写入权限?

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

于 2010-11-05T15:18:28.957 回答
2

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

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

于 2012-06-14T14:41:39.297 回答