web-dev-qa-db-fra.com

Erreur Git Push: refus de mettre à jour la branche extraite

J'ai résolu certains conflits de fusion, commis puis essayé de pousser mes modifications et reçu l'erreur suivante:

c:\Program Files (x86)\Git\bin\git.exe Push --recurse-submodules=check "Origin" master:master
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:/Development/GIT_Repo/Project
 ! [remote rejected] master -> master (branch is currently checked out)
error: failed to Push some refs to 'C:/Development/GIT_Repo/Project'

Est-ce que quelqu'un sait ce qui pourrait causer cette erreur?

169
Funky

Il existe deux types de référentiels: nu et non-n

Les référentiels nus n'ont pas de copie de travail et vous pouvez y accéder. Ce sont les types de référentiels que vous obtenez dans Github! Si vous voulez créer un référentiel nu, vous pouvez utiliser

git init --bare

Donc, en bref, vous ne pouvez pas pousser vers un référentiel non-nu  (Édition: Eh bien, vous ne pouvez pas accéder à la branche actuellement extraite d'un référentiel. Avec un référentiel vide, vous pouvez appuyer sur n'importe quelle branche car aucune d'entre elles n'est extraite. Bien que cela soit possible, le transfert vers des référentiels non à nu n'est pas courant.) . Ce que vous pouvez faire, c'est récupérer et fusionner à partir de l'autre référentiel. Voici comment fonctionne le pull request que vous pouvez voir dans Github. Vous leur demandez de tirer de vous et vous ne forcez pas.


Update : Merci à VonC pour cette remarque, dans les dernières versions de Git (actuellement la version 2.3.0), passage à la branche extraite d’un référentiel non-nu est possible . Néanmoins, vous ne pouvez toujours pas utiliser Push vers un arbre de travail sale , ce qui n’est de toute façon pas une opération sûre.

204
Shahbaz

J'ai résolu ce problème en vérifiant d'abord que la télécommande n'avait rien vérifié (ce n'était vraiment pas censé le faire), puis j'ai expliqué:

$ git config --bool core.bare true

Après cela, Git Push a bien fonctionné.

99
Sasha Pachev

Sommaire

Vous ne pouvez pas accéder à la branche extraite d'un référentiel, car cela gâcherait l'utilisateur de ce référentiel d'une manière qui se terminerait probablement par perte de données et d'historique. Mais vous pouvez pousser vers n'importe quelle autre branche du même référentiel.

Comme les référentiels nus n'ont jamais d'extraction extraite de branche, vous pouvez toujours transférer vers n'importe quelle branche d'un référentiel nu.

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 en tant que nouvelle validation.

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 détaché mode:

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 en suspens:

      [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 juste pour Git garbage collector.

41
Nowhere man

cd dans le repo/répertoire que vous poussez sur la machine distante et entrez

$ git config core.bare true
19
Ricky

Pour moi, ce qui suit a fait l'affaire:

git config --global receive.denyCurrentBranch updateInstead

J'ai configuré le lecteur F :, presque dans son intégralité, pour synchroniser mon ordinateur de bureau Windows 10 avec mon ordinateur portable Windows 10, à l'aide de Git. J'ai fini par exécuter la commande ci-dessus sur les deux machines.

J'ai d'abord partagé le lecteur F du bureau sur le réseau. Ensuite, j'ai pu le cloner sur mon ordinateur portable en exécutant:

F: git clone 'file://///DESKTOP-PC/f'

Malheureusement, tous les fichiers se sont retrouvés sous "F:\f \" sur mon ordinateur portable, pas sous F:\directement. Mais j'ai pu les couper et les coller manuellement. Git travaillait toujours à partir du nouvel emplacement par la suite.

Ensuite, j'ai essayé d'apporter des modifications aux fichiers de l'ordinateur portable, de les valider et de les repousser sur le bureau. Cela n'a pas fonctionné jusqu'à ce que je lance la commande git config mentionnée ci-dessus.

Notez que j'ai exécuté toutes ces commandes à partir de Windows PowerShell, sur les deux ordinateurs.

MISE À JOUR: J'ai toujours eu des problèmes pour pousser les changements, dans certains cas. J'ai finalement finalement commencé à extraire les modifications à la place, en exécutant ce qui suit sur l'ordinateur sur lequel je souhaite extraire le dernier commit (s):

git pull --all --Prune

14
Stephen G Tuggy

Comme il existe déjà un référentiel existant, en cours d'exécution

git config --bool core.bare true

sur le référentiel distant devrait suffire

à partir de la documentation core.bare

Si true (bare = true), le référentiel est supposé être nu, sans répertoire de travail associé. Si tel est le cas, un certain nombre de commandes nécessitant un répertoire de travail seront désactivées, telles que git-add ou git-merge (mais vous pourrez y accéder par la suite).

Ce paramètre est automatiquement déterminé par git-clone ou git-init lors de la création du référentiel. Par défaut, un référentiel qui se termine par "/.git" est supposé ne pas être nu (bare = false), alors que tous les autres référentiels sont supposés être nu (bare = true).

13
Johnny

TLDR

  1. Tirez et poussez à nouveau: git pull &&& git Push.
  2. Toujours un problème? Poussez dans différentes branches: git Push Origin master:foo et fusionnez-les dans le référentiel distant.
  3. Vous pouvez également forcer le Push en ajoutant -f (denyCurrentBranch doit être ignoré).

Fondamentalement, l'erreur signifie que votre référentiel n'est pas à jour avec le code distant (son index et son arbre de travail sont incompatibles avec ce que vous avez poussé).

Normalement, vous devriez pull d'abord récupérer les modifications récentes, puis Push à nouveau.

Si cela ne vous aide pas, essayez de pousser dans une autre branche, par exemple:

git Push Origin master:foo

puis fusionnez cette branche sur le référentiel distant avec le maître.

Si vous avez modifié intentionnellement certaines validations passées via git rebase et que vous souhaitez remplacer le référentiel par vos modifications, vous souhaiterez probablement forcer le Push en ajoutant le paramètre -f/--force (non recommandé si vous ne l'avez pas fait. 'fais pas rebase). Si cela ne fonctionne toujours pas, vous devez définir receive.denyCurrentBranch sur ignore sur remote, comme suggéré par un message git via:

git config receive.denyCurrentBranch ignore
9
kenorb

Peut-être que votre référentiel à distance est dans la branche que vous souhaitez pousser. Vous pouvez essayer de vérifier une autre branche de votre machine distante. Je l'ai fait, ces erreurs ont disparu et j'ai poussé le succès vers mon dépôt distant. Notez que j’utilise ssh pour connecter mon propre serveur au lieu de github.com.

3
JZAU

J'ai cette erreur parce que le dépôt git a été (accidentellement) initialisé deux fois au même endroit: d'abord comme dépôt non-nu et peu de temps après comme dépôt nu. Comme le dossier .git est conservé, git suppose que le référentiel n’est pas nu. La suppression du dossier .git et des données du répertoire de travail a résolu le problème.

1
xastor