it-swarm.com.de

Was sind die Folgen der Verwendung von receive.denyCurrentBranch in Git?

Ich habe ein Git-Repository. Ich habe das Repository geklont und kann meine lokalen Änderungen übernehmen. Wenn ich meine Änderungen an den Server schiebe, funktioniert es.

Sobald ich eine Niederlassung erstelle, checke ich die Niederlassung aus, binde meine Arbeit ab und checke dann die Hauptniederlassung aus. Ich füge dann meine lokalen Änderungen im Hauptzweig zusammen. Wenn ich versuche, auf den Server zu schieben, erhalte ich die folgende Ausnahme:

Welcome to Git (version 1.7.11-preview20120620)

Run 'git help git' to display the help index.
Run 'git help <command>' to display help for specific commands.

$ git Push Origin master:master
 Counting objects: 9, done.
 Delta compression using up to 4 threads.
 Compressing objects: 100% (7/7), done.
 Writing objects: 100% (8/8), 13.68 KiB, done.
 Total 8 (delta 2), reused 1 (delta 0)
 Unpacking objects: 100% (8/8), 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:/jGit
 ! [remote rejected] master -> master (branch is currently checked out)
 error: failed to Push some refs to 'c:/gitRepository'

Eine Lösung besteht darin, den folgenden Befehl auszuführen:

git config receive.denyCurrentBranch ignore

Danach funktioniert es, aber ich würde gerne wissen, warum ich diese Option verwenden muss. Ist dies die einzige Option? Was sind die Konsequenzen daraus?

Was ich wirklich gerne machen würde, ist, Zweige zu erstellen, sie in den Hauptzweig zusammenzuführen und dann meine Änderungen an den Server zu übertragen.

39
user1646481

Der Server, auf den Sie pushen, sollte das leere Repository verwenden.

Wie konvertiere ich ein normales Git-Repository in ein nacktes?

25
kan

Warum Git nicht zulässt, dass Sie in nicht-bloße Repositorys pushen

Das Originalplakat sagt:

Eine Lösung besteht darin, den folgenden Befehl auszuführen:

git config receive.denyCurrentBranch ignore

Danach funktioniert es, aber ich möchte wissen, warum ich diese Option verwenden muss. Ist das die einzige Option? Was sind die Konsequenzen daraus?

Wie ich in meine Antwort auf eine ähnliche Frage , seit Git Version 1.6.2, Git lässt Sie nicht standardmäßig in ein nicht-nacktes Repository pushen . Dies liegt daran, dass mit dem Befehl git Push Nur die Verweise für Verzweigungen und HEAD im Remote-Repository aktualisiert werden. Was es nicht tut , ist auch die Aktualisierung der Arbeitskopie und des Staging-Bereichs in dieser nicht-blanken Fernbedienung.

Wenn Sie also git status Im Remote-Repo verwenden, sehen Sie, dass der vorherige Status des Repos in der Arbeitskopie noch vorhanden ist (und im Index bereitgestellt wird):

$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        new file:   previous-state.txt

Wenn Sie sich die Fehlermeldung ansehen, die Sie erhalten haben, als Sie zum ersten Mal versucht haben, auf Ihr nicht-nacktes Remote-Repo zu pushen, wobei die Einstellung receive.denyCurrentBranch Auf den Standardwert refuse gesetzt ist, wird das angezeigt Nachricht sagt Ihnen im Grunde das gleiche:

error: refusing to update checked out branch: refs/heads/master
error: By default, updating the current branch in a non-bare repository
error: is denied, because it will make the index and work tree inconsistent
error: with what you pushed, and will require 'git reset --hard' to match
error: the work tree to HEAD.
error:
error: You can set 'receive.denyCurrentBranch' configuration variable to
error: 'ignore' or 'warn' in the remote repository to allow pushing into
error: its current branch; however, this is not recommended unless you
error: arranged to update its work tree to match what you pushed in some
error: other way.

Sie sollten wirklich nur Push to Bare Git-Repositorys

Wie in einige von the andere Antworten ausgeführt, sollten Sie aus den oben genannten Gründen und aus welchen Gründen Git selbst nicht wirklich auf ein nicht-nacktes Repository drängen sagt es dir.

So wie in what diese Antwort angegeben, besteht eine einfache Möglichkeit, ein vorhandenes nicht-bloßes Repo in ein bloßes Repo umzuwandeln, darin, es einfach als bloßes Repo erneut zu klonen:

git clone --bare old-repo

Oder Sie könnten versuchen, mit der Konfigurationseinstellung core.bare Herumzuspielen, wie in diese Antwort beschrieben.

23
user456814

Ich hatte den gleichen Fehler und musste das Repository online als Dev-Testseite ausführen (das heißt, um ein nicht-nacktes Repo zu halten). Hoffentlich habe ich es gelöst, indem ich das Repository mit dieser Befehlsfolge initiierte (seit git 2.3):

git init
git config --global user.email "[email protected]"
git config --global user.name "Your Name"
git commit
git config receive.denyCurrentBranch updateInstead

Wie hier zu sehen: kann nicht in git Repository schieben

5
Fanky

Sie sollten ein leeres Repository auf dem Server haben, nicht eines mit ausgecheckter Arbeitsstruktur. Git sagt Ihnen, dass es den Zweig, der gerade auf dem Server ausgecheckt ist, nicht überschreibt.

In diese Antwort finden Sie Informationen zum Konvertieren Ihres nicht-leeren Repositorys auf dem Server in ein leeres.

3

Autopsie des Problems

Wenn ein Zweig ausgecheckt ist, wird beim Festschreiben ein neues Commit mit dem Kopf des aktuellen Zweigs als übergeordnetes Element hinzugefügt und der Kopf des Zweigs wird zu diesem neuen Commit.

So

A ← B
    ↑
[HEAD,branch1]

wird

A ← B ← C
        ↑
    [HEAD,branch1]

Aber wenn jemand zwischendurch auf diesen Zweig pushen könnte, würde sich der Benutzer in dem Modus befinden, in dem git den getrennten Kopfmodus aufruft:

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

Nun befindet sich der Benutzer nicht mehr in branch1, ohne explizit aufgefordert zu haben, 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]

Hypothetisch, wenn der Benutzer zu diesem Zeitpunkt einen anderen Zweig auscheckt, wird dieses schwerwiegende Commit zum Spiel von Gits Garbage Collector .

1

Ich denke, ein nicht-nacktes Repository kann nützlich sein, wenn man den git update-Hookso konfiguriert, dass er nach dem Push aus dem Repository bereitgestellt wird. Vergessen Sie nicht, das Repository zurückzusetzen. Wenn Sie diesen Schritt vermissen, werden Dateien nicht den tatsächlichen Status nachverfolgen ...

0
kisp