2010-11-05 87 views
22

我一直在试图找出这一个,但我很难做到这一点。我目前正在开发一个开源项目,要求我允许用户将到远程存储库而不是它已经存在那里。我想避免手动登录到服务器并运行git initgit init --bareGit在推送时创建远程存储库

出于显而易见的原因,我想我的本地库推到不指向现有资源库的远程服务器上的路径时,遇到下列错误:

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

但我想是能够例如运行以下命令:

git push origin master 

而且具有在/var/repositories创建/myrepo如果它不存在。我将如何能够做到这一点?我会认为它是某种(全局)git config设置你可能会设置在远程服务器上,或者在本地设置为(存储库特定)git config,但我无法弄清楚。

任何帮助将不胜感激!

谢谢!

回答

6
  1. 结帐并跟踪从远程分支:

    git checkout -t origin\funbranch 
    
  2. 分公司关闭它:

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

    git push origin mybranch 
    

应该说“创造了新的远程分支来源\ mybranch”

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

大多数开源项目的工作方式是,您必须创建一个用于完成工作的叉(克隆本身),因为大多数时候您没有对该仓库的写入权限。当你有变化时,你将发送一个拉取请求给资源库所有者,他/她将从你的分支中提取他们想要的变化。

+1

嗨。谢谢回复!尽管对于大多数观看这个问题的人来说这是一个有效的答案,但它并不是我正在寻找的那个。我需要能够推动我的本地__develop__分支,例如远程__staging__分支。但我不想创建一个新的分支来完成跟踪和所有。你知不知道这可能是可以实现的,而无需对本地存储库进行更改?对不起,如果问题有点不清楚,我想要做的可能不是很常见。 :) – 2010-11-05 15:55:49

+5

@Michael:你的评论在这里听起来根本不像你的问题。在这里你正在谈论推送一个本地分支到不同的远程分支(可能存在也可能不存在)。然而,你的问题是关于推送到* repository *尚不存在的远程,并且必须创建。 – Cascabel 2010-11-05 17:49:11

22

目前无法使用git push在远程创建存储库。你可以做的最好的事情是写一个这样的脚本:

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

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

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

+0

感谢您的回复,并对我迟到的回复感到抱歉。你所说的应该确实有效。是的,我有SSH的能力。我实际上使用GitHub上的PushAnd库解决了这个问题。我不完全确定它为什么可以与这个库安装,但它确实!我相信它会安装一个post-push hook /脚本,它运行一些命令来初始化一个存储库等。 – 2010-11-19 05:57:23

+0

为了避免两行中的&&,为什么不使用'bash -e'?你也可以运行'git init --bare/path/to/$ 2'。 – Eric 2017-07-29 17:33:14

+0

@Eric这只是一个例子,但我通常更喜欢明确的错误处理(不必担心bash会做什么,不允许使用-e),并且能够调整,复制粘贴到其他脚本中,以及所以不用担心改变行为。 – Cascabel 2017-07-29 18:11:50

2

我知道这是一个古老的问题,但我偶然发现了这个问题,同时用其他的东西搜索。

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

7

您可以在远程编写一个包装脚本,并在authorization_keys的行前加上command =“/ path/to/wrapper”。

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

在这个包装中,您将检查SSH_ORIGINAL_COMMAND。混帐发出以下命令:

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

+0

这个答案应该被投票了。我没有尝试过,但这是合理的。 – septianw 2015-04-27 03:34:07

相关问题