maître (la branche est actuellement extraite)''/> maître (la branche est actuellement extraite)''/> maître (la branche est actuellement extraite)''/> Erreur Git push '[distant rejeté] maître -> maître (la branche est actuellement extraite)' | abulletproofidea.com

Question Erreur Git push '[distant rejeté] maître -> maître (la branche est actuellement extraite)'


Hier, j'ai posté une question sur la façon de cloner un Git référentiel d'une de mes machines à l'autre, Comment puis-je «cloner» d'une autre machine?.

Je suis maintenant en mesure de cloner avec succès un dépôt Git de ma source (192.168.1.2) vers ma destination (192.168.1.1).

Mais quand j'ai fait une modification dans un fichier, un git commit -a -m "test" et un git push, J'obtiens cette erreur sur ma destination (192.168.1.1):

git push                                                
hap@192.168.1.2's password: 
Counting objects: 21, done.
Compressing objects: 100% (11/11), done.
Writing objects: 100% (11/11), 1010 bytes, done.
Total 11 (delta 9), reused 0 (delta 0)
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.
error: 
error: To squelch this message and still keep the default behaviour, set
error: 'receive.denyCurrentBranch' configuration variable to 'refuse'.
To git+ssh://hap@192.168.1.2/media/LINUXDATA/working
! [remote rejected] master -> master (branch is currently checked out)
error: failed to push some refs to 'git+ssh://hap@192.168.1.2/media/LINUXDATA/working'

J'utilise deux versions différentes de Git (1.7 sur la télécommande et 1.5 sur la machine locale). Est-ce une raison possible?


877
2018-05-12 06:06


origine


Réponses:


