web-dev-qa-db-fra.com

Quelles sont les conséquences de l’utilisation de receive.denyCurrentBranch dans Git?

J'ai un référentiel Git. J'ai cloné le référentiel et je peux valider mes modifications locales. Quand je pousse mes modifications sur le serveur cela fonctionne.

Dès que je crée une branche, je vérifie la branche, valide mon travail, puis la branche principale. Je fusionne ensuite mes modifications locales dans la branche principale. Lorsque j'essaie de transmettre au 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 fonctionne, mais je voudrais savoir pourquoi je dois utiliser cette option. Est-ce la seule option? Quelles sont les conséquences de cela?

Ce que j'aimerais vraiment faire, c'est créer des branches, les fusionner dans la branche principale, puis transmettre mes modifications au serveur.

39
user1646481

Le serveur sur lequel vous poussez doit utiliser un référentiel nu.

Comment convertir un référentiel Git normal en un nud?

25
kan

Pourquoi Git ne vous laissera pas pousser vers des référentiels non nus

L'affiche originale dit:

Une solution consiste à exécuter la commande suivante:

git config receive.denyCurrentBranch ignore

Après cela, cela fonctionne, mais j'aimerais savoir pourquoi je dois utiliser ceci option. Est-ce la seule option? Quelles sont les conséquences de faire ce?

Comme je le fais remarquer dans ma réponse à une question similaire , depuis la version 1.6.2 de Git, Git ne vous laissera pas pousser vers un référentiel non-nu par défaut . En effet, la commande git Push ne met à jour que les références de branche et HEAD du référentiel distant. Ce que ne fait pas est également de mettre à jour la zone de copie de travail et de stockage intermédiaire dans cette télécommande non nue.

Par conséquent, lorsque vous utilisez git status dans le référentiel distant, vous constaterez que l'état précédent du référentiel est toujours présent dans la copie de travail (et transféré 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 consultez le message d'erreur que vous avez reçu lorsque vous avez essayé pour la première fois de transmettre à votre référentiel distant non-nu avec le paramètre receive.denyCurrentBranch défini sur 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 juste pousser à mettre à nu les dépôts Git

Comme indiqué dans certaines des les autres réponses , vous ne devriez pas vraiment pousser vers un référentiel non-nu, pour les raisons que j'ai mentionnées ci-dessus et que Git lui-même vous dit.

Donc, comme quoi cette réponse États, un moyen simple de convertir un dépôt non-nu existant en un stock nu consiste simplement à le recloner comme un rapport nu:

git clone --bare old-repo

Ou vous pouvez essayer de jouer avec le paramètre core.bare config, comme détaillé dans cette réponse .

22
user456814

J'ai eu la même erreur et j'avais besoin que le référentiel soit exécuté en tant que page de test de développement en ligne (c'est-à-dire, je suppose, pour conserver un référentiel non-nu). J'espère que j'ai résolu le problème en lançant le dépôt avec cette série de commandes (depuis 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

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

5
Fanky

Vous devez avoir un référentiel nu sur le serveur, pas un avec un arbre de travail extrait. Git vous dit qu'il refuse d'écraser la branche actuellement extraite sur le serveur.

Voir cette réponse pour obtenir des informations sur la conversion de votre référentiel non-nu sur le serveur en un nud.

3
Carl-Eric Menzel

Autopsie du problème

Lorsqu'une branche est extraite, la validation ajoute un nouveau commit avec la tête de la branche actuelle en tant que parent et déplace la tête de la branche pour qu'elle devienne ce nouveau commit.

Alors

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 la branche 1, sans avoir explicitement demandé à extraire une autre branche. Pire encore, l'utilisateur est maintenant en dehors de toute branche, et tout nouveau commit sera simplement suspendu:

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

De manière hypothétique, si à ce stade, l'utilisateur vérifie une autre branche, cette validation pendante devient alors un jeu équitable pour/ garbage collector de Git.

1
Harshal Doshi Jain

Je pense qu'un référentiel non nu peut être utile lorsque man configure le crochet git update à déployer à partir du référentiel lui-même après que le Push ait eu lieu. N'oubliez pas de réinitialiser le référentiel. Si vous manquez cette étape, les fichiers ne suivront pas l'état actuel ...

0
kisp