web-dev-qa-db-ja.com

Gitはプッシュでリモートリポジトリを作成します

私はこれを理解しようとしてきましたが、それを理解するのに苦労しています。私は現在、ユーザーがリモートリポジトリにプッシュなしすでに存在することを許可する必要があるオープンソースプロジェクトに取り組んでいます。サーバーに手動でログインしてgit initまたは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を作成してもらいます。どうすればこれを達成できますか?ある種の(global)git config設定であり、おそらくリモートサーバーで設定するか、そうでなければ(リポジトリ固有の)git configローカルであると思いますが、私はそれを理解できませんでした。

どんな助けでも大歓迎です!

ありがとう!

27
  1. リモートからブランチをチェックアウトして追跡します。

    git checkout -t Origin\funbranch
    
  2. それから分岐します:

    git checkout -b mybranch
    
  3. 新しいブランチを押し上げると、リモートに新しいブランチが自動的に作成されます。

    git Push Origin mybranch
    

「新しいリモートブランチOrigin\mybranchを作成しました」と表示されます。

それでも「リモートエンドがハングアップ」する場合は、セキュリティ上の問題のようです。 SSHキーが正しくインストールされており、リモートサーバーへの書き込み権限がありますか?

ほとんどのオープンソースプロジェクトが機能する方法では、ほとんどの場合、リポジトリへの書き込み権限がないため、作業に使用するフォーク(本質的にクローン)を作成する必要があります。変更がある場合は、リポジトリの所有者にプルリクエストを送信します。所有者は、必要な変更をフォークからプルします。

6
Chris Kooken

現在、git Pushを使用してリモートにリポジトリを作成する方法はありません。あなたができる最善のことは、次のようなワンライナースクリプトを書くことです。

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

うまくいけば、SSHで接続できます。できない場合は、ある種のファイルシステムアクセスを使用して、適切なファイル/ディレクトリ構造にダンプすることでリポジトリを手動で作成できます(おそらくローカルで作成してコピーします)。途中で名前付きリモコンを作成することもできます。

これは実際には2010年のGitサーベイで最も 要求された機能 の1つだったので、来年のいつかあなたの願いが叶うかもしれません!

26
Cascabel

リモートでラッパースクリプトを記述し、authorized_keysの行の前に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が空で、ユーザーにシェルアクセスを提供する場合は、シェルを呼び出します。

SSH_ORIGINAL_COMMANDが空ではないが、gitコマンドで始まらない場合、ユーザーにシェルアクセスを許可する場合は、提供されたコマンドを実行するだけです。

ここに少し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でこのスクリプトに引数を渡して、ユーザーを識別し、ユーザーにシェルアクセスを許可するかどうかを選択することもできます。また、リポジトリごとにアクセスを制御するためにもこれを行います。この引数をgitフックに伝えたい場合は、環境変数を作成するだけです。

8
Pikrass

これは古い質問だと思いますが、何か他のものを探しているときに、これに出くわしました。

リモートサーバーにプッシュして、リポジトリが存在しない場合にリポジトリを作成できるようにするための最良の方法は、gitoliteを使用することです。インストールガイドを見てください。セットアップは非常に簡単です。いくつかの構成設定を変更した場合は、既存の/ var/repositoriesを使用してリポジトリを保存できます。

2
AsherMaximum