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.
6 réponses
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 .
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.
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
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 .
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...