Git: comment ignorer fast forward et revenir à l'origine [branch] vers une propagation antérieure?

j'ai utilisé

git reset --hard dc082bc... 
pour revenir à la branche un état précédent, en raison d'une mauvaise engage. Ça a fait rebondir ma branche locale. Cependant, je veux rembobiner la branche sur "origin" à la même commit pour que je puisse recommencer. Est-ce que quelqu'un pourrait me dire comment retourner la branche d'origine (et non le maître) à ce commit?

j'ai essayé git push origin master, mais il donne l'erreur suivante

 ! [rejected]        branch -> branch (non-fast-forward)
error: failed to push some refs to 'git@github.com:xxx/xxx.git'
To prevent you from losing history, non-fast-forward updates were rejected
Merge the remote changes before pushing again.  See the 'Note about
fast-forwards' section of 'git push --help' for details.
8
demandé sur igniteflow 2010-07-02 18:44:36

2 réponses

vous pouvez essayer git push --force pour forcer la poussée.

--force

habituellement, la commande refuse de mettre à jour un ref distant qui n'est pas un ancêtre du ref local utilisé pour l'écraser. Ce drapeau désactive le chèque.

Cela peut entraîner le dépôt distant à perdre s'engage; utiliser avec prudence.

Donc, si beaucoup de gens ont déjà tiré la même branche d'origine, qui peuvent causer des rebase question de leur côté.

Cette opération peut être bloquée côté serveur, comme ebneter souligne (dans les commentaires):

selon la façon dont la télécommande est configurée, bien que cela ne fonctionne peut-être pas

-- toutes mes repos centrales sont configurées avec receive.denyNonFastForwards = true et receive.denyDeletes = true , dans quel cas une telle chirurgie doit être fait sur le serveur distant.

cependant, dans le cas de GitHub, de tels paramètres ne sont pas facilement disponibles pour l'utilisateur qui gère son GitHub repo.

Donc, si vous git push --force par erreur, tout ce qu'il vous reste est ouvrant un cas au support GitHub , pour eux de vérifier leurs réflexes locaux (i.e." GitHub") et voir s'ils peuvent restaurer de vieilles commits.

(Depuis reflogs sont locaux, comme je l'ai été rappelé récemment . Ainsi les commits qui sont remplacés par de nouveaux au cours d'un push --force ne sont encore visibles que si aucun git gc " ou git prune "n'a déjà eu lieu, au GitHub côté serveur

Donc Marco Ceppi insiste (dans les commentaires):

cela pourrait vraiment gâcher d'autres contributeurs les repos locaux si vous forcez les pushes-bien que ce soit parfois juste un mal nécessaire (j'ai peut-être dû le faire deux fois dans ma vie de L'utilisation de Git)

18
répondu VonC 2017-05-23 11:54:38

pour ajouter à ma réponse précédente , et pour aborder le fait qu'un git push forcé peut vraiment gâcher les repos locaux d'autres contributeurs, git 1.8.5 (Q4 à venir 2013) verra une nouvelle option:

git push --force-with-lease

voir l'origine de cette option dans ce fil :

si quelque chose arrive à origin ' à la branche que vous forcez ou supprimez puisque vous récupéré pour l'inspecter, vous pouvez finir par perdre le travail d'autres personnes .

Quelqu'un qui n'est pas au courant de la décision de rembobiner et de reconstruire la branche peut tenter de pousser vers la branche entre le temps que vous avez récupéré pour la rebaser et le temps que vous avez poussé pour la remplacer avec le résultat du rebasage.

Nous pouvons make these pushes safer par en option permettant à l'utilisateur de le dire " git push ":

I am forçage / suppression, basé sur l'hypothèse que la valeur de "branch" est toujours à cet objet.

Si cette hypothèse ne tient plus, c.-à-d. si quelque chose est arrivé à la branche depuis que j'ai commencé à me préparer pour cette poussée, s'il vous plaît ne pas procéder et échouer cette poussée.

vous pouvez voir la documentation complète de --force-with-lease dans commit 28f5d17

--force-with-lease protégera tous les références à distance qui vont être mises à jour en exigeant que leur valeur actuelle soit la même que quelque défaut raisonnable, sauf indication contraire;

pour l'instant, "some reasonable default" est provisoirement défini comme "la valeur de la branche de suivi à distance que nous avons pour la ref de la télécommande en cours de mise à jour", et c'est une erreur si nous n'avons pas une telle branche de suivi à distance.

qui explique la partie "lease" de cette option:

force-with-lease " vous supposez que vous avez pris le bail sur le ref quand vous êtes allé chercher pour décider ce que l'histoire rebasée devrait être, et vous pouvez repousser seulement si le bail n'a pas été cassé.


cela est déjà testé, et mentionné dans le" ce qui cuit en git.git (Aug 2013, #07; Wed, 28) ":

soit dit en passant, la poussée qui l'emporte sur le "must fast-forward" habituel a été effectuée en utilisant l'option force-with-lease "qui a été cuire dans next , comme ceci:

$ git fetch ko next
$ anchor=$(git rev-parse --verify FETCH_HEAD)
$ for remote in ko repo gph github2
  do
    git push --force-with-lease=refs/heads/next:$anchor $remote next
  done

Remarque: " git push --force-with-lease " a été enseigné à signaler si le push nécessaire pour forcer (ou fast-forwarded).

donc cette commande est plus détaillée dans sa sortie avec git 2.8 (mars 2016)

push: fix réf rapport d'état pour --force-with-lease

l'option --force--with-lease permet d'obtenir des renseignements moins détaillés que --force .

En particulier, la sortie indique qu'une référence a l'avance rapide, même quand il a été mis à jour de force.


méfiez-vous de cette option étant ignorée/contournée, comme expliqué dans Git 2.13 (T2 2017) .

26
répondu VonC 2017-05-23 12:18:04