2010-11-05 10 views
22

Ich habe versucht, dieses herauszufinden, aber ich habe es schwer, so zu tun. Ich arbeite derzeit an einem Open-Source-Projekt, das erfordert, dass ich einen Benutzer zu Push- zu Remote-Repository ohne es bereits dort vorhanden ist. Ich möchte es vermeiden, mich manuell bei einem Server anzumelden und git init oder git init --bare auszuführen.Git erstellen Remote-Repository auf Push

Aus offensichtlichen Gründen bekomme ich folgende Fehlermeldung beim Versuch meines lokalen Repository auf einen Pfad zu schieben, die auf dem Remote-Server zu einem vorhandenen Repository verweisen nicht:

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

Aber ich mag sein kann beispielsweise den folgenden Befehl auszuführen:

git push origin master 

Und die /myrepo in /var/repositories haben zu erstellen, wenn es noch nicht existiert. Wie könnte ich das erreichen? Ich würde annehmen, es ist eine Art von (global) git config Einstellung würden Sie wahrscheinlich auf dem Remote-Server setzen, oder sonst eine (Repository-spezifische) git config vor Ort, aber ich konnte es nicht herausfinden.

Jede Hilfe wäre sehr willkommen!

Vielen Dank!

Antwort

6
  1. Kasse und verfolgen Sie den Zweig aus der Fernbedienung:

    git checkout -t origin\funbranch 
    
  2. abzweigen davon:

    git checkout -b mybranch 
    
  3. Schieben Sie Ihr neues, wird es einen neuen Zweig erstellen automatisch auf der Fernbedienung:

    git push origin mybranch 
    

Es sollte „erstellt neuen Remote-Zweig Herkunft \ mybranch“

sagt Wenn Sie noch „Remote Ende Hung up“ bekommen, es klingt wie eine Sicherheits Sache. Haben Sie SSH-Schlüssel korrekt installiert und haben Sie Schreibrechte auf dem Remote-Server?

Die Art und Weise, wie die meisten Open-Source-Projekte funktionieren, müssen Sie einen Fork (einen inhärenten Klon) erstellen, den Sie für Ihre Arbeit verwenden, da Sie meist keine Schreibberechtigung für den Repo haben. Wenn Sie Änderungen vorgenommen haben, senden Sie eine Pull-Anforderung an den Repository-Eigentümer, und er/sie wird die gewünschten Änderungen von Ihrer Verzweigung ziehen.

+1

Hallo. Danke für die Antwort! Während dies eine gültige Antwort für wahrscheinlich die meisten Leute ist, die diese Frage betrachten, ist es nicht _exactly_ der, den ich suchte. Ich muss in der Lage sein, meinen lokalen __develop__-Zweig zum Beispiel in einen entfernten __staging-Zweig zu schieben. Aber ich möchte keinen neuen Zweig erstellen, nur um das Tracking und alles zu erreichen. Kennen Sie eine andere Möglichkeit, dies zu erreichen, ohne Änderungen an meinem lokalen Repository vorzunehmen? Tut mir leid, wenn die Frage ein wenig unklar ist, was ich versuche zu tun ist wahrscheinlich nicht sehr häufig getan. :) –

+5

@Michael: Dein Kommentar hier klingt überhaupt nicht wie deine Frage. Hier sprichst du einen lokalen Zweig zu einem anderen Remote-Zweig (der vielleicht existiert oder nicht existiert). Bei Ihrer Frage ging es jedoch darum, zu einer Remote zu gelangen, wo das * Repository * noch nicht existiert und erstellt werden muss. – Cascabel

22

Es gibt derzeit keine Möglichkeit git push zu verwenden, um ein Repository auf der Fernbedienung zu erstellen. Das Beste, was Sie tun können, ist ein One-Liner-Skript zu schreiben, so etwas wie:

Hoffentlich können Sie ssh in; Wenn dies nicht möglich ist, können Sie eine Art Dateisystemzugriff verwenden, um den Repo manuell zu erstellen, indem Sie die entsprechende Datei-/Verzeichnisstruktur ablegen (möglicherweise lokal erstellen und kopieren). Sie können auch eine benannte Fernbedienung auf dem Weg erstellen.

Dies war tatsächlich eine der requested features auf der Git Umfrage 2010 - also vielleicht bekommen Sie Ihren Wunsch irgendwann im nächsten Jahr!

+0

Danke für die Antwort und Entschuldigung für meine späte Antwort. Was du gesagt hast, sollte tatsächlich funktionieren. Ja, ich habe die Fähigkeit zu SSH. Ich habe dieses Problem mit der PushAnd-Bibliothek auf GitHub gelöst. Ich bin nicht ganz sicher, warum es mit dieser Bibliothek funktioniert, aber es funktioniert! Ich glaube, es installiert ein Post-Push-Hook/Skript, das einen Befehl ausführt, um ein Repository und ähnliches zu initialisieren. –

+0

Um '&&' über zwei Zeilen zu vermeiden, warum nicht 'bash -e' verwenden? Sie können auch 'git init --bare/pfad/zu/$ 2' ausführen. – Eric

+0

@Eric Es war nur ein Beispiel, aber ich bevorzuge normalerweise explizite Fehlerbehandlung (muss sich nicht darum kümmern, was bash mit -e tut und nicht erlaubt) und in der Lage sein, zu zwicken, copy-paste in andere Skripte und und so weiter, ohne sich um Verhaltensänderungen zu kümmern. – Cascabel

2

Ich weiß, das ist eine alte Frage, aber ich stolperte darüber, während für etwas anderes googlen.

Der beste Weg, den ich gefunden habe, um auf einen Remote-Server zu pushen und ein Repository erstellen zu lassen, wenn es nicht existiert, ist die Verwendung von Gitolit. Sehen Sie sich die Installationshandbücher dafür an, es ist sehr einfach einzurichten, und wenn Sie einige Konfigurationseinstellungen ändern, können Sie Ihre vorhandenen/var/repositories verwenden, um die Repos zu speichern.

7

Sie können ein Wrapper-Skript auf der Fernbedienung schreiben und den Zeilen authorized_keys command = "/ path/to/wrapper" voranstellen.

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

In diesem Wrapper würden Sie SSH_ORIGINAL_COMMAND überprüfen. Git gibt diese Befehle:

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

Wenn SSH_ORIGINAL_COMMAND nicht leer ist und beginnt mit einem von diesen, können Sie den Pfad überprüfen, erstellen Sie das Repository, falls erforderlich, installieren Sie eine beliebige Konfiguration Sie es brauchen, und den Befehl auszuführen.

Wenn SSH_ORIGINAL_COMMAND leer ist und Sie Benutzern Shellzugriff gewähren möchten, rufen Sie eine Shell auf.

Wenn SSH_ORIGINAL_COMMAND nicht leer ist, aber nicht mit einem Git-Befehl beginnt, wenn Sie Benutzern den Shell-Zugriff erlauben möchten, führen Sie einfach den bereitgestellten Befehl aus.

Hier ist ein bisschen Ruby-Code zu demonstrieren. Beachten Sie, dass ich es nicht getestet habe und es gibt Raum für Verbesserungen (zum Beispiel sollten wir nicht hartcodieren/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 

können Sie auch ein Argument dieses Skript in der authorized_keys passieren Benutzer zu identifizieren und zu entscheiden, ob sie eine Shell-Zugang haben sollte. Ich tue dies auch, um den Zugriff auf einer Repository-Basis zu steuern. Wenn Sie dieses Argument an die Git-Hooks übergeben möchten, erstellen Sie einfach eine Umgebungsvariable.

+0

Diese Antwort sollte stimmen.Ich habe das nicht versucht, aber es ist vernünftig. – septianw