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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4107239/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-19 04:42:58  来源:igfitidea点击:

Git create remote repository on push

gitgit-pushgit-remotegit-config

提问by Michael van Rooijen

I have been trying to figure this one out but I am having a hard time doing so. I am currently working on an open source project that requires me to allow a user to pushto remote repository withoutit already existing there. I want to avoid manually logging in to a server and running git initor git init --bare.

我一直在尝试解决这个问题,但我很难做到这一点。我目前正在开发一个开源项目,该项目要求我允许用户送到远程存储库,该存储库存在。我想避免手动登录服务器并运行git initgit init --bare.

For obvious reasons, I get the following error when trying to push my local repository to a path that doesn't point to an existing repository on the remote server:

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

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

But I would like to be able to run for example the following command:

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

git push origin master

And have that create /myrepoin /var/repositoriesif it does not yet exist. How would I be able to accomplish this? I would assume it is some kind of (global) git configsetting you would probably set on the remote server, or otherwise a (repository specific) git configlocally, but I couldn't figure it out.

并具有可创建/myrepo/var/repositories,如果不存在了。我怎么能做到这一点?我认为它是您可能会在远程服务器上设置的某种(全局)git 配置设置,或者是本地的(特定于存储库的)git 配置,但我无法弄清楚。

Any help would be much appreciated!

任何帮助将非常感激!

Thanks!

谢谢!

采纳答案by Chris Kooken

  1. Checkout and track the branch from the remote:

    git checkout -t origin/funbranch
    
  2. Branch off of it:

    git checkout -b mybranch
    
  3. Push your new one up, it will create a new branch automatically on the remote:

    git push origin mybranch
    
  1. 从远程签出并跟踪分支:

    git checkout -t origin/funbranch
    
  2. 它的分支:

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

    git push origin mybranch
    

It should say "created new remote branch origin/mybranch"

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

If you are still getting "Remote end Hung up", it sounds like a security thing. Do you have SSH keys installed correctly, and do you have write permissions on the remote server?

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

The way most open source projects work, you have to create a fork (a clone inherently) that you use to do your work because most of the time you don't have write permissions to the repo. When you have changes, you will then send a pull request to the repository owner, and he/she will pull from your fork the changes that they want.

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

回答by Cascabel

There is currently no way to use git pushto create a repository on the remote. The best you can do is write a one-liner script something like this:

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

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

Hopefully you can ssh in; if you can't, you could use some kind of filesystem access to just manually create the repo by dumping in the appropriate file/directory structure (maybe create it locally and copy). You might also create a named remote along the way.

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

This was actually one of the most requested featureson the 2010 Git Survey - so maybe you'll get your wish sometime in the next year!

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

回答by Pikrass

You can write a wrapper script on the remote, and prepend command="/path/to/wrapper" to the authorized_keys' lines.

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

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

In this wrapper you would check SSH_ORIGINAL_COMMAND. Git issues these commands:

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

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

If SSH_ORIGINAL_COMMAND is not empty and starts with one of these, you check the path, create the repository if necessary, install any configuration you need in it, and execute the command.

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

If SSH_ORIGINAL_COMMAND is empty and you want to provide users with shell access, you invoke a shell.

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

If SSH_ORIGINAL_COMMAND is not empty but doesn't start with a git command, if you want to allow users to have shell access, you just execute the command provided.

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

Here's a bit of Ruby code to demonstrate. Note that I didn't test it and there's room for improvement (for example we should not hardcode /bin/bash).

这里有一些 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

You can also pass an argument to this script in the authorized_keys to identify users and choose whether they should have shell access. I also do this to control access on a per-repository basis. If you want to carry this argument to the git hooks, just create an environment variable.

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

回答by AsherMaximum

I know this is an old question, but I stumbled upon this while googling for something else.

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

The best way I've found to be able to push to a remote server and have it create a repository if it doesn't exists is to use gitolite. Look at the install guides for it, it's very easy to setup, and if you change some config settings you can have it use your exiting /var/repositories to store the repos.

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