Git Push-Fehler: Weigert sich, den ausgecheckten Zweig zu aktualisieren

196

Ich habe einige Zusammenführungskonflikte gelöst, festgeschrieben und dann versucht, meine Änderungen zu übertragen. Dabei wurde der folgende Fehler angezeigt:

c:\Program Files (x86)\Git\bin\git.exe push --recurse-submodules=check "origin" master:master
Done
remote: error: refusing to update checked out branch: refs/heads/master
remote: error: By default, updating the current branch in a non-bare repository
remote: error: is denied, because it will make the index and work tree inconsistent
remote: error: with what you pushed, and will require 'git reset --hard' to match
remote: error: the work tree to HEAD.
remote: error: 
remote: error: You can set 'receive.denyCurrentBranch' configuration variable to
remote: error: 'ignore' or 'warn' in the remote repository to allow pushing into
remote: error: its current branch; however, this is not recommended unless you
remote: error: arranged to update its work tree to match what you pushed in some
remote: error: other way.
remote: error: 
remote: error: To squelch this message and still keep the default behaviour, set
remote: error: 'receive.denyCurrentBranch' configuration variable to 'refuse'.
To C:/Development/GIT_Repo/Project
 ! [remote rejected] master -> master (branch is currently checked out)
error: failed to push some refs to 'C:/Development/GIT_Repo/Project'

Weiß jemand, was diesen Fehler verursachen könnte?

Funky
quelle
6
Sie haben jetzt tatsächlich eine sichere Möglichkeit, mit Git 2.3.0 (Februar 2015) und git config receive.denyCurrentBranch=updateInstead: stackoverflow.com/a/28262104/6309
VonC

Antworten:

229

Grund: Sie pushen auf ein nicht nacktes Repository

Es gibt zwei Arten von Repositorys: nackte und nicht nackte

Nackte Repositorys haben keine Arbeitskopie und können auf sie übertragen werden. Das sind die Arten von Repositories, die Sie in Github erhalten! Wenn Sie ein nacktes Repository erstellen möchten, können Sie verwenden

git init --bare

Kurz gesagt, Sie können nicht in ein nicht nacktes Repository pushen(Bearbeiten: Nun, Sie können nicht in den aktuell ausgecheckten Zweig eines Repositorys pushen. Mit einem nackten Repository können Sie in jeden Zweig pushen, da keiner ausgecheckt ist. Obwohl möglich, ist das Pushen in nicht nackte Repositorys nicht üblich.) . Was Sie tun können, ist das Abrufen und Zusammenführen aus dem anderen Repository. So funktioniert das pull request, was Sie in Github sehen können. Sie bitten sie, sich von Ihnen zu lösen, und Sie drücken sie nicht mit Gewalt hinein.


Update : Dank VonC für diesen Hinweis ist es in den neuesten Git-Versionen (derzeit 2.3.0) möglich, in den ausgecheckten Zweig eines nicht nackten Repositorys zu wechseln . Trotzdem können Sie immer noch nicht auf einen schmutzigen Arbeitsbaum drücken , was ohnehin keine sichere Operation ist.

Shahbaz
quelle
1
Ja! Das ist richtig, danke! Da ich ungefähr eine Million Dinge zu tun habe, habe ich versehentlich das Arbeitsverzeichnis geklont ... doh!
Funky
25
Tatsächlich können Sie problemlos in ein nicht nacktes Repository pushen. Sie können einfach nicht in den einen Zweig pushen, der gerade ausgecheckt ist .
Nirgendwo Mann
1
Tatsächlich gibt es Dutzende anderer Szenarien. Einige meiner Repositorys befinden sich beispielsweise nur auf meiner Workstation und meinem Laptop (kein Code, sondern Notizen, die ich mache). Auf jedem habe ich zwei Zweige, "Workstation" und "Laptop". Auf der Workstation checke ich nur "Workstation" aus und gehe nur zum Zweig "Workstation" auf dem Laptop (und umgekehrt).
Nirgendwo Mann
8
Sie haben jetzt tatsächlich eine sichere Möglichkeit, mit Git 2.3.0 (Februar 2015) und git config receive.denyCurrentBranch=updateInstead: stackoverflow.com/a/28262104/6309
VonC
1
@skelly Dein Klon ist nicht nackt, während die Kopie auf Github ist. Während beide Klone den gesamten Verlauf haben, wurde für die Kopie auf Github kein Commit ausgecheckt, aber für Ihre Kopie, damit Sie arbeiten können!
Shahbaz
115

