Utilisez git rebase --interactive
pour modifier cette validation antérieure, exécutez git reset HEAD~
et ensuite git add -p
pour en ajouter, puis faire un commit, puis en ajouter d'autres et faire un autre commit, autant de fois que vous le souhaitez. Quand vous avez terminé, lancez git rebase --continue
et vous aurez tous les commits séparés plus tôt dans votre pile.
Important : Notez que vous pouvez jouer et faire tous les changements que vous voulez, et ne pas avoir à vous soucier de la perte des anciens changements, parce que vous pouvez toujours exécuter la commande git reflog
pour trouver le point dans votre projet qui contient les changements que vous voulez, (appelons-le a8c4ab
), et ensuite git reset a8c4ab
.
Voici une série de commandes pour montrer comment cela fonctionne :
mkdir git-test; cd git-test; git init
ajoutez maintenant un fichier A
vi A
ajouter cette ligne :
one
git commit -am one
puis ajoutez cette ligne à A :
two
git commit -am two
puis ajoutez cette ligne à A :
three
git commit -am three
maintenant le fichier A ressemble à ceci :
one
two
three
et notre git log
ressemble à ce qui suit (en fait, j'utilise git log --pretty=oneline --pretty="%h %cn %cr ---- %s"
bfb8e46 Rose Perrone 4 seconds ago ---- three
2b613bc Rose Perrone 14 seconds ago ---- two
9aac58f Rose Perrone 24 seconds ago ---- one
Disons que nous voulons diviser le deuxième commit, two
.
git rebase --interactive HEAD~2
Cela fait apparaître un message qui ressemble à ceci :
pick 2b613bc two
pick bfb8e46 three
Changez le premier pick
à un e
pour modifier ce commit.
git reset HEAD~
git diff
nous montre que nous venons de déstocker le commit que nous avons fait pour le second commit :
diff --git a/A b/A
index 5626abf..814f4a4 100644
--- a/A
+++ b/A
@@ -1 +1,2 @@
one
+two
Mettons en scène ce changement, et ajoutons "et un troisième" à cette ligne dans le fichier A
.
git add .
C'est généralement à ce moment-là, au cours d'un rebasement interactif, que l'on lance la commande git rebase --continue
parce que nous voulons généralement revenir en arrière dans notre pile de commits pour modifier un commit précédent. Mais cette fois, nous voulons créer un nouveau commit. Donc nous allons lancer git commit -am 'two and a third'
. Maintenant nous éditons le fichier A
et ajoutez la ligne two and two thirds
.
git add .
git commit -am 'two and two thirds'
git rebase --continue
Nous avons un conflit avec notre engagement, three
alors résolvons-le :
Nous allons changer
one
<<<<<<< HEAD
two and a third
two and two thirds
=======
two
three
>>>>>>> bfb8e46... three
à
one
two and a third
two and two thirds
three
git add .; git rebase --continue
Maintenant, notre git log -p
ressemble à ça :
commit e59ca35bae8360439823d66d459238779e5b4892
Author: Rose Perrone <roseperrone@fake.com>
Date: Sun Jul 7 13:57:00 2013 -0700
three
diff --git a/A b/A
index 5aef867..dd8fb63 100644
--- a/A
+++ b/A
@@ -1,3 +1,4 @@
one
two and a third
two and two thirds
+three
commit 4a283ba9bf83ef664541b467acdd0bb4d770ab8e
Author: Rose Perrone <roseperrone@fake.com>
Date: Sun Jul 7 14:07:07 2013 -0700
two and two thirds
diff --git a/A b/A
index 575010a..5aef867 100644
--- a/A
+++ b/A
@@ -1,2 +1,3 @@
one
two and a third
+two and two thirds
commit 704d323ca1bc7c45ed8b1714d924adcdc83dfa44
Author: Rose Perrone <roseperrone@fake.com>
Date: Sun Jul 7 14:06:40 2013 -0700
two and a third
diff --git a/A b/A
index 5626abf..575010a 100644
--- a/A
+++ b/A
@@ -1 +1,2 @@
one
+two and a third
commit 9aac58f3893488ec643fecab3c85f5a2f481586f
Author: Rose Perrone <roseperrone@fake.com>
Date: Sun Jul 7 13:56:40 2013 -0700
one
diff --git a/A b/A
new file mode 100644
index 0000000..5626abf
--- /dev/null
+++ b/A
@@ -0,0 +1 @@
+one
66 votes
Une bonne source pour apprendre à le faire est Pro Git §6.4 Outils Git - Réécrire l'histoire dans la section "Fractionnement d'un engagement".
7 votes
Les documents liés au commentaire ci-dessus sont excellents, mieux expliqués que les réponses ci-dessous.
3 votes
Je suggère l'utilisation de cet alias stackoverflow.com/a/19267103/301717 . Il permet de diviser un commit en utilisant
git autorebase split COMMIT_ID
2 votes
La chose la plus facile à faire sans un rebasement interactif est (probablement) de créer une nouvelle branche en commençant par le commit précédant celui que vous voulez scinder, cherry-pick -n le commit, reset, stash, commit le déplacement du fichier, réapplication du stash et commit des changements, et ensuite soit fusionner avec l'ancienne branche ou cherry-pick les commits qui ont suivi. (Puis changez le nom de l'ancienne branche en tête actuelle) (Il est probablement préférable de suivre les conseils de MBO et de faire un rebasement interactif) (Copié de la réponse de 2010 ci-dessous).
3 votes
J'ai rencontré ce problème après avoir accidentellement écrasé deux commits lors d'un rebasement dans un commit précédent. Ma façon de résoudre le problème était de vérifier le commit écrasé,
git reset HEAD~
,git stash
entoncesgit cherry-pick
le premier commit au sein du squash, puisgit stash pop
. Mon cas de cherry-pick est assez spécifique ici, maisgit stash
ygit stash pop
est très pratique pour d'autres.