Wie kann man auf ein nicht nacktes Git-Repository pushen?

150

Normalerweise arbeite ich auf einem Remote-Server über ssh (screen und vim), wo ich ein Git-Repository habe. Manchmal bin ich nicht online, daher habe ich ein separates Repository (von meiner Fernbedienung geklont) auf meinem Laptop.

Ich kann jedoch nicht von diesem Repository auf der Remote-Seite abrufen, da ich normalerweise hinter einer Firewall stehe oder keine öffentliche IP-Adresse habe.

Ich habe gelesen, dass ich nur in ein nacktes Repository pushen sollte. Wie soll ich dann meine Änderungen in mein Remote-Repository übertragen?

woky
quelle
3
Habe 2 Remote-Repos, ein nacktes und ein normales, und benutze Haken. scheint ein Ärger zu sein, aber laut git ready und dem offiziellen git-Wiki sollten Sie nur auf ein nacktes Repo drängen . Dies ist wahrscheinlich der Grund, warum die meisten Git-Repo-Hosts (z. B. GitHub, Bitbucket) Post-Receive-Hooks enthalten, sodass Sie an eine URL auf Ihrem Server POSTEN können, auf der beispielsweise ein Skript ausgeführt wird, das ausgeführt wird git pull github master.
Jake Berger

Antworten:

136

receive.denyCurrentBranch updateInstead

Diese Option wurde in Git 2.3 hinzugefügt und der Server aktualisiert seinen Arbeitsbaum, wenn er sauber ist.

Wenn Sie also sicherstellen, dass Sie immer ein Commit durchführen, bevor Sie lokal ziehen, und einen sauberen Arbeitsbaum auf dem Server behalten (was Sie tun sollten, um Zusammenführungskonflikte zu vermeiden), ist diese Option eine gute Lösung.

Beispielnutzung:

git init server
cd server
touch a
git add .
git commit -m 0
git config --local receive.denyCurrentBranch updateInstead

cd ..
git clone server local
cd local
touch b
git add .
git commit -m 1
git push origin master:master

cd ../server
ls

Ausgabe:

a
b
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
quelle
ist es möglich zu pushen, ohne ein nacktes Repo zu erstellen, wie es Heroku tut
ANinJa
2
@ANinJa Ich verstehe nicht, ist das nicht genau das, was mein Beispiel tut?
Ciro Santilli 法轮功 冠状 病 六四 事件 28
ist --localoptional?
Yukulélé
@ Yukulélé --localbetrifft nur das aktuelle Verzeichnis, --globalbetrifft alle Git-Repos mit ~/.gitconfig, siehe man git-config.
Ciro Santilli 法轮功 冠状 病 六四 事件 法轮功
1
danke @CiroSantilli 法轮功 改造 中心 六四 事件 法轮功 nach dem Lesen des Dokuments bestätige ich, dass es nicht notwendig ist "(Sie können sagen - lokal, aber das ist die Standardeinstellung)"
Yukulélé
146

Beste Option

Die wahrscheinlich sauberste, am wenigsten verwirrende und sicherste Möglichkeit, in Ihr nicht nacktes Remote-Repository zu pushen, besteht darin, auf dedizierte Zweige in der Fernbedienung zu pushen, die Ihre Laptop-Zweige darstellen.

Schauen wir uns den einfachsten Fall an und nehmen wir an, dass Sie in jedem Repo nur einen Zweig haben: master. Wenn Sie von Ihrem Laptop auf das Remote-Repo drücken, drücken Sie statt Master -> Master, Master -> Laptop-Master (oder einen ähnlichen Namen). Auf diese Weise wirkt sich der Push nicht auf den aktuell ausgecheckten Hauptzweig im Remote-Repo aus. Um dies vom Laptop aus zu tun, ist der Befehl ziemlich einfach:

git push origin master:laptop-master

Dies bedeutet, dass der lokale Master-Zweig in den Zweig "Laptop-Master" im Remote-Repository verschoben wird. In Ihrem Remote-Repo haben Sie einen neuen Zweig namens "Laptop-Master", den Sie dann in Ihren Remote-Master einbinden können, wenn Sie bereit sind.

Alternative Option

Es ist auch möglich, nur master -> master zu drücken, aber das Verschieben in den aktuell ausgecheckten Zweig eines nicht nackten Repos wird im Allgemeinen nicht empfohlen, da es verwirrend sein kann, wenn Sie nicht verstehen, was los ist. Dies liegt daran, git statusdass beim Verschieben in einen ausgecheckten Zweig der Arbeitsbaum nicht aktualisiert wird. Wenn Sie also in den ausgecheckten Zweig einchecken, in den verschoben wurde, werden genau die entgegengesetzten Unterschiede angezeigt wie beim letzten Verschieben. Besonders verwirrend wäre es, wenn der Arbeitsbaum vor dem Push verschmutzt wäre. Dies ist ein wichtiger Grund, warum dies nicht empfohlen wird.

Wenn Sie versuchen möchten, nur master -> master zu drücken, lautet der Befehl einfach:

git push origin

Wenn Sie jedoch zum Remote-Repo zurückkehren, möchten Sie höchstwahrscheinlich einen Vorgang ausführen, git reset --hard HEADum den Arbeitsbaum mit dem Inhalt zu synchronisieren, der übertragen wurde. Dies kann gefährlich sein , da nicht festgeschriebene Änderungen im Remote-Arbeitsbaum, die Sie beibehalten möchten, diese löschen. Stellen Sie sicher, dass Sie die Konsequenzen kennen, bevor Sie es versuchen, oder erstellen Sie zuerst ein Backup!

BEARBEITEN Seit Git 2.3 können Sie "Push-to-Deployment" -Git-Push verwenden: https://github.com/blog/1957-git-2-3-has-been-released . Das Verschieben in einen separaten Zweig und das anschließende Zusammenführen ist jedoch normalerweise besser, da eine tatsächliche Zusammenführung durchgeführt wird (daher funktioniert dies mit nicht festgeschriebenen Änderungen genauso wie die Zusammenführung).

Dan Moulding
quelle
1
Ist es möglich, die Verzweigung nach dem Drücken des Laptop-Masters zu automatisieren?
rdoubleui
3
@rdoubleui: Meinten Sie " Zusammenführen automatisieren "? Wenn ja, nein, ist es nicht möglich, die Zusammenführung zu automatisieren, da Zusammenführungen ohne menschliches Eingreifen nicht garantiert sind. Es kann Konflikte geben, die gelöst werden müssen.
Dan Moulding
7
in späteren versionen (?) git config receive.denyCurrentBranch ignoremuss vor dem
pushen
3
Tolle Antwort @DanMoulding, danke. @rdoubleui: Sie könnten immer eine Befehlszeile wie die folgende als Bash-Funktion speichern:git push origin master:laptop-master && ssh user@remotemachine 'cd repos_path && git merge laptop-master'
Rich
@rdoubleui Um das Zusammenführen zu automatisieren, können Sie gitolite verwenden und es einrichten (etwas kompliziert), damit das nicht-nackte Commit alles schmutzig macht und es mit dem Pre-git-Trigger auf die gitolite (nackte) Version schiebt. Wenn danach das Zusammenführen im Non-Bare-Modus nicht aufgelöst werden kann, wird Ihr Push abgelehnt, sodass Sie wissen, dass Sie zuerst ziehen, die Zusammenführungen auflösen und erneut drücken müssen. Ich habe das noch nicht eingerichtet, aber ich bin dabei und denke, dass es funktionieren kann.
17

Ich würde vorschlagen, ein Bare-Repository und ein lokal funktionierendes (nicht Bare) Repos auf Ihrem Server zu haben. Sie können Änderungen vom Laptop zum Server-Bare-Repo übertragen und dann von diesem Bare-Repo zum Server-Working-Repo übertragen. Der Grund, warum ich dies sage, ist, dass Sie möglicherweise viele vollständige / unvollständige Zweige im Server haben, die Sie auf dem Laptop replizieren möchten.

Auf diese Weise müssen Sie sich keine Gedanken über den Status des Zweigs machen, der auf dem Server-Repo ausgecheckt wurde, während Sie Änderungen an den Server übertragen.

Manish
quelle
4

Eine andere Möglichkeit besteht darin, einen umgekehrten SSH-Tunnel einzurichten, damit Sie ziehen statt schieben können.

# start the tunnel from the natted box you wish to pull from (local)
$ ssh -R 1234:localhost:22 user@remote

# on the other box (remote)
$ git remote add other-side ssh://user@localhost:1234/the/repo
$ git pull other-side

Und wenn Sie möchten, dass der Tunnel im Hintergrund verläuft

$ ssh -fNnR 1234:localhost:22 user@remote
Todd befreit
quelle
1

Du kannst tun:

$git config --bool core.bare true

Dies kann im nackten oder zentralen Repository erfolgen, sodass alle Dateien akzeptiert werden, die aus nicht nackten Repositorys übertragen werden. Wenn Sie dies in einem nicht nackten Repository tun, können wir keine Dateien von einem nicht nackten in ein nacktes Repository verschieben.

Wenn Sie GIT üben, indem Sie ein zentrales und nicht nacktes Repo auf dem PC erstellen, werden die übertragenen Dateien auf einigen PCs möglicherweise nicht angezeigt, aber es wurde verschoben. Sie können es überprüfen, indem Sie ausführen.

$git log im zentralen repo.

Anders als wenn Sie auf GitHub pushen, werden die Dateien dort angezeigt.

Vidwan Reddy
quelle