Ich habe dieses Problem gelöst, indem ich zuerst überprüft habe, ob auf der Fernbedienung nichts ausgecheckt wurde (was eigentlich nicht beabsichtigt war), und es dann entblößt mit:

$ git config --bool core.bare true

Danach hat der Git Push gut funktioniert.

Sasha Pachev
quelle
3
Dies ist der Einzeiler fix ich suchte .. aber vielleicht nackten nicht-bare repos wie die @shahbaz Antwort erklären
Mr5o1
Auf diese Weise kann der Änderungsverlauf verschoben werden, diese Änderungen werden jedoch nicht im nicht bloßen Repo berücksichtigt.
jhill515
Wirst du git config core.bare falseund git reset --hard ?
Flugzeuge
1
Wie oben erwähnt, wird die Fernbedienung nicht geändert, wenn Sie darauf drücken.
user1097111
46

Zusammenfassung

Sie können nicht zu dem ausgecheckten Zweig eines Repositorys wechseln, da dies den Benutzer dieses Repositorys auf eine Weise verwirren würde, die höchstwahrscheinlich mit dem Verlust von Daten und Verlauf endet . Sie können jedoch auf jeden anderen Zweig desselben Repositorys pushen.

Da bei Bare-Repositorys niemals ein Zweig ausgecheckt ist, können Sie jederzeit zu jedem Zweig eines Bare-Repositorys pushen.

Autopsie des Problems

Wenn ein Zweig ausgecheckt ist, fügt das Festschreiben ein neues Festschreiben mit dem Kopf des aktuellen Zweigs als übergeordnetem Element hinzu und verschiebt den Kopf des Zweigs zu diesem neuen Festschreiben.

So

A ← B
    ↑
[HEAD,branch1]

wird

A ← B ← C
        ↑
    [HEAD,branch1]

Aber wenn jemand zwischendurch zu diesem Zweig pushen könnte, würde sich der Benutzer in den von git getrennten Kopfmodus versetzen:

A ← B ← X
    ↑   ↑
[HEAD] [branch1]

Jetzt befindet sich der Benutzer nicht mehr in Zweig1, ohne explizit aufgefordert worden zu sein, einen anderen Zweig auszuchecken. Schlimmer noch, der Benutzer befindet sich jetzt außerhalb eines Zweigs , und jedes neue Commit wird nur baumeln :

      [HEAD]
        ↓
        C
      ↙
A ← B ← X
        ↑
       [branch1]

Wenn der Benutzer zu diesem Zeitpunkt einen anderen Zweig auscheckt, wird dieses baumelnde Commit hypothetisch zu einem fairen Spiel für Gits Garbage Collector .

Nirgendwo, Mann
quelle
Ich habe ein bisschen in stackoverflow.com/questions/2816369/… erweitert
Nirgendwo Mann
21

CD in das Repo / Verzeichnis, in das Sie auf dem Remote-Computer verschieben, und geben Sie ein

$ git config core.bare true
Ricky
quelle
Das funktioniert nicht. Das Repository bleibt leer, nachdem es hineingeschoben wurde.
Sören
Wie oben von jhil515 erwähnt, werden die nicht bloßen Dateien nicht aktualisiert, sondern nur die Datenbanken.
Denis Cousineau
19

Für mich hat Folgendes den Trick getan:

git config --global receive.denyCurrentBranch updateInstead

Ich habe Laufwerk F: fast vollständig eingerichtet, um mithilfe von Git zwischen meinem Windows 10-Desktop und meinem Windows 10-Laptop zu synchronisieren. Am Ende habe ich den obigen Befehl auf beiden Computern ausgeführt.

Zuerst habe ich das F-Laufwerk des Desktops im Netzwerk freigegeben. Dann konnte ich es auf meinen Laptop klonen, indem ich Folgendes ausführte:

F: git clone 'file://///DESKTOP-PC/f'

Leider landeten alle Dateien auf meinem Laptop unter "F: \ f \", nicht direkt unter F: \. Aber ich konnte sie manuell ausschneiden und einfügen. Git arbeitete danach immer noch vom neuen Standort aus.

Dann habe ich versucht, einige Änderungen an Dateien auf dem Laptop vorzunehmen, sie festzuschreiben und sie wieder auf den Desktop zu verschieben. Das hat nicht funktioniert, bis ich den oben erwähnten Befehl git config ausgeführt habe.

Beachten Sie, dass ich alle diese Befehle in Windows PowerShell auf beiden Computern ausgeführt habe.

UPDATE: In einigen Fällen hatte ich immer noch Probleme, Änderungen voranzutreiben. Ich habe schließlich gerade angefangen, Änderungen abzurufen, indem ich Folgendes auf dem Computer ausgeführt habe, auf den ich die neuesten Commits ziehen möchte:

git pull --all --prune

Stephen G Tuggy
quelle
1
Ich ziehe dieses Lokal dem Git Repo vor:git config receive.denyCurrentBranch updateInstead
Klor
14

Da bereits ein Repository vorhanden ist, wird ausgeführt

git config --bool core.bare true

auf dem Remote-Repository sollte ausreichen

Aus der core.bare Dokumentation

Wenn true (bare = true), wird angenommen, dass das Repository leer ist und kein Arbeitsverzeichnis zugeordnet ist. In diesem Fall wird eine Reihe von Befehlen deaktiviert, für die ein Arbeitsverzeichnis erforderlich ist, z. B. git-add oder git-merge (Sie können jedoch darauf zugreifen).

Diese Einstellung wird beim Erstellen des Repositorys automatisch von git-clone oder git-init erraten. Standardmäßig wird angenommen, dass ein Repository, das mit "/.git" endet, nicht leer ist (bare = false), während alle anderen Repositorys als nackt (bare = true) angenommen werden.

Johnny
quelle
12

TLDR

  1. Ziehen und erneut drücken : git pull &&& git push.
  2. Immer noch ein Problem? In einen anderen Zweig verschieben: git push origin master:foound auf Remote-Repo zusammenführen.
  3. Alternativ können Sie den Push durch Hinzufügen erzwingen -f( denyCurrentBranchmuss ignoriert werden).

Grundsätzlich bedeutet der Fehler, dass Ihr Repository nicht mit dem Remote-Code auf dem neuesten Stand ist (sein Index und Arbeitsbaum stimmen nicht mit dem überein, was Sie gepusht haben).

Normalerweise sollten Sie pullzuerst die letzten Änderungen abrufen und pushes erneut.

Wenn dies nicht hilft, versuchen Sie, in einen anderen Zweig zu wechseln, z.

git push origin master:foo

Führen Sie dann diesen Zweig im Remote-Repository wieder mit dem Master zusammen.

Wenn Sie einige frühere Commits absichtlich über geändert haben git rebaseund das Repo mit Ihren Änderungen überschreiben möchten, möchten Sie den Push wahrscheinlich durch Hinzufügen von -f/ --forceparameter erzwingen (nicht empfohlen, wenn Sie dies nicht getan haben rebase). Wenn dies immer noch nicht funktioniert, müssen Sie auf Remote einstellen receive.denyCurrentBranch, ignorewie in einer Git-Nachricht vorgeschlagen:

git config receive.denyCurrentBranch ignore
Kenorb
quelle
3

Möglicherweise befindet sich Ihr Remote-Repo in der Filiale, die Sie pushen möchten. Sie können versuchen, einen anderen Zweig auf Ihrem Remotecomputer auszuchecken. Ich habe dies getan, als dieser Fehler verschwand, und ich habe den Erfolg auf mein Remote-Repo übertragen. Beachten Sie, dass ich ssh verwende, um meinen eigenen Server anstelle von github.com zu verbinden.

JZAU
quelle
1

Ich habe diesen Fehler, weil das Git-Repo (versehentlich) zweimal an derselben Stelle initialisiert wurde: zuerst als nicht-nacktes Repo und kurz danach als nacktes Repo. Da der .git-Ordner erhalten bleibt, geht git davon aus, dass das Repository nicht leer ist. Das Entfernen des .git-Ordners und der Arbeitsverzeichnisdaten löste das Problem.

Xastor
quelle
1
In meiner Situation war dies der Fall. Durch Entfernen des .gitOrdners auf der Fernbedienung konnte ich das anfängliche Commit übertragen.
tim.rohrer
0

Ich habe diesen Fehler bekommen, als ich beim Lesen von Progit herumgespielt habe. Ich habe ein lokales Repository erstellt, es dann in einem anderen Repo im selben Dateisystem abgerufen, bearbeitet und versucht, es zu pushen. Nachdem Sie die Antwort von NowhereMan gelesen hatten, bestand eine schnelle Lösung darin, in das "Remote" -Verzeichnis zu wechseln und vorübergehend ein anderes Commit auszuchecken, aus dem Verzeichnis zu pushen, in dem ich Änderungen vorgenommen habe, und dann zurück zu gehen und den Kopf wieder auf Master zu setzen.

Nathan Chappell
quelle