Vous pouvez simplement convertir votre référentiel distant en référentiel nu (il n'y a pas de copie de travail dans le référentiel nu - le dossier contient uniquement les données réelles du référentiel).

Exécutez la commande suivante dans votre dossier de référentiel distant:

git config --bool core.bare true

Puis supprimez tous les fichiers sauf .git dans ce dossier. Et puis vous serez en mesure d'effectuer git push vers le référentiel distant sans aucune erreur.


1066
2017-07-14 22:45



J'ai juste eu la même erreur pendant que je commençais à apprendre Git. Certaines des autres réponses ne sont clairement pas pour quelqu'un de nouveau à Git!

(Je vais utiliser des termes non techniques pour faire passer l'idée.) Quoi qu'il en soit, ce qui se passe, c'est que vous avez deux dépôts, l'un est l'original que vous avez créé et l'autre le travail que vous venez de faire.

En ce moment, vous êtes dans votre référentiel de travail et utilisez la branche "master". Mais il se trouve aussi que vous êtes "connecté" dans votre référentiel d'origine à la même branche "maître". Maintenant que vous êtes "connecté" dans l'original, Git craint que vous puissiez vous tromper parce que vous pourriez travailler sur l'original et bousiller les choses. Vous devez donc retourner dans le dépôt d'origine et faire un "git checkout someotherbranch", et maintenant vous pouvez pousser sans problème.

J'espère que ça aide.


644
2018-05-29 03:26



Le message d'erreur décrit ce qui s'est passé. Les versions plus modernes de Git refusent de mettre à jour une branche via un push si cette branche est extraite.

Le moyen le plus simple de travailler entre deux référentiels non-nus est de

  1. toujours mettre à jour les dépôts en tirant (ou aller chercher et fusionner) ou, si vous devez,

  2. en poussant vers une branche distincte (une branche d'importation), puis en fusionnant cette branche dans la branche principale de la machine distante.

La raison de cette restriction est que l'opération push fonctionne uniquement sur le référentiel Git distant, elle n'a pas accès à l'index et à l'arbre de travail. Donc, si autorisé, une poussée sur la branche empruntée changerait le  HEAD  être incompatible avec l'index et l'arbre de travail sur le référentiel distant.

Cela rendrait très facile de commettre accidentellement un changement qui annule tous les changements poussés et rend également très difficile la distinction entre les changements locaux qui n'ont pas été commis et les différences entre les nouveaux HEAD, l'index et l'arbre de travail qui ont été causés par un mouvement de poussée HEAD.


118
2018-05-12 06:21



Résumé

Vous ne pouvez pas pousser vers la branche d'un référentiel qui a été extraite, car cela perturberait l'utilisateur de ce référentiel d'une manière qui se terminera très probablement avec perte de données et d'histoire. Mais vous pouvez pousser vers n'importe quelle autre branche du même référentiel.

Comme les dépôts nus n'ont jamais de branche extraite, vous pouvez toujours pousser vers n'importe quelle branche d'un référentiel nu.

Il existe plusieurs solutions, selon vos besoins.

Solution 1: Utiliser un repositionnement nu

Comme suggéré, si sur une machine, vous n'avez pas besoin du répertoire de travail, vous pouvez vous déplacer vers un référentiel nu. Pour éviter de jouer avec le dépôt, vous pouvez simplement le cloner:

machine1$ cd ..
machine1$ mv repo repo.old
machine1$ git clone --bare repo.old repo

Maintenant, vous pouvez pousser tout ce que vous voulez à la même adresse que précédemment.

Solution 2: pousser vers une branche non vérifiée

Mais si vous avez besoin de vérifier le code sur votre télécommande <remote>, alors vous pouvez utiliser une branche spéciale pour pousser. Disons que dans votre dépôt local, vous avez appelé votre télécommande origin et vous êtes sur le maître de la branche. Alors vous pourriez faire

machine2$ git push origin master:master+machine2

Ensuite, vous devez fusionner quand vous êtes dans le origin repo à distance:

machine1$ git merge master+machine2

Autopsie du problème

Lorsqu'une branche est extraite, la validation ajoute un nouveau commit avec la tête de la branche courante comme parent et déplace la tête de la branche pour qu'elle soit la nouvelle validation.

Alors

A ← B
    ↑
[HEAD,branch1]

devient

A ← B ← C
        ↑
    [HEAD,branch1]

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

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

Maintenant, l'utilisateur n'est plus dans branche1, sans avoir explicitement demandé de vérifier une autre branche. Pire, l'utilisateur est maintenant en dehors de toute branche, et tout nouveau commit sera juste se balancer:

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

Hypothétiquement, si à ce moment-là, l'utilisateur vérifie une autre branche, alors ce commit dangling devient un jeu équitable pour Git's Éboueur.


102
2018-02-14 16:28



Vous pouvez contourner cette "limitation" en éditant le .git/config sur le serveur de destination. Ajoutez ce qui suit pour permettre à un dépôt git d'être poussé à même s'il est "extrait":

[receive]
denyCurrentBranch = warn

ou

[receive]
denyCurrentBranch = false

La première permettra la poussée tout en avertissant de la possibilité de gâcher la branche, alors que la seconde le permettra tout simplement.

Cela peut être utilisé pour "déployer" du code sur un serveur qui n'est pas destiné à être édité. Ce n'est pas la meilleure approche, mais une approche rapide pour le déploiement du code.


52
2017-12-16 05:17



J'aime l'idée d'avoir toujours un dépôt utilisable sur la boîte à distance, mais au lieu d'une branche fictive, j'aime utiliser:

git checkout --detach

Cela semble être une caractéristique très nouvelle de Git - J'utilise git version 1.7.7.4.


38
2018-02-14 20:37



git config --local receive.denyCurrentBranch updateInstead

https://github.com/git/git/blob/v2.3.0/Documentation/config.txt#L2155

Utilisez-le sur le référentiel du serveur, et il met également à jour l'arborescence de travail si aucun écrasement non suivi ne se produit.

Il a été ajouté dans Git 2.3 comme mentionné par VonC dans les commentaires.

J'ai compilé Git 2.3 et l'ai essayé. Exemple d'utilisation:

git init server
cd server
touch a
git add .
git commit -m 0
git config --local receive.denyCurrentBranch updateInstead

cd ..
git clone server local
cd local
touch b
git add .
git commit -m 1
git push origin master:master

cd ../server
ls

Sortie:

a
b

Yay, b a été poussé!


31
2018-02-07 14:57



J'ai eu le même problème. Pour moi, j'utilise Git push pour déplacer le code vers mes serveurs. Je ne change jamais le code du côté serveur, donc c'est sûr.

Dans le référentiel, vous essayez de taper:

git config receive.denyCurrentBranch ignore

Cela vous permettra de changer le dépôt alors que c'est une copie de travail.

Après avoir lancé un push Git, allez sur la machine distante et tapez ceci:

git checkout -f

Cela fera refléter les changements que vous avez poussés dans la copie de travail de la machine distante.

Veuillez noter que ce n'est pas toujours sûr si vous apportez des modifications dans la copie de travail que vous êtes en train de pousser.


26
2018-01-27 00:42



Vous pouvez recréer le référentiel de votre serveur et le transférer depuis le maître de la succursale locale vers le maître du serveur.

Sur votre serveur distant:

mkdir myrepo.git
cd myrepo.git
git init --bare

OK, depuis votre agence locale:

git push origin master:master

24
2018-02-07 08:22



Avec quelques étapes de configuration, vous pouvez facilement déployer des modifications sur votre site Web en utilisant un

git push production

Ce qui est agréable et simple, et vous n'avez pas à vous connecter au serveur distant et faire un pull ou quoi que ce soit. Notez que cela fonctionnera mieux si vous n'utilisez pas votre contrôle de production en tant que branche de travail! (Le PO fonctionnait dans un contexte légèrement différent, et je pense que la solution de @Robert Gould l'a bien adaptée: cette solution est plus appropriée pour le déploiement sur un serveur distant.)

Vous devez d'abord configurer un référentiel nu quelque part sur votre serveur, en dehors de votre site Web.

mkdir mywebsite.git
cd mywebsite.git
git init --bare

Ensuite, créez un fichier hooks/post-receive:

#!/bin/sh
GIT_WORK_TREE=/path/to/webroot/of/mywebsite git checkout -f

Et rendre le fichier exécutable:

chmod +x hooks/post-receive

Sur votre machine locale,

git remote add production git@myserver.com:mywebsite.git
git push production +master:refs/heads/master

Tout ensemble! Maintenant, dans le futur, vous pouvez utiliser git push production pour déployer vos modifications!

Le crédit pour cette solution va à http://sebduggan.com/blog/deploy-your-website-changes-using-git/. Regardez là pour une explication plus détaillée de ce qui se passe.


17
2017-10-15 18:16



Qu'est-ce que vous avez probablement fait pour provoquer ceci:

Ce genre de chose arrive quand vous allez frapper un petit programme. Vous êtes sur le point de changer quelque chose qui fonctionnait déjà, alors vous lancez votre sortilège de niveau 3 d'irréversibilité perpétuelle:

machine1:~/proj1> git init

et vous commencez à ajouter / commettre. Mais puis, le projet commence à s'impliquer davantage et vous voulez travailler à partir d'un autre ordinateur (comme votre PC ou votre ordinateur portable), pour que vous fassiez quelque chose comme

machine2:~> git clone ssh://machine1/~/proj1

et il clone et tout a l'air bien, et ainsi vous travaillez sur votre code de machine2.

alors... vous essayez de pousser vos commits de machine2, et vous obtenez le message d'avertissement dans le titre.

La raison de ce message est que le repo git dont vous avez tiré était destiné à être utilisé uniquement pour ce dossier sur la machine1. Vous pouvez cloner à partir de cela, tout va bien, mais pousser peut causer des problèmes. La façon «correcte» de gérer le code dans deux endroits différents est de faire un repo «nu», comme cela a été suggéré. Un repo nu n'est pas conçu pour que le travail soit fait dans il est destiné à coordonner les commits de sources multiples. C'est pourquoi la réponse la mieux notée suggère suppression tous les fichiers / dossiers autres que le dossier .git après git config --bool core.bare true.

Clarifier la réponse la mieux notée:Beaucoup de commentaires à cette réponse disent quelque chose comme "Je n'ai pas supprimé les fichiers non-.git de la machine1 et j'étais encore capable de commettre à partir de la machine2". C'est vrai. Cependant, ces autres fichiers sont complètement "divorcés" du repo git, maintenant. Allez essayer git status là-bas et vous devriez voir quelque chose comme "fatale: cette opération doit être exécutée dans un arbre de travail". Ainsi, la suggestion de supprimer les fichiers n'est pas de sorte que la validation de la machine2 travail; C'est pour que vous ne soyez pas confus et pensez que git continue de suivre ces fichiers. Mais, supprimer les fichiers est un problème si vous voulez toujours travailler sur les fichiers sur la machine1, n'est-ce pas?

Alors, que devriez-vous vraiment faire?

Dépend de combien vous prévoyez de travailler sur machine1 et machine2 ...

Si vous avez terminé le développement de la machine1 et que vous avez déplacé tout votre développement vers la machine2 ... faites juste ce que la réponse la mieux notée suggère: git config --bool core.bare true puis, facultativement, supprimez tous les fichiers / dossiers autres que .git de ce dossier, car ils ne sont pas suivis et risquent de créer de la confusion.

Si votre travail sur machine2 était juste une chose ponctuelle, et vous n'avez pas besoin de continuer le développement là-bas ... alors ne vous embêtez pas à faire un repo nu; juste ftp / rsync / scp / etc. vos fichiers de la machine * 2 * au-dessus des fichiers sur la machine * 1 *, valider / pousser à partir de la machine * 1 *, puis supprimer les fichiers hors de la machine * 2 *. D'autres ont suggéré de créer une branche, mais je pense que c'est un peu compliqué si vous voulez juste fusionner un développement que vous avez fait sur une base unique d'une autre machine.

Si vous devez continuer le développement sur la machine1 et la machine2 ... alors vous devez configurer les choses correctement. Vous devez convertir votre repo en un puis vous devez faire un clone de cela sur la machine1 pour vous travail po Probablement le moyen le plus rapide de le faire est de faire

machine1:~/proj1> git config --bool core.bare true
machine1:~/proj1> mv .git/ ../proj1.git
machine1:~/proj1> cd ..
machine1:~> rm -rf proj1
machine1:~> git clone proj1.git
machine1:~> cd proj1

Très important: parce que vous avez déplacé l'emplacement du dépôt de proj1 à proj1.git, vous devez mettre à jour ceci dans le fichier .git / config sur la machine2. Après cela, vous pouvez valider vos modifications à partir de la machine2. Enfin, j'essaie de garder mes repos nus dans un emplacement central, loin de mes arbres de travail (c'est-à-dire ne pas mettre 'proj1.git' dans le même dossier parent que 'proj1'). Je vous conseille de faire de même, mais je voulais garder les étapes ci-dessus aussi simple que possible.


16
2018-05-12 21:07