git rebase et git push: non-avance rapide, pourquoi l'utiliser?

j'ai une branche qui devrait être disponible pour les autres contributeurs et qui doit constamment rester à jour avec le maître.

malheureusement, chaque fois que je fais "git rebase" et ensuite essayer de pousser, il en résulte un message "non-fast forward" et l'avortement de pousser. La seule façon de pousser ici est l'utilisation de --force. Est-ce que cela signifie que je devrais utiliser "git merge" au lieu de rebaser si ma branche est devenue publique et que d'autres travaillent dessus?

68
demandé sur snitko 2009-02-18 08:09:23

2 réponses

quelques notes sur le fonctionnement de git (non technique):

quand vous rebasez, git prend les commits en question, et les "recommande" en plus d'une histoire propre. C'est pour empêcher l'histoire de montrer:

Description: tree -> mywork -> merge -> mywork -> merge -> mywork -> merge
Commit SHA1: aaaa -> bbbb   -> cccc  -> dddd   -> eeee  -> ffff   -> gggg

Après cela, il peut ressembler à ceci (ou similaire):

Description: tree -> rebase
Commit SHA1: aaaa -> hhhh

le problème est que le nouveau commit que vous tentez de faire sortir est pas un descendant de s'engager sur le bout de la branche que vous pousser à.

Maintenant, vous savez que la même information est dans les commits, mais git est responsable en ne se contentant pas d'écraser ces commits là-bas (bbbb-gggg dans l'exemple ci-dessus).


Modèle De Pension Partagée

si vous utilisez un dépôt partagé, alors des choses comme ça peuvent devenir très déroutantes. Laissez-moi vous expliquer pourquoi. Disons qu'un autre développeur a retiré la branche, et qu'ils ont commit aaaa -> gggg dans leur branche. Puis ils font un commit iiii

pendant ce temps, vous vous êtes rebaptisé et avez forcé une poussée, faisant ressembler l'arbre à ceci:

Description: tree -> rebase
Commit SHA1: aaaa -> hhhh

quand l'autre développeur essaie de pousser, il reçoit un message" non-fast forward". Quand il fait une fusion, alors les deux histoires sont RELINÉES ensemble, et tu finis avec a mess

quelque Chose comme ceci (en désordre):

Description: tree -> rebase -> mywork -> merge -> mywork -> merge -> mywork -> merge -> devwork -> merge 
Commit SHA1: aaaa -> hhhh   -> bbbb   -> cccc  -> dddd   -> eeee  -> ffff   -> gggg -> iiii    -> jjjj

en d'autres termes, si d'autres tirent et poussent, il est préférable que vous vous en teniez à git merge, ou éviter de pousser jusqu'après le rebase (et seulement rebase votre travail).


Modèle De Dépôt Public

peut - être utilisez-vous un autre (plus gittish) modèle où vous voulez juste que les gens soient en mesure de tirer de votre pension. Dans ce cas, git push ... La force n'est pas si mal, parce qu'alors ils peuvent s'en charger. Ils peuvent rebaser leurs modifications pour être au-dessus de vos modifications avant de vous donner leurs patches. Ça évite à votre repo de tout gâcher.

cependant, il peut y avoir un meilleur moyen pour vous. git push --miroir

de http://www.kernel.org/pub/software/scm/git/docs/git-push.html

au lieu de nommer chaque ref à pousser, spécifie que tous les ref sous $ GIT_DIR / refs /( qui inclut mais est ne se limite pas aux réf/heads/, refs/remotes/, et refs/tags/) en miroir, sur le dépôt distant. Local nouvellement créé refs sera poussé à l'extrémité distante, localement mise à jour refs sera force de mises à jour sur la fin distante, et les références supprimées seront être supprimé à partir de l'extrémité distante. Ce est la valeur par défaut si la configuration l'option de la télécommande..miroir.


une des grandes choses au sujet de git est qu'il est très flexible et permet de nombreux types différents de flux de travail. Mais sa véritable force réside dans le fait qu'il s'agit d'un modèle distribué, de sorte que je crois que le plus grand retour sur investissement peut être obtenu en l'utilisant de cette façon.

99
répondu gahooa 2009-09-09 20:51:36

Non, rebase est parfaitement légal avec les dépôts publics et peut même être souhaitable pour garder l'histoire courante. Gardez juste à l'esprit que vous ne devez pas utiliser rebase pour réécrire l'histoire des propagations publiées à distance. Autrement dit, rebase ne peut être appliqué qu'à votre propre, Local, commits que vous n'avez jamais publié. Vous utilisez rebase pour placer vos commits sur eux quand fetch et puis, peut-être, les ajuster là. Une autre raison pour laquelle vous pouvez recevoir un tel message est que la succursale vous pushing a été mis à jour et vous avez besoin de synchroniser -- fetch et rebase vos propagations en plus de ce que vous avez récupéré.

2
répondu Val 2013-01-11 10:37:40