web-dev-qa-db-fra.com

Comment puis-je séparer un commit Git enfoui dans l'histoire?

J'ai raté mon historique et je veux y apporter quelques modifications. Le problème, c'est que j'ai un commit avec deux modifications non liées et qu'il est entouré d'autres modifications de mon historique local (non poussé).

Je souhaite scinder ce commit avant de le publier, mais la plupart des guides que je vois concernent le fractionnement de votre dernier commit ou des modifications locales non validées. Est-il possible de le faire pour un commit qui est un peu enfoui dans l’histoire, sans avoir à refaire mes commit depuis?

286
Ben

Il existe un guide sur le fractionnement des commits dans la page de manuel Rebase . Le résumé rapide est:

  • Effectuez une réinitialisation interactive incluant la validation cible (par exemple, git rebase -i <commit-to-split>^ branch) et marquez-la pour la modifier.

  • Lorsque la base a atteint cette validation, utilisez git reset HEAD^ pour la réinitialiser avant la validation, tout en maintenant votre arbre de travail intact.

  • Ajoutez progressivement des modifications et validez-les, en effectuant autant de modifications que vous le souhaitez. add -p peut être utile pour n’ajouter que quelques modifications dans un fichier donné. Utilisez commit -c ORIG_HEAD si vous souhaitez réutiliser le message de validation d'origine pour une validation donnée.

  • Si vous souhaitez tester ce que vous commettez (bonne idée!), Utilisez git stash pour masquer la partie que vous n'avez pas validée (ou stash --keep-index avant même de la valider), testez, puis git stash pop, pour renvoyer le reste dans l'arbre de travail. Continuez à vous engager jusqu’à ce que toutes les modifications soient validées, c’est-à-dire que vous avez un arbre de travail vierge.

  • Exécutez git rebase --continue pour continuer à appliquer les validations après la validation maintenant divisée.

439
Cascabel

Voici comment faire avec Magit .

Dites commit ed417ae est celui que vous souhaitez modifier; il contient deux modifications non liées et est enterré sous un ou plusieurs commits. Appuyez sur ll pour afficher le journal et accédez à ed417ae:

 initial log

Cliquez ensuite sur r pour ouvrir la fenêtre contextuelle de la base.

 rebase popup

et m pour modifier le commit à un moment donné. 

Remarquez comment le @ est présent sur le commit que vous voulez scinder - cela signifie que HEAD est maintenant à ce commit:

 modifying a commit

Nous voulons déplacer HEAD vers le parent, donc naviguez jusqu'au parent (47e18b3) et tapez x (magit-reset-quickly, lié à o si vous utilisez evil-magit) et entrez-le pour dire "oui, je voulais dire commettre au point". Votre journal devrait maintenant ressembler à:

 log after resetting

A présent, appuyez sur q pour accéder au statut Magit normal, puis utilisez la commande régulière unstage u pour annuler ce qui ne va pas dans le premier commit, commit c le reste comme d'habitude, puis stage et commit ce qui se passe dans le second commit lorsque vous avez terminé: appuyez sur r pour ouvrir la fenêtre contextuelle de la base

 rebase popup

et un autre r pour continuer, et vous avez terminé! ll montre maintenant:

 all done log

2
unhammer

Pour scinder un commit <commit> et ajouter le new commit avant celui-ci et enregistrer la date de création de <commit>, - procédez comme suit:

  1. Editez le commit before <commit>

    git rebase -i <commit>^^
    

    NB: il faudra peut-être aussi éditer <commit>.

  2. Cherry pick <commit> dans l'index

    git cherry-pick -n <commit>
    
  3. Réinitialiser de manière interactive les modifications inutiles à partir de l'index et réinitialiser l'arborescence de travail

    git reset -p && git checkout-index -f -a
    

    Comme alternative, stockez simplement les modifications inutiles de manière interactive: git stash Push -p -m "tmp other changes"

  4. Apportez d'autres modifications (le cas échéant) et créez le nouveau commit

    git commit -m "upd something" .
    

    Répétez éventuellement les éléments 2 à 4 pour ajouter davantage de commits intermédiaires.

  5. Continuer à rebaser

    git rebase --continue
    
0
ruvim