Prenons le cas suivant:
J'ai du travail dans une branche thématique et maintenant je suis prêt à reprendre le master:
* 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 récupération et remarque que la branche principale distante a de nouveaux changements:
* 8101fe3 Merge branch 'topic' [master]
|\
| * b62cae6 2 [topic]
| | * e7affba 4 [origin/master]
| |/
|/|
* | eb3b733 3
|/
* 38abeae 1
Si j'essaye 'git rebase origin / master' de master, 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 rebaser le commit de fusion afin que je me retrouve avec un historique comme celui que je montre ci-dessous?
* 51984c7 Merge branch 'topic' [master]
|\
| * b62cae6 2 [topic]
* | e7affba 4 [origin/master]
* | eb3b733 3
|/
* 38abeae 1
git
merge
rebase
git-rebase
git-rewrite-history
jipumarino
la source
la source
git rebase --preserve-merges origin/master
git config --global pull.rebase preserve
pour toujours préserver les commits de fusion lors d'un rebasegit --rebase-merges
remplacera à terme l'anciengit --preserve-merges
. Voir Que fait exactement «rebase --preserve-merges
» de Git (et pourquoi?)--preserve-merges
est obsolète. Utilisationgit rebase --rebase-merges origin/master
Réponses:
Il y a deux options ici.
La première consiste à effectuer un rebase interactif et à modifier la validation de fusion, à refaire la fusion manuellement et à continuer le rebase.
Une autre consiste à utiliser l'
--rebase-merges
option ongit rebase
, qui est décrite comme suit dans le manuel: "Par défaut, un rebase supprimera simplement les commits de fusion de la liste des tâches et placera les commits rebasés dans une seule branche linéaire. Avec --rebase- fusionne, le rebase essaiera à la place de préserver la structure de branchement dans les commits qui doivent être rebasés, en recréant les commits de fusion. Tous les conflits de fusion résolus ou les modifications manuelles dans ces commits de fusion devront être résolus / réappliqués manuellement. "la source
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 deuxième fois. Ma solution basée sur l'idée@Tobi B
mais avec des commandes pas à pas exactesNous allons donc commencer sur un tel état en nous basant sur l'exemple de la question:
Notez que nous avons 2 commits devant master, donc le cherry-pick ne fonctionnerait pas.
Tout d'abord, créons l'historique correct que nous voulons:
Nous utilisons
--preserve-merges
pour enregistrer notre validation de fusion dans l'historique. Nous utilisons--strategy=ours
pour ignorer tous les conflits de fusion car nous ne nous soucions pas du contenu de cette validation de fusion, nous n'avons besoin que d'un bel historique maintenant.L'histoire ressemblera à ça (en ignorant le maître):
Obtenons l'index correct maintenant.
Nous pouvons avoir des conflits de fusion supplémentaires ici, mais ce ne serait que des conflits de fichiers modifiés entre
8101fe3
etf5a7ca8
, mais n'inclut pas les conflits déjà résolus à partir detopic
L'historique ressemblera à ceci (en ignorant l'historique correct):
La dernière étape consiste à combiner notre branche avec un historique correct et une branche avec un index correct
Nous utilisons
reset --soft
pour réinitialiser notre branche (et notre historique) à l'historique correct, mais laissons l'index et l'arbre de travail tels quels. Ensuite, nouscommit --amend
réécrivons notre validation de fusion, qui avait un index incorrect, avec notre bon index de master.À la fin, nous aurons un tel état (notez un autre identifiant du commit supérieur):
la source
git commit --amend
ajoute les modifications au dernier commit (HEAD, dans ce cas le commit de fusion). Étant donné que le contenu de la validation change, le hachage est mis à jour.Étant donné que je viens de perdre une journée à essayer de comprendre cela et que j'ai trouvé une solution avec l'aide d'un collègue, j'ai pensé que je devrais intervenir.
Nous avons une grande base de code et nous devons faire face à 2 branches fortement modifiées en même temps. Il y a une branche principale et une branche secondaire si vous le souhaitez.
Pendant que je fusionne la branche secondaire dans la branche principale, le travail se poursuit dans la branche principale et au moment où j'en ai terminé, je ne peux pas appliquer mes modifications car elles sont incompatibles.
J'ai donc besoin de "rebaser" ma "fusion".
Voici comment nous l'avons finalement fait:
1) notez le SHA. ex .: c4a924d458ea0629c0d694f1b9e9576a3ecf506b
2) Créez l'historique approprié, mais cela interrompra la fusion.
3) notez le SHA. ex .: 29dd8101d78
4) Maintenant, réinitialisez à l'endroit où vous étiez auparavant
5) Maintenant, fusionnez le maître actuel dans votre branche de travail
6) Maintenant que vous avez les bons fichiers, mais le mauvais historique, obtenez le bon historique en plus de vos modifications avec:
7) Et puis - modifiez les résultats de votre validation de fusion d'origine
Voila!
la source
Il semble que vous souhaitiez supprimer votre première fusion. Vous pouvez suivre la procédure suivante:
Cela vous donnerait ce que vous voulez.
la source
la source