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.
Le serveur sur lequel vous poussez doit utiliser un référentiel nu.
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.
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 .
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
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.
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.
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 ...