Prenons le cas suivant:
Je travaille dans une branche thématique et je suis maintenant prêt à fusionner pour maîtriser:
* eb3b733 3 [master] [Origin/master]
| * b62cae6 2 [topic]
|/
* 38abeae 1
J'effectue la fusion à partir du maître, je résous les conflits et maintenant j'ai:
* 8101fe3 Merge branch 'topic' [master]
|\
| * b62cae6 2 [topic]
* | eb3b733 3 [Origin/master]
|/
* 38abeae 1
Maintenant, la fusion m'a pris un certain temps, alors je fais une autre extraction et remarque que la branche maître distante a de nouvelles modifications:
* 8101fe3 Merge branch 'topic' [master]
|\
| * b62cae6 2 [topic]
| | * e7affba 4 [Origin/master]
| |/
|/|
* | eb3b733 3
|/
* 38abeae 1
Si j'essaie 'git rebase Origin/master' depuis le maître, je suis obligé de résoudre à nouveau tous les conflits et je perds également le commit de fusion:
* d4de423 2 [master]
* e7affba 4 [Origin/master]
* eb3b733 3
| * b62cae6 2 [topic]
|/
* 38abeae 1
Existe-t-il un moyen propre de reformuler le commit de fusion pour que je me retrouve avec une histoire comme celle que je montre ci-dessous?
* 51984c7 Merge branch 'topic' [master]
|\
| * b62cae6 2 [topic]
* | e7affba 4 [Origin/master]
* | eb3b733 3
|/
* 38abeae 1
Il y a deux options ici.
La première consiste à créer une base interactive, à modifier la validation de fusion, à rétablir la fusion manuellement et à poursuivre la base.
Une autre consiste à utiliser l'option -p
sur git rebase
, décrite comme suit dans le manuel: "Au lieu d'ignorer les fusions, essayez de les recréer." Cette question explique plus en détail: Que fait exactement (et pourquoi?) La "rebase - conservation-fusion" de git
Ok, c’est une vieille question et elle a déjà accepté la réponse par @siride
, mais cette réponse n’était pas suffisante dans mon cas, car --preserve-merges
vous oblige à résoudre tous les conflits une seconde fois. Ma solution basée sur l'idée de @Tobi B
mais avec des commandes exactes, étape par étape
Nous allons donc commencer sur un tel état en nous basant sur l'exemple de la question:
* 8101fe3 Merge branch 'topic' [HEAD -> master]
|\
| * b62cae6 2 [topic]
| |
| | * f5a7ca8 5 [Origin/master]
| | * e7affba 4
| |/
|/|
* | eb3b733 3
|/
* 38abeae 1
Notez que nous avons 2 commits ahead master, donc le choix de cerises ne fonctionnerait pas.
Tout d’abord, créons l’historique correcte que nous voulons:
git checkout -b correct-history # create new branch to save master for future
git rebase -s ours -p Origin/master
-p
signifie --preserve-merges
, nous l'utilisons pour enregistrer notre commit de fusion dans l'historique -s ours
signifie --strategy=ours
, nous l'utilisons pour ignorer tous les conflits de fusion car nous ne nous soucions pas du contenu de ce commit de fusion, nous n'avons besoin que de l'historique à présent.
L'histoire ressemblera à cela (en ignorant le maître):
* 51984c7 Merge branch 'topic' [HEAD -> correct-history]
|\
| * b62cae6 2 [topic]
* | f5a7ca8 5 [Origin/master]
* | e7affba 4
* | eb3b733 3
|/
* 38abeae 1
Soyons correct index maintenant.
git checkout master # return to our master branch
git merge Origin/master # merge Origin/master on top of our master
Nous pourrions obtenir quelques conflits de fusion supplémentaires ici, mais cela ne serait que des conflits de fichiers modifiés entre 8101fe3
et f5a7ca8
, mais n'inclut pas les conflits déjà résolus de topic
L'histoire ressemblera à ceci (en ignorant l'historique correct):
* 94f1484 Merge branch 'Origin/master' [HEAD -> master]
|\
* | f5a7ca8 5 [Origin/master]
* | e7affba 4
| * 8101fe3 Merge branch 'topic'
| |\
| | * b62cae6 2 [topic]
|/ /
* / eb3b733 3
|/
* 38abeae 1
La dernière étape consiste à combiner notre branche avec un historique correct et une branche avec un index correct
git reset --soft correct-history
git commit --amend
Nous utilisons reset --soft
pour réinitialiser notre branche (et notre historique) afin de corriger l’historique, mais nous laissons l’index et l’arbre de travail tels quels. Ensuite, nous utilisons commit --amend
pour réécrire notre commit de fusion, qui avait un index incorrect, avec notre bon index de maître.
À la fin, nous aurons un tel état (notez un autre identifiant de top commit):
* 13e6d03 Merge branch 'topic' [HEAD -> master]
|\
| * b62cae6 2 [topic]
* | f5a7ca8 5 [Origin/master]
* | e7affba 4
* | eb3b733 3
|/
* 38abeae 1
Étant donné que je venais de perdre une journée à essayer de résoudre ce problème et de trouver une solution avec l’aide d’un collègue, j’ai pensé que je devrais intervenir.
Nous avons une base de code volumineuse et nous devons gérer deux modifications importantes en même temps. Il y a une branche principale et une branche secondaire si vous qui.
Tandis que je fusionne la branche secondaire dans la branche principale, le travail continue dans la branche principale et lorsque j'ai terminé, je ne peux plus appliquer mes modifications car elles sont incompatibles.
Je dois donc "rebaser" ma "fusion".
Voici comment nous l'avons finalement fait:
1) notez le SHA. ex .: c4a924d458ea0629c0d694f1b9e9576a3ecf506b
git log -1
2) Créez l'historique approprié mais cela rompra la fusion.
git rebase -s ours --preserve-merges Origin/master
3) prendre note de la SHA. ex .: 29dd8101d78
git log -1
4) maintenant réinitialiser à où vous étiez avant
git reset c4a924d458ea0629c0d694f1b9e9576a3ecf506b --hard
5) Maintenant, fusionnez le master actuel dans votre branche active
git merge Origin/master
git mergetool
git commit -m"correct files
6) Maintenant que vous avez les bons fichiers, mais le mauvais historique, obtenez le bon historique En plus de votre modification avec:
git reset 29dd8101d78 --soft
7) Et ensuite - modifiez les résultats dans votre commit de fusion original
git commit --amend
Voila!
Il semble que ce que vous voulez faire est de supprimer votre première fusion. Vous pouvez suivre la procédure suivante:
git checkout master # Let's make sure we are on master branch
git reset --hard master~ # Let's get back to master before the merge
git pull # or git merge remote/master
git merge topic
Cela vous donnerait ce que vous voulez.