29

私はこれを理解しようとしてきましたが、それを行うのに苦労しています。私は現在、オープンソースプロジェクトに取り組んでおり、ユーザーがリモートリポジトリに存在していなくてもリモートリポジトリにプッシュできるようにする必要があります。サーバーに手動でログインしてまたはを実行することは避けたいです。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

4 に答える 4

27

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

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

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

これは、実際には2010 Git Surveyで最もリクエストの多かった機能の1つでした。そのため、来年中に希望を得ることができるかもしれません。

于 2010-11-05T17:59:00.627 に答える
10

リモートでラッパースクリプトを記述し、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フックに伝えたい場合は、環境変数を作成するだけです。

于 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キーが正しくインストールされていますか?また、リモートサーバーへの書き込み権限がありますか?

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

于 2010-11-05T15:18:28.957 に答える
2

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

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

于 2012-06-14T14:41:39.297 に答える