Quelles sont les conséquences de l'utilisation de recevoir.denyCurrentBranch in Git?

j'ai un dépôt Git. J'ai cloné le dépôt et je peux propager mes modifications locales. Quand je mets mes modifications sur le serveur, ça marche.

dès Que j'ai créer une branche, je l'extraction de la branche, de commettre mon travail et ensuite récupérer la branche master. Je fusionne ensuite mes modifications locales dans la branche principale. Lorsque j'essaie de pousser pour le serveur j'obtiens l'exception suivante:

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'

Une solution consiste à exécuter la commande suivante:

git config receive.denyCurrentBranch ignore

Après cela, il fonctionne, mais je voudrais savoir pourquoi j'ai besoin d'utiliser cette option. Est-ce la seule option? Quelles sont les conséquences de cette mesure?

ce que je voudrais vraiment faire c'est créer des branches, les fusionner dans la branche principale et ensuite pousser mes modifications sur le serveur.

37
demandé sur user1646481 2012-09-04 18:33:09

6 réponses

le serveur vers lequel vous poussez doit utiliser un dépôt nu.

comment convertir un dépôt Git normal en un dépôt nu?

24
répondu kan 2017-05-23 12:25:55

Pourquoi Git ne vous laisseront pas de les pousser à non à nu les référentiels

l'affiche originale dit:

Une solution consiste à exécuter la commande suivante:

git config receive.denyCurrentBranch ignore

Après cela, il fonctionne, mais je voudrais savoir pourquoi j'ai besoin d'utiliser cette option. Est-ce la seule option? Quelles sont les conséquences cette?

Comme je le souligne dans ma réponse à une question similaire , depuis la version 1.6.2 de Git, Git ne vous laissera pas pousser vers un dépôt non-nu par défaut . Cela est dû au fait que la commande git push ne met à jour que la branche et les références HEAD sur le dépôt distant. Ce que ne fait pas , c'est aussi mettre à jour la copie de travail et la zone de transit dans cette télécommande non-nue.

par conséquent, lorsque vous utilisez git status dans la prise en charge à distance, vous verrez que l'état antérieur de la pension est encore présent dans la copie de travail (et mis en scène dans l'index):

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

        new file:   previous-state.txt

si vous regardez le message d'erreur que vous avez reçu lorsque vous avez essayé pour la première fois de pousser à votre repo distant non-nu avec le paramètre receive.denyCurrentBranch défini à la valeur par défaut refuse , vous verrez que le message vous dit essentiellement la même chose:

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.

Vous devriez vraiment pousser à nu dépôts Git

Comme indiqué dans quelques-unes des les autres réponses , vous ne devriez pas vraiment pousser vers un dépôt non-nu, pour les raisons que j'ai indiquées ci-dessus, et que Git lui-même vous dit.

donc comme ce que cette réponse déclare, une façon simple de convertir un repo non-nu existant à un repo nu est de simplement le reclone comme un repo nu:

git clone --bare old-repo

ou vous pourriez essayer de jouer autour de la configuration core.bare , comme détaillé dans cette réponse .

22
répondu Community 2017-05-23 11:54:27

Vous devriez avoir un dépôt nu sur le serveur, pas avec un extrait arbre de travail. Git vous dit qu'il refuse d'écraser la branche qui est actuellement cochée sur le serveur.

Voir cette réponse pour plus d'informations sur la façon de convertir votre non-dépôt nu sur le serveur pour un nu un.

3
répondu Carl-Eric Menzel 2017-05-23 12:17:48

j'ai eu la même erreur et j'avais besoin que le dépôt soit exécuté en tant que page de test dev en ligne (c'est-à-dire, je suppose, pour garder un repo non-nu). Avec un peu de chance je l'ai résolu en initialisant le dépôt avec cette série de commandes (depuis git 2.3):

git init
git config --global user.email "your@mail.here"
git config --global user.name "Your Name"
git commit
git config receive.denyCurrentBranch updateInstead

comme vu ici: ne peut pas pousser dans le dépôt git

3
répondu Fanky 2017-05-23 12:17:48

autopsie du problème

Lorsqu'une branche est cochée, committing ajoutera une nouvelle commit avec la tête de la branche actuelle comme parent et déplacera la tête de la branche pour être cette nouvelle commit.

Donc

A ← B
    ↑
[HEAD,branch1]

devient

A ← B ← C
        ↑
    [HEAD,branch1]

mais si quelqu'un pouvait pousser vers cette branche entre les deux, l'utilisateur se retrouverait dans ce que git appelle le mode tête détachée:

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

maintenant l'utilisateur n'est plus dans branch1, sans avoir explicitement demandé de vérifier une autre branche. Pire, l'utilisateur est maintenant en dehors de n'importe quelle branche, et n'importe quel nouveau commit sera juste suspendu:

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

Hypothétiquement, si, à ce stade, l'utilisateur vérifie une autre branche, puis cette balançant commettre devient un jeu équitable pour Git garbage collector .

1
répondu Harshal Doshi Jain 2014-12-03 03:47:40

je pense qu'un dépôt non nu peut être utile lorsque man configure le git update hook à déployer à partir du dépôt lui-même après la poussée. Il suffit de ne pas oublier de remettre le référentiel. Si vous manquez cette étape, les fichiers ne suivront pas l'état réel...

0
répondu kisp 2015-01-04 16:32:51