Wie verwende ich Git-Bundle, um die Entwicklung synchron zu halten?

70

Ich muss meine Entwicklungsbäume auf verschiedenen Computern synchron halten, ohne dass eine Netzwerkverbindung zwischen ihnen besteht.

Wir haben ein zentrales Git-Repository und ich arbeite normalerweise an meinem eigenen Klon auf meinem Bürocomputer. Manchmal muss ich etwas auf einem anderen Computer entwickeln, der nie mit dem Büronetzwerk verbunden ist. Keiner der Computer ist jemals mit dem Internet verbunden. Die Entwicklung kann auf beiden Computern zwischen den Synchronisierungen durchgeführt werden.

Ich habe die Hilfeseiten für Git-Bundle gelesen , das als das beste Tool erscheint, bin mir aber nicht sicher, wie ein guter Workflow eingerichtet werden könnte.

Können Sie mir Ratschläge oder Hinweise geben?

matli
quelle
1
Wenn sie mit dem Internet verbunden sind, können Sie sie mit DopBox verwenden: siehe stackoverflow.com/questions/3632723/git-with-dropbox/…
VonC
1
Entschuldigung, keiner von ihnen wird jemals mit dem Internet verbunden sein. Das wurde der Frage hinzugefügt.
Matli

Antworten:

112

Bündel!

Der Workflow mit Git-Bundle wird im Wesentlichen der gleiche sein wie jeder andere Workflow. Dies scheint kein besonders hilfreicher Rat zu sein, aber hier ist es: Verwenden Sie den Workflow, den Sie normalerweise verwenden würden, und ersetzen Sie "Push / Pull" durch "Tragen Sie ein Bundle auf einem Flash-Laufwerk von hier nach dort und ziehen Sie dann".

Die Manpage bietet tatsächlich eine ziemlich gute Anleitung, um damit loszulegen, obwohl es sich eher um ein Einwegbeispiel handelt. Der Vollständigkeit halber hier eine leicht modifizierte Version, die zeigt, wie Informationen in beide Richtungen verschoben werden:

# on hostA, the initial home of the repo
hostA$ git bundle create hostA.bundle --branches --tags

# transfer the bundle to hostB, and continue:
hostB$ git clone /path/to/hostA.bundle my-repo
# you now have a clone, complete with remote branches and tags
# just to make it a little more obvious, rename the remote:
hostB$ git remote rename origin hostA

# make some commits on hostB; time to transfer back to hostA
# use the known master branch of hostA as a basis
hostB$ git bundle create hostB.bundle ^hostA/master --branches --tags

# copy the bundle back over to hostA and continue:
hostA$ git remote add hostB /path/to/hostB.bundle
# fetch all the refs from the remote (creating remote branches like hostB/master)
hostA$ git fetch hostB
# pull from hostB's master, for example
hostA$ git pull

# make some commits on hostA; time to transfer to hostB
# again, use the known master branch as a basis
hostA$ git bundle create hostA.bundle ^hostB/master --branches --tags
# copy the bundle to hostB, **replacing** the original bundle
# update all the refs
hostB$ git fetch hostA

# and so on and so on

Das Wichtigste ist, dass Sie ein Bundle als Fernbedienung hinzufügen und wie mit jeder anderen Fernbedienung damit interagieren können. Um diese Fernbedienung zu aktualisieren, legen Sie einfach ein neues Bundle ab und ersetzen Sie das vorherige.

Ich habe auch einen etwas anderen Ansatz bei der Auswahl einer Basis gewählt. Die Manpage verwendet Tags, die immer mit den letzten Verweisen auf dem neuesten Stand gehalten werden, die auf den anderen Host übertragen wurden. Ich habe einfach die Remote-Zweige verwendet, die sich auf die letzten vom anderen Host übertragenen Refs beziehen . Es ist ein bisschen ineffizient; Sie werden am Ende mehr bündeln als nötig, da es einen Schritt zurück liegt. Aber Flash-Laufwerke sind groß, Bundles sind klein, und die Verwendung der bereits vorhandenen Refs, anstatt einen zusätzlichen Schritt unternehmen und auf Tags achten zu müssen, spart viel Aufwand.

