2011-01-15 4 views
8

Ich versuche, eine leere Kopie eines Git-Repository beizubehalten und einige Probleme zu haben, die Remote-Tracking-Zweigstellen auf dem neuesten Stand zu halten. Ich erstelle die Remote-Tracking-Zweige wie folgt:Wie erhalte ich einen Remote-Tracking-Zweig, um in einem leeren Git-Repository auf dem neuesten Stand zu bleiben?

Dies scheint zu tun, was ich für diesen Zeitpunkt tun muss. Wenn ich jedoch Änderungen an origin mache und dann mit dem bloßen Repo abrufe, beginnen die Dinge auseinander zu fallen. Mein Workflow sieht wie folgt aus:

git fetch origin 

Es sieht aus wie alle Commits an diesem Punkt kommen, aber meine lokale Kopie von 0,1 wird nicht aktualisiert. Ich kann sehen, dass die Änderungen in das Repository gebracht wurden, indem Sie folgendermaßen vorgehen:

git diff 0.1 refs/remotes/origin/0.1 

Was muß ich tun, um meinen Tracking-Zweig mit der Updates der Fernbedienung aktualisiert zu bekommen? Ich fühle mich, als müsste ich irgendwo einen Schritt oder eine Flagge verpassen.

Aktualisiert: Zusätzliche Klärung

Normalerweise würde man in einem kahlen Repository schieben, anstatt laufen git aus ihm holen. Wenn Sie das arrangieren können, wird das Leben viel einfacher.

Hier ist ein wenig Klarheit über den Workflow.

Das öffentliche Git-Repository des Projekts wird auf GitHub gehostet. Ich verwalte das Projekt (Wiki, Ausgaben, Foren) mit Redmine. Redmine benötigt ein lokales, bloßes Repository, um zu funktionieren. Wenn GitHub Änderungen empfängt, pingt es Redmine. Redmine versucht dann, Änderungen von seinem Ursprung (GitHub) abzurufen.

Das funktioniert gut, wenn ich nur mit Master arbeite, aber es funktionierte nicht mit meinen Tracking-Filialen. Die Änderungen wurden importiert, wurden jedoch nicht im Redmine-Repository-Browser in der Verzweigung aufgeführt, da die lokalen Zweige nicht aktualisiert wurden.

Ich bin mir sicher, dass ich das anders hätte machen können, aber eine (generische) Lösung zu finden, die Tracking-Zweige zum Laufen zu bringen, war definitiv meine Vorliebe, da die meisten git-bezogenen Plugins für Redmine Dinge wie "git fetch" annehmen Herkunft "ist alles, was getan werden muss.

Siehe akzeptierte Antwort für die vollständige Lösung. Die --mirror Lösung scheint genau das zu sein, was in diesem Fall benötigt wird.

Antwort

17

Normalerweise würde man in ein bloßes Repository pushen, anstatt git fetch darin auszuführen. Wenn Sie das arrangieren können, wird das Leben viel einfacher.

Wenn Sie haben zu holen, anstatt zu schieben, und Sie möchten nur einen Spiegel der Herkunft in Ihrem nackten Repository erstellen, könnten Sie vermeiden, Remote-Tracking-Zweige vollständig. Wenn Sie diesen Spiegel von Grund auf neu starten, wird unter Charles Bailey darauf hingewiesen, dass Git diese Konfiguration für Sie vornehmen wird, wenn Sie das Repository zunächst mit git clone --mirror klonen.

Andernfalls könnten Sie einen ähnlichen Effekt mit erhalten:

git fetch origin +refs/heads/*:refs/heads/* 

Die + bedeutet, dass dies den Zustand Ihrer lokalen Niederlassungen mit denen aus der Fernbedienung überschrieben. Ohne die + werden Updates, die nicht Fast-Forward-Zusammenführungen sind, zurückgewiesen. Wenn dies jedoch nur ein Spiegel ist, sollte das keine Rolle spielen. (Können Sie konfigurieren diese die Standard-Aktion sein auf git fetch origin durch die Konfigurationsvariable remote.origin.fetch-+refs/heads/*:refs/heads/* setzen. Wenn Sie möchten, um Tags spiegeln und Remote-Tracking-Zweig vom Ursprung als auch, Sie +refs/*:refs/* stattdessen verwenden könnten.)

jedoch Wenn Sie, wie Sie ursprünglich fragen, Remote-Tracking-Zweigstellen verwalten und diese selektiv in lokale Zweigstellen zusammenführen möchten, können Sie die folgenden Schritte ausführen, aber ich empfehle sie nicht unbedingt, es sei denn, Sie sind die einzige Person, die dieses bare Repository verwendet. (Hinweis: ursprünglich hier schlug ich vor, mit "Git symbolisch-ref HEAD refs/heads/was auch immer", um Zweig und "git reset --soft" zu wechseln, um den Zweig Ref ändern - jedoch, Charles Bailey wies in den Kommentaren darauf hin, dass man kann Verwenden Sie "git update-ref refs/heads/was auch immer refs/remotes/origin/was auch immer", das erfordert nicht einen Zweig zuerst zu wechseln.)

Zuerst möchten Sie vielleicht überprüfen, ob die Aktualisierung der Branche haben würde war eine Fast-Forward-Zusammenführung, und danach aktualisieren Sie die Verzweigung. Beachten Sie, dass es hier eine Race Condition gibt, weshalb ich sage, dass Sie dies nur tun sollten, wenn Sie die einzige Person sind, die Ihr lokales Repository verwendet - der Check wäre nutzlos, wenn sich jemand anders zwischen diesen Schritten auf dem Ast bewegt.

  1. Sie können prüfen, ob ein Ersatz merge eine vorspulen wäre (das heißt, dass die Geschichte der origin/master umfasst master) durch git merge-base master origin/master mit git show-ref master zu vergleichen - sie gleich sein sollten. Oder Sie könnten das is-ancestor Skript in this question verwenden, die tun diese Befehle mit einigen zusätzlichen Kontrollen.)
  2. Schließlich können Sie Ihren aktuellen Zweig aktualisieren (master in diesem Fall) zu origin/master mit git update-ref refs/heads/master refs/remotes/origin/master

hinweisen, jedoch wie ich am Anfang gesagt, denke ich, dass die wirkliche Lösung, die Sie wollen, ist entweder:

  • Pushing in bloße Repository statt oder
  • Spiegeln die Fern nackten Reposi Genau wie ich oben beschrieben

Ich hoffe, das ist von einigem Nutzen.

+1

'git merge' erfordert immer einen funktionierenden Baum, Sie müssen' git update-ref' stattdessen in einem blanken Repository verwenden.Ich denke, Sie haben Recht, dass ein Spiegel eine bessere Lösung klingt. Es kann sich lohnen, ein nicht über 'git clone --spiegel 'hinzuzufügen. –

+0

@Charles Bailey: Der Grund, warum ich dachte, es könnte ein Fehler sein, ist, dass in der Quelle von butintin-merge.c ein Kommentar beginnt "An diesem Punkt brauchen wir eine echte Zusammenführung ..." nach dem Punkt, wo eine schnelle Vorwärts wäre getan worden - ich glaube nicht, dass der Index oder Arbeitsbaum bis zu diesem Punkt benötigt wird. Ich werde diese Bemerkung sowieso entfernen. –

+0

Sie könnten auf der Git-Mailing-Liste fragen, aber ich bin nicht davon überzeugt, dass es als ein Fehler betrachtet werden würde. Ich denke, dass es im Allgemeinen konsequenter ist, klar zwischen Befehlen zu unterscheiden, die keinen funktionierenden Baum erfordern und denen, die dies tun. Einen Befehl zu haben, der eine funktionierende Baumstruktur benötigt, ist eine komplexere Schnittstelle, die möglicherweise zu Missverständnissen führen kann. –

1

Wenn Sie fetch ändern, aktualisieren Remote-Änderungen Ihre eigene lokale Referenz für die Remote, origin/0.1 (dies verursacht nie irgendwelche Konflikte, da nie lokale Änderungen hostet). Um diese Änderungen zu importieren, können Sie git reset refs/remotes/origin/0.1 von 0.1, die den HEAD-Zweig (0.1) zeigen, auf das gleiche Commit wie der Remote-Zweig verweisen.

Beachten Sie, dass dadurch alle Änderungen an 0.1 verloren gehen, die nicht von der Fernbedienung kommen.

+1

Wenn ich die Frage richtig verstehe, wird das nicht funktionieren, da die Frage nach einem leeren Repository fragt und "git merge" und "git pull" einen funktionierenden Baum erfordern. –

+0

Oh, du hast Recht! Ich habe meine Antwort entsprechend modifiziert. – huitseeker

Verwandte Themen