J'ai fait 3 commits git, mais je n'ai pas été poussé. Comment puis-je modifier l'ancien (ddc6859af44) et (47175e84c), qui n'est pas le plus récent?
$git log
commit f4074f289b8a49250b15a4f25ca4b46017454781
Date: Tue Jan 10 10:57:27 2012 -0800
commit ddc6859af448b8fd2e86dd0437c47b6014380a7f
Date: Mon Jan 9 16:29:30 2012 -0800
commit 47175e84c2cb7e47520f7dde824718eae3624550
Date: Mon Jan 9 13:13:22 2012 -0800
git rebase -i HEAD^^^
Marquez maintenant ceux que vous souhaitez modifier avec edit
ou e
(remplacez pick
). Maintenant, enregistrez et quittez.
Maintenant, faites vos modifications, puis
git add -A
git commit --amend --no-edit
git rebase --continue
Si vous souhaitez ajouter une suppression supplémentaire, supprimez les options de la commande commit. Si vous souhaitez ajuster le message, omettez simplement le --no-edit
option.
J'ai préparé mon engagement que je voulais modifier avec un ancien et j'ai été surpris de voir que Rebase -i se plaignait de modifications non engagées. Mais je ne voulais plus effectuer mes modifications en spécifiant l’option d’édition du commit précédent. La solution était donc simple et facile:
git rebase -i <commit you want to amend>^
- remarquez le ^
donc vous voyez le dit commit dans l'éditeur de textevous obtiendrez quelque chose comme ceci:
pick 8c83e24 use substitution instead of separate subsystems file to avoid jgroups.xml and jgroups-e2.xml going out of sync
pick 799ce28 generate ec2 configuration out of subsystems-ha.xml and subsystems-full-ha.xml to avoid discrepancies
pick e23d23a fix indentation of jgroups.xml
maintenant, pour combiner e23d23a avec 8c83e24, vous pouvez modifier l’ordre des lignes et utiliser squash comme ceci:
pick 8c83e24 use substitution instead of separate subsystems file to avoid jgroups.xml and jgroups-e2.xml going out of sync
squash e23d23a fix indentation of jgroups.xml
pick 799ce28 generate ec2 configuration out of subsystems-ha.xml and subsystems-full-ha.xml to avoid discrepancies
écrivez et quittez le fichier, vous serez présent avec un éditeur pour fusionner les messages de commit. Faites-le et enregistrez/quittez le document texte
le crédit va à: http://git-scm.com/book/en/Git-Tools-Rewriting-History Il y a aussi une autre magie démontrée utile.
Vous pouvez utiliser git rebase
pour réécrire l'historique de commit. Cela peut être potentiellement destructeur pour vos modifications, utilisez-le avec précaution.
Commencez par valider votre modification "amendée" comme une validation normale. Faites ensuite une rebase interactive à partir du parent de votre plus ancien commit.
git rebase -i 47175e84c2cb7e47520f7dde824718eae3624550^
Cela lancera votre éditeur avec tous les commits. Réorganisez-les pour que votre engagement de modification vienne en dessous de celui que vous souhaitez modifier. Remplacez ensuite le premier mot sur la ligne par le mot-clé "modifier" avec s
qui le combinera (s quash) avec le commit avant. Enregistrez et quittez votre éditeur et suivez les instructions.
J'ai utilisé un autre moyen plusieurs fois. En fait, c’est un manuel git rebase -i
et il est utile lorsque vous souhaitez réorganiser plusieurs commits, notamment en écrasant ou en divisant certains d'entre eux. Le principal avantage est que vous n'avez pas à décider du destin de chaque engagement à un moment donné. Toutes les fonctionnalités de Git seront également disponibles au cours du processus, contrairement à ce qui se passe au cours d’une base Par exemple, vous pouvez afficher le journal de l'historique original et de l'historique réécrit à tout moment, ou même effectuer une autre base!
Je vais faire référence aux commits de la manière suivante, pour que ce soit facilement lisible:
C # good commit after a bad one
B # bad commit
A # good commit before a bad one
Votre histoire au début ressemble à ceci:
x - A - B - C
| |
| master
|
Origin/master
Nous allons le recréer de cette façon:
x - A - B*- C'
| |
| master
|
Origin/master
git checkout B # get working-tree to the state of commit B
git reset --soft A # tell Git that we are working before commit B
git checkout -b rewrite-history # switch to a new branch for alternative history
Améliorez votre ancien commit en utilisant git add
(git add -i
, git stash
etc.) maintenant. Vous pouvez même diviser votre ancien commit en deux ou plus.
git commit # recreate commit B (result = B*)
git cherry-pick C # copy C to our new branch (result = C')
Résultat intermédiaire:
x - A - B - C
| \ |
| \ master
| \
| B*- C'
| |
| rewrite-history
|
Origin/master
Finissons:
git checkout master
git reset --hard rewrite-history # make this branch master
Ça y est, vous pouvez Push
votre progression maintenant.
Vous pouvez utiliser git rebase --interactive
, en utilisant la commande edit
sur le commit que vous souhaitez modifier.
Dans le cas où l'OP voudrait écraser les 2 commits spécifiés en 1, voici une autre façon de le faire sans changer de base.
git checkout HEAD^ # go to the first commit you want squashed
git reset --soft HEAD^ # go to the second one but keep the tree and index the same
git commit --amend -C HEAD@{1} # use the message from first commit (omit this to change)
git checkout HEAD@{3} -- . # get the tree from the commit you did not want to touch
git add -A # add everything
git commit -C HEAD@{3} # commit again using the message from that commit
Le @{N)
_ La syntaxe est pratique à connaître car elle vous permettra de référencer l’historique de vos références. Dans ce cas, c’est HEAD qui représente votre commit actuel.