Das einzige, was Bundles zu Problemen macht, ist, dass Sie nicht auf sie drängen und sie nicht "neu gründen" können. Wenn Sie das Bundle auf einer neuen Basis haben möchten, müssen Sie es neu erstellen. Wenn Sie neue Commits möchten, müssen Sie diese neu erstellen. Dieser Ärger gibt Anlass zu meinem nächsten Vorschlag ...

Repo auf einem USB-Stick

Ehrlich gesagt, wenn Ihr Repo nicht wirklich groß ist, könnte dies genauso einfach sein. Wenn Sie einen nackten Klon auf ein USB-Stick legen, können Sie von beiden Computern aus darauf drücken und daraus ziehen. Behandle es wie deine Netzwerkverbindung. Müssen Sie zum zentralen Repo wechseln? Steck es ein!

Cascabel
quelle
Ein großes Lob für den USB-Stick erwähne ich auch. Könnte damit anfangen.
Akauppi
Die richtige Reihenfolge der Argumente für git remote addist nameund erst nach - url.
Shytikov
4
Übrigens funktioniert dies nur dann gut, wenn die Commits im Commit-Diagramm hostBnahe beieinander liegen hostA/master. Wenn Sie beispielsweise an einem Zweig arbeiten würden experimental, der vor mastersehr langer Zeit gegabelt wurde, würde der Befehl git bundle create hostB.bundle ^hostA/master --branches --tagsein großes Bündel mit der gesamten Geschichte von erstellen experimental. Dies ist kein grundlegendes Problem bei diesem Ansatz, sondern nur etwas, bei dem man vorsichtig sein muss. PS. Für andere über die fragen , ^commitSyntax, bedeutet es , „alle Commits , die nicht Vorfahren sind commit(siehe. git-rev-parse, SPECIFYING REVISIONS)
opqdonut
2
git bundle create hostA.bundle --branches --tagsführte zu einem Bundle, das beim Versuch, daraus zu klonen, den Fehler " remote HEAD refers to nonexistent ref, unable to checkout" ergab . Verwenden git bundle create hostA.bundle --allscheint für mich zu funktionieren.
Michael Burr
2
Ich habe eine (hoffentlich) benutzerfreundliche Bash-Implementierung dieser Technik geschrieben - siehe github.com/cxw42/git-tools/blob/master/wormhole . Kommentare willkommen - YMMV - keine Garantie :).
cxw
10

@ Jefromi Antwort war großartig - 10x besser als die Git-Dokumente, die ausführlich über unverständliche Anforderungen und Aktionen sprechen.

Es ist immer noch etwas kompliziert, daher ist hier der einfachste Fall, der einmal synchronisiert wird (in meinem Fall: FROM: ein Offline-Laptop mit defekter WLAN-Karte, TO: ein Desktop mit Netzzugang). Basierend auf der Antwort von @ Jefromi scheint dies gut zu funktionieren:

AHEAD = Maschine, die einige Commits voraus ist. HINTER = Maschine, auf die Sie die Commits kopieren möchten

1. AHEAD: git-bundle create myBundleName.bundle --branches --tags

BEIDE: kopiere myBundleName.bundle (per E-Mail, USB, was auch immer)

HINTER: (Platzieren Sie die Datei myBundName.bundle an einer beliebigen Stelle außerhalb des Projektordners.)

2. BEHIND: cd [the project folder]
3. BEHIND: git pull [path to the bundle file]/myBundleName.bundle master

Solange Sie den Verzweigungsnamen am Ende einfügen (standardmäßig, wenn Sie keine Verzweigungen verwenden, "master"), scheint dies gut zu funktionieren und ersetzt keine der internen Verweise auf BEHIND - also Sie kann immer noch mit / vom Ursprungsmaster synchronisieren.

Wenn BEHIND über einen Internetzugang verfügt, ist dies dennoch sicher:

(OPTIONAL) 4. BEHIND: git push

... und das Haupt-Repository wird aktualisiert, als ob Ihre Änderungen wie gewohnt lokal hinter BEHIND vorgenommen worden wären.

Adam
quelle