Comment forcer une réinitialisation vers un référentiel distant?

94

Notre branche principale distante s'est en quelque sorte foirée. Le code de développement actuel se trouve sur la branche principale avec les derniers commits. De toute évidence, le code de développement n'est pas prêt pour la branche principale.

Donc , sur mon dépôt local, je l' ai fait une remise à la dernière balise git reset --hard (Tag). La branche principale est maintenant correcte sur mon référentiel local. Maintenant, lorsque j'essaie de transmettre les modifications au référentiel distant git push origin master, j'obtiens une erreur:

To (REMOTE GIT REPOSITORY LOCATION)
 ! [rejected]        master -> master (non-fast-forward)
error: failed to push some refs to '(REMOTE GIT REPOSITORY LOCATION)'
To prevent you from losing history, non-fast-forward updates were rejected
Merge the remote changes (e.g. 'git pull') before pushing again.  See the
'Note about fast-forwards' section of 'git push --help' for details.

Alors après avoir regardé autour de moi, j'ai découvert l' --forceoption. J'ai donc fait une poussée forcée sur le référentiel distant git push --force origin master, et j'ai toujours une erreur:

Total 0 (delta 0), reused 0 (delta 0)
remote: error: denying non-fast-forward refs/heads/master (you should pull first)
To (REMOTE GIT REPOSITORY LOCATION)
 ! [remote rejected] master -> master (non-fast-forward)
error: failed to push some refs to '(REMOTE GIT REPOSITORY LOCATION)'

Je ne peux pas tirer sur master, car il contient du code de développement qui ne peut pas être sur master.

Samwell
la source
3
Je pense que le message signifie que vous n'avez pas le droit de faire une avance non rapide.
svick
3
Vous aviez raison, merci. Dans le fichier de configuration pour le dépôt de la télécommande, denyNonFastforwards = true. Je l'ai changé en faux, j'ai poussé mes modifications, puis je l'ai changé en vrai. Merci encore à tous, pour l'aide.
samwell
2
@samwell veuillez marquer la réponse de svick comme acceptée
hultqvist
@samwell est-ce que la réponse de svick a fonctionné pour vous ou non?
Songo
Pour ceux qui ont besoin de détails sur la façon de désactiver denyNonFastForwards comme Samwell l'a fait, plus d'instructions peuvent être trouvées ici: stackoverflow.com/a/43721579/2073804
ron190

Réponses:

152

Le message signifie que vous n'êtes pas autorisé à effectuer une poussée non rapide.

Votre référentiel distant a très probablement denyNonFastforwards = truedans sa configuration. Si vous changez cela, cela git push --forcedevrait fonctionner.

Pour modifier le paramètre, vous devez accéder à la machine avec le référentiel distant. À partir de là, faites git config receive.denynonfastforwards false.

svick
la source
1
Pouvez-vous faire un git configpour un serveur? Ou peut-être que vous utilisiez cela métaphoriquement. Pour jouer avec ces idées, j'ai créé un dépôt de test dans /opt/git(mon espace serveur git), puis j'ai modifié ce paramètre dans /opt/git/the_repo/the_repo.git/config. Mais une fois fait, le git push --force origin SHA:branchtravail a été effectué au besoin.
HankCa
4
Le message d'erreur aura une ligne qui commence par "error: failed to push some refs to <your repository>" où <your repository> est le chemin se terminant par .git qui est un répertoire contenant un fichier appelé "config". Ce fichier "config" est l'endroit où vous pouvez définir denyNonFastforwards = false
emery
1
Le commentaire de @ emery est précieux. Parfois, le dossier sur le serveur aura son origine définie sur quelque chose comme /srv/git/repo.git. C'est la configuration qui a défini denyNonFastForwards, pas le dossier de l'application.
Elijah Lynn
1
@hsalimi Si vous n'avez pas accès au serveur, vous devez contacter l'administrateur du serveur et lui demander de l'éteindre temporairement afin que vous puissiez forcer le push, puis le rallumer. Il est peu probable que la plupart soient en mesure de le faire. Cela peut être plus courant dans un environnement interne avec votre propre équipe d'hébergement.
Elijah Lynn
1
C'est initialement frustrant, mais la beauté de celui-ci est: la télécommande est totalement protégée par défaut, et si vous en tant que développeur faites intentionnellement et correctement des rebases, vous pouvez remplacer cette configuration pour autoriser le comportement dangereux. Le rebasage est quelque chose que chaque utilisateur git devrait savoir faire - et savoir quand ne pas le faire. doc1 doc2
moodboom
15

La télécommande ne permet pas les avances non rapides.

Votre meilleure option est de prendre git reverttous les commits qui ne devraient pas être là et d'être plus prudent à l'avenir.

git revert [commit]va créer un nouveau commit qui annule tout ce qui a été [commit]fait.

richo
la source
Ce sont certains paramètres du référentiel distant qui ont bloqué toutes les modifications non rapides.
samwell
Si vous faites cela et que vous devez réappliquer les validations, l'historique n'est pas supprimé lors d'un retour, seuls les changements de code, et vous ne pourrez pas sélectionner les
validations
12

