Si vous appuyez sur une validation au serveur, puis réécriture qui engagent localement (avec git reset
, git rebase
, git filter-branch
ou toute autre manipulation de l' histoire), puis poussé que réécrite commettre de nouveau sur le serveur, vous bousiller toute autre personne qui avait tiré. Voici un exemple; disons que vous avez validé A et que vous l'avez poussé vers le serveur.
- * - * - A <- maître
- * - * - A <- origine / maître
Vous décidez maintenant de réécrire A, comme vous l'avez mentionné, de réinitialiser et de réengager. Notez que cela laisse un commit suspendu, A, qui sera finalement récupéré car il n'est pas accessible.
-*-*-UNE
\
Un '<- maître
- * - * - A <- origine / maître
Si quelqu'un d'autre, disons Fred, sort master
du serveur pendant que vous faites cela, il aura une référence à A, à partir de laquelle il pourra commencer à travailler:
- * - * - A '<- maître
- * - * - A <- origine / maître
- * - * - AB <- fred / master
Maintenant, si vous pouviez pousser votre A 'à l'origine / maître, ce qui créerait une avance non rapide, il n'aurait pas A dans son histoire. Donc, si Fred essayait à nouveau de tirer, il devrait soudainement fusionner et réintroduire le commit A:
- * - * - A '<- maître
- * - * - A <- origine / maître
-*-*-UN B-\
\ * <- fred / master
UNE'--/
Si Fred remarque cela, alors il pourrait faire un rebase, ce qui empêcherait le commit A de réapparaître. Mais il devrait le remarquer et se souvenir de le faire; et si vous avez plus d'une personne qui a abaissé A, elles devraient toutes rebaser pour éviter d'avoir le commit A supplémentaire dans l'arbre.
Donc, ce n'est généralement pas une bonne idée de changer l'historique d'un repo dont d'autres personnes tirent. Si, cependant, vous savez que personne d'autre ne tire de ce dépôt (par exemple, c'est votre propre dépôt privé, ou vous n'avez qu'un seul autre développeur travaillant sur le projet avec lequel vous pouvez vous coordonner facilement), alors vous pouvez forcer mettre à jour en exécutant:
git push -f
ou
git push origin +master
Ceux-ci ignoreront à la fois la vérification d'une poussée non rapide et mettront à jour ce qui se trouve sur le serveur avec votre nouvelle révision A ', abandonnant la révision A afin qu'elle soit finalement ramassée.
Il est possible que les poussées forcées soient entièrement désactivées avec l' receive.denyNonFastForwards
option config. Cette option est activée par défaut sur les référentiels partagés. Dans ce cas, si vous voulez vraiment, vraiment forcer un push, la meilleure option est de supprimer la branche et de la recréer, avec git push origin :master; git push origin master:master
. Cependant, l' denyNonFastForwards
option est activée pour une raison, qui est décrite ci-dessus; sur un référentiel partagé, cela signifie que désormais, tous ceux qui l'utilisent doivent s'assurer qu'ils rebasent sur le nouvel historique.
Sur un référentiel partagé, il est généralement préférable de simplement pousser de nouveaux commits par-dessus pour résoudre le problème que vous rencontrez; vous pouvez utiliser git revert
pour générer des commits qui annuleront les modifications des commits précédents.