web-dev-qa-db-fra.com

Rebaser un commit de fusion Git

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
141
jipumarino

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

101
siride

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.

  1. 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
    
  2. 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
    
  3. 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
    
15
Ivan Naydonov

É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!

3
Claude Peloquin

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.

1
Antoine Pelisse
  • De votre fusion fusionner
  • Cherry-pick le nouveau changement qui devrait être facile
  • copier vos affaires
  • refaites la fusion et résolvez les conflits en copiant simplement les fichiers de votre copie locale;)
0
Tobi B