Étapes pour activer en permanence la poussée forcée dans le style suivant

git push -f myrepo my-branch

Modifiez le fichier nommé "config" dans le dossier se terminant par ".git" sur votre référentiel distant

Dans la sortie de ligne de commande de git suite à l'échec du push, recherchez la ligne qui dit quelque chose comme:

error: failed to push some refs to 'ssh://[email protected]/srv/git/myrepo.git

puis

ssh [email protected]
cd /srv/git/myrepo.git
vi config

Définissez "denyNonFastforwards" sur false

Dans "config", définissez

[receive]
        denyNonFastforwards = false

Vous pouvez maintenant pousser depuis votre machine locale avec -f

git push -f myrepo my-branch
émeri
la source
Comment faire cela sans accès à SSH au repo nu git?
Vladimir Vukanac
Peut-être utiliser la commande git revert comme le suggère richo? Si vous sauvegardez d'abord l'état actuel du dépôt, vous pouvez toujours fusionner votre code pour avancer.
emery
git revertest un peu compliqué lorsque vous avez des fusions. Pour être plus compliqué, mon cas a 3 fusions, dont une avec de très vieux ~ 20 commit divergé de develop, 2nd est une sorte de fusion de master - laid comme l'enfer.
Vladimir Vukanac le
1
Peut-être que la solution consiste à réinitialiser à l'état souhaité, à sauvegarder (cacher), à extraire à nouveau et à appliquer une sauvegarde (cachette).
Vladimir Vukanac le
1
mrW, vous pouvez toujours fusionner la base de code que vous voulez sur une base de code inversée / extraite
emery
11

Essayez d'utiliser l' -findicateur et de le mettre après le nom de la branche distante.

git push origin master -f

Chris Ledet
la source
1
Non, cela n'a pas fonctionné non plus. J'ai aussi essayé git push -f origin masteret même résultat. Les deux fois que je l'ai essayé, j'ai reçu la deuxième version du message d'erreur.
samwell
2

Vous n'êtes pas autorisé à faire git push qui n'est pas une avance rapide.

  1. Si la télécommande est GitHub, accédez à https://github.com/$USER/$REPO/settings/brancheset dé-protégez la branche en question.

    entrez la description de l'image ici

    Vous devez être administrateur du repo pour ce faire.

  2. Si la télécommande est votre propre serveur git, exécutez- git config receive.denynonfastforwards falsey.

filiph
la source
Sachez que pour les instances Git Hub Enterprise, les poussées vers la branche par défaut (généralement «maître») peuvent être désactivées au niveau de l'instance. Cela signifie que même si "master" n'est pas protégé, et même si vous êtes un administrateur de site, vous ne pourrez pas forcer les poussées vers la branche par défaut. En supposant que vous ayez des autorisations, vous pouvez temporairement contourner ce problème en basculant la branche par défaut sur autre chose, en effectuant votre poussée forcée, puis en revenant.
Christopher Hunter
2

La meilleure façon de contourner ce problème est de supprimer la branche distante et de la renvoyer:

git push origin master --delete
git push origin master
Danilo Souza Morães
la source
0

Le problème se produit car la branche actuelle n'est pas configurée correctement pour le PULL . Vérifiez d'abord si la branche amont est correctement configurée pour l'extraction à l'aide de - git remote show origin. Vous pouvez le trouver dans la section - Les sections locales configurées pour « git pull »: . Sinon, configurez-le en utilisant:

git config branch.MYBRANCH.merge refs/heads/MYBRANCH

Donnez le nom de la succursale approprié pour l'espace réservé - MYBRANCH

Sudheesh.MS
la source
0

J'utilise ce groupe de commandes pour réinitialiser mon dépôt distant, cela réinitialisera votre dépôt local et reliera à nouveau votre dépôt distant, puis forcera à pousser les mises à jour.

Je pense que cette méthode ne fonctionnera pas dans votre cas, mais peut être utile pour quelqu'un d'autre

allez dans le dossier source puis exécutez les commandes: notez qu'il https://github.com/*.gits'agit de votre lien de dépôt distant

git init
git remote add origin https://github.com/*.git
git add .
git commit -m "initial commit"
git push origin master -f
git push --set-upstream origin master

**Note: this will clear all your git history on your master branch**

Khaled AbuShqear
la source
0

Pour moi, l'indice de @svick allait dans la bonne direction. Étant donné que le serveur git que je voulais modifier est en fait ma boîte, je me suis connecté et j'ai fait un git config --global receive.denynonfastforwards falsepour changer tous les dépôts pour accepter un push non-ff forcé. Cela n'a pas fonctionné hors de la boîte. Ce que j'ai trouvé, c'est que dans la configuration, il était déjà receive.denynonfastforwards=truedéfini et qu'il ne pouvait pas être effacé avec git config --global --unset receive.denynonfastforwards. La modification manuelle du dépôt ( vi config) a cependant fonctionné.

jglathe
la source
0

J'ai résolu en supprimant la branche principale de protected et également par défaut, qui est juste au-dessus des règles de branche protégées dans la configuration d'un référentiel.

dasra khadka
la source