Question branche maîtresse et «origine / maître» ont divergé, comment «se séparer» des branches »?


D'une façon ou d'une autre mon maître et mon origine / branche principale ont divergé. En fait, je ne veux pas qu'ils soient divergents. Comment puis-je voir ces différences et les «fusionner»?


723
2018-03-16 05:05


origine


Réponses:


Vous pouvez revoir les différences avec un:

git log HEAD..origin/master

avant le tirant (chercher + fusionner) (voir aussi "Comment obtenez-vous que git tire toujours d'une branche spécifique?")


Lorsque vous avez un message comme:

"Votre branche et 'origin / master' ont divergé, # et ont respectivement 1 et 1 commit (s) différent (s)."

, vérifiez si vous besoin de mettre à jour origin. Si origin est à jour, alors certains commits ont été poussés à origin d'un autre repo pendant que vous faites vos propres commits localement.

... o ---- o ---- A ---- B  origin/master (upstream work)
                   \
                    C  master (your work)

Vous avez basé C sur commit A parce que c'était le dernier travail que vous aviez récupéré en amont à l'époque.

Cependant, avant d'essayer de repasser à l'origine, quelqu'un d'autre a poussé le commit B.
L'histoire du développement a divergé en chemins séparés.

Vous pouvez ensuite fusionner ou rebaser. Voir Pro Git: Git Branching - Rebasing pour plus de détails.

Fusionner

Utilisez la commande git merge:

$ git merge origin/master

Cela dit à Git d'intégrer les changements de origin/master dans votre travail et créer un commit de fusion.
Le graphique de l'histoire ressemble maintenant à ceci:

... o ---- o ---- A ---- B  origin/master (upstream work)
                   \      \
                    C ---- M  master (your work)

La nouvelle fusion, commit M, a deux parents, chacun représentant un chemin de développement qui a conduit au contenu stocké dans ce commit.

Notez que l'histoire derrière M est maintenant non-linéaire.

Rebase

Utilisez la commande git rebase:

$ git rebase origin/master

Cela dit à Git de rejouer le commit C (votre travail) comme si vous l'aviez basé sur le commit B au lieu de A.
Les utilisateurs CVS et Subversion réorganisent régulièrement leurs modifications locales en amont du travail en amont lorsqu'elles se mettent à jour avant la validation.
Git ajoute juste une séparation explicite entre les étapes commit et rebase.

Le graphique de l'histoire ressemble maintenant à ceci:

... o ---- o ---- A ---- B  origin/master (upstream work)
                          \
                           C'  master (your work)

Commit C 'est un nouveau commit créé par la commande git rebase.
Il est différent de C de deux façons:

  1. Il a une histoire différente: B au lieu de A.
  2. Son contenu tient compte des changements dans B et C; C'est la même chose que M à partir de l'exemple de fusion.

Notez que l'histoire derrière C 'est toujours linéaire.
Nous avons choisi (pour l'instant) de n'autoriser que l'histoire linéaire cmake.org/cmake.git.
Cette approche préserve le flux de travail basé sur CVS utilisé précédemment et peut faciliter la transition.
Une tentative de pousser C 'dans notre dépôt fonctionnera (en supposant que vous ayez des permissions et que personne n'ait poussé pendant que vous rebasiez).

La commande git pull fournit un moyen abrégé d'extraire de l'origine et de rebaser le travail local:

$ git pull --rebase

Cela combine les étapes d'extraction et de rebasification ci-dessus en une seule commande.


812
2018-03-16 07:02



J'ai eu ceci et suis mystifié quant à ce qui l'a causé, même après avoir lu les réponses ci-dessus. Ma solution était de faire

git reset --hard origin/master

Ensuite, cela réinitialise juste ma copie (locale) de master (que je suppose est vissé) au point correct, comme représenté par origine / maître (à distance).

ATTENTION: Vous allez perdre tous les changements pas encore poussés à origin/master.


483
2017-12-12 14:40



git pull --rebase origin/master 

est une commande unique qui peut vous aider la plupart du temps.

Modifier: Extrait les validations de l'origine / du maître et applique vos modifications à l'historique des branches nouvellement extraites.


37
2018-03-21 04:10



Je me suis retrouvé dans cette situation quand j'ai essayé de rebaser une branche qui suivait une branche distante, et j'essayais de la rebaser sur le master. Dans ce scénario, si vous essayez de rebaser, vous trouverez probablement votre branche divergé et il peut créer un désordre qui n'est pas pour git nubees!

Disons que vous êtes sur la branche my_remote_tracking_branch, qui a été ramifiée à partir du maître

$ git status

# Sur la branche my_remote_tracking_branch

rien à commettre (répertoire de travail propre)

Et maintenant vous essayez de rebaser du maître comme:

git rebase master

ARRÊTEZ MAINTENANT et sauvez-vous des ennuis! Au lieu de cela, utilisez la fusion comme:

git merge master

Oui, vous allez vous retrouver avec des commits supplémentaires sur votre branche. Mais à moins que vous soyez prêt pour des branches "non divergentes", ce sera un flux de travail beaucoup plus fluide que le rebasage. Voir ce blog pour une explication beaucoup plus détaillée.

D'un autre côté, si votre branche n'est qu'un local branche (c'est-à-dire pas encore poussé vers une télécommande), vous devriez certainement faire une rebase (et votre branche ne sera pas diverger dans ce cas).

Maintenant, si vous lisez ceci parce que vous avez déjà sont Dans un scénario "divergent" dû à une telle rebase, vous pouvez revenir à la dernière validation depuis l'origine (c'est-à-dire dans un état non divergent) en utilisant:

git reset --hard origine / my_remote_tracking_branch


22
2018-05-18 09:21



Dans mon cas, voici ce que j'ai fait pour provoquer la divergé message: J'ai fait git push mais ensuite git commit --amend ajouter quelque chose au message de validation. Puis j'ai aussi fait un autre commit.

Donc, dans mon cas, cela signifie simplement que l'origine / le maître était obsolète. Parce que je savais que personne d'autre ne touchait l'origine / le maître, la solution était triviale: git push -f  (où -f signifie force)


18
2018-01-23 03:03



Dans mon cas, j'ai poussé les changements à origin/master Et puis je me suis rendu compte que je n'aurais pas dû le faire :-( Cela a été compliqué par le fait que les changements locaux étaient dans un sous-arbre.Je suis donc retourné au dernier bon commit avant les "mauvais" changements locaux (en utilisant SourceTree). eu le "message de divergence".

Après avoir réparé mon désordre localement (les détails ne sont pas importants ici) je voulais "remonter dans le temps" la télécommande origin/master branche de sorte qu'il serait en synchronisation avec le local master encore. La solution dans mon cas était:

git push origin master -f

Noter la -f (force) commutateur. Cela a supprimé les "mauvais changements" qui avaient été poussés à origin/master par erreur et maintenant les branches locales et distantes sont en synchronisation.

S'il vous plaît gardez à l'esprit qu'il s'agit d'une opération potentiellement destructrice, donc exécutez-le seulement si vous êtes sûr à 100% que "reculer" le maître à distance dans le temps est OK.


5
2018-06-27 08:58



Dans mon cas, cela a été causé par la non-résolution de mon conflit.

Le problème a été causé par l'exécution du git pullcommander. Les changements dans l'origine ont conduit à des conflits avec mon dépôt local, que j'ai résolu. Cependant, je ne les ai pas commis. La solution à ce stade est de valider les changements (git commit le fichier résolu)

Si vous avez également modifié certains fichiers depuis la résolution du conflit, le git status La commande affichera les modifications locales sous forme de modifications locales non mises en scène et fusionnera la résolution en tant que modifications locales par étapes. Cela peut être correctement résolu en validant les modifications de la fusion d'abord par git commit, puis en ajoutant et en validant les changements non statiques comme d'habitude (par exemple par git commit -a).


3
2018-02-25 08:47