web-dev-qa-db-fra.com

git: les branches ont divergé; la façon de procéder?

Mon arbre local a divergé du maître:

$ git status
# On branch master
# Your branch and 'Origin/master' have diverged,
# and have 7 and 3 different commit(s) each, respectively.
#
nothing to commit (working directory clean)

J'ai essayé git pull --rebase et j'ai échoué:

$ git pull --rebase
First, rewinding head to replay your work on top of it...
Applying: * ...
Using index info to reconstruct a base tree...
Falling back to patching base and 3-way merge...
Auto-merging ChangeLog
CONFLICT (content): Merge conflict in ChangeLog
Failed to merge in the changes.
Patch failed at 0001 * ...

Alors je suis retourné avec git rebase --abort et je suis maintenant à la case 1.

Ce que je veux c'est:

  1. "Exporter" mes 7 correctifs dans des fichiers diff lisibles par l'homme (à la hg export ).
  2. Faire de mon arbre une copie conforme de l’origine/master (à la hg strip ).
  3. réappliquez mes 7 patchs un à un à la main (à la hg import ).

Je comprends que git rebase --continue do this . Je l’ai fait et cela a fonctionné (après quelques fusions manuelles et un git add ) . Cependant, je veux être capable de le faire manuellement, Je me demande donc quelles sont les commandes git correspondant aux commandes hg ci-dessus.

Merci.

PS. S'il vous plaît, ne me dites pas que l'utilisation d'un ChangeLog fichier avec git est stupide . Même si c'est le cas, cela ne dépend pas de moi.

31
sds

Il y a bien sûr plusieurs façons de le faire manuellement. Vous aurez toujours les mêmes conflits car git le fait pour vous sous le capot. Mais si vous voulez le faire manuellement, voici deux manières.

Tout d’abord, exportez vos commits sous forme d’une série de correctifs. Pour ce faire, le plus simple consiste à utiliser git format-patch:

git format-patch -M @{upstream}

produira 7 fichiers de correctifs - un pour chacun de vos commits. (Notez que "@ {upstream}" est littéral - c'est une fonctionnalité peu connue de git.) C'est mieux que de capturer la sortie de git diff car toutes les informations de validation (auteur, date, message, etc.) conservé.

Ensuite, vous pouvez réinitialiser votre référentiel pour qu'il corresponde à l'amont:

git reset --hard @{upstream}

Ensuite, vous pouvez réappliquer vos correctifs en utilisant git am - un à la fois ou tous à la fois.

git am 0001-blah-blah.patch
git am 0002-blah-blah.patch
...

Une deuxième option serait de créer une branche de secours avec votre travail:

git branch scrap

Puis réinitialisez votre branche en amont:

git reset --hard @{upstream}

Puis sélectionnez les commits sur:

git cherry-pick scrap~6
git cherry-pick scrap~5
git cherry-pick scrap~4
...

Ensuite, éliminez la branche de ferraille:

git branch -D scrap
45
Pat Notz

Avez-vous essayé git merge Origin/master?

Vos modifications à distance sont stockées dans la branche Origin/master. (Ou bien, si vous faites git fetch.) Il vous suffit de fusionner les deux branches - master et Origin/master - comme toutes les deux branches et de résoudre les conflits (le cas échéant).

Cela peut vous aider si vous avez besoin de savoir comment résoudre les conflits git.

Comment résoudre les conflits de fusion dans Git?

16
Sailesh

Git dit qu'il a essayé de faire exactement ce que vous voulez (réappliquez vos correctifs en plus des dernières modifications apportées par Origin/master) mais a échoué avec un conflit. Immédiatement après les conflits git pull --rebase, ouvrez un éditeur contenant les fichiers en conflit (git status les répertoriera sous "tous les deux modifiés") et résolvez les conflits marqués en langage standard. Lorsque vous avez terminé de résoudre le conflit, insérez un git rebase --continue (ou git rebase --skip si votre résolution n'introduit aucune modification).

Lisez à propos de sa documentation sur Stackexchange pour «Résoudre les conflits de fusion après une rebase Git» .

7
wilhelmtell

Voici quelques bonnes réponses au même problème (uniquement sans résolution de conflit):

branche maître et «origine/maître» ont divergé, comment «dévier des branches»?

Tout d’abord, vous voudrez peut-être examiner ce qui a été modifié sur le maître distant par rapport à votre version locale:

git log HEAD..Origin/master

Pour résoudre votre problème, cela revient à la même ligne que celle proposée par wilhelmtell:

git pull --rebase

Comme vous l'avez dit, vous aurez des conflits.

La résolution des conflits est un problème récurrent. Si vous ne l'avez pas encore fait, vous pouvez jeter un oeil à git mergetool (voir git help mergetool pour plus de détails). Pour obtenir un support graphique, je vous recommande d’écraser la configuration merge.tool. Par exemple, si vous souhaitez utiliser meld pour les fusions à trois, vous pouvez utiliser:

git config --global merge.tool meld

Donc, après avoir résolu le conflit, qu'est-ce que git pull --rebase a fait? Il a fusionné toutes les modifications de l’origine/maître dans votre maître local et a répété vos modifications par-dessus. Félicitations, vous êtes revenu à la normale.

0
Philipp Claßen