Comment modifier l'ancien git commit? [dupliquer]

cette question a déjà une réponse ici:

j'ai fait 3 git commits, mais je n'ai pas été poussé. Comment puis-je modifier l'ancienne (DD 6859af44) et (47175e84c) qui n'est pas la plus récente?

$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
120
demandé sur michael 2012-01-11 22:52:56

6 réponses

git rebase -i HEAD^^^

Inscrivez maintenant ceux que vous voulez modifier avec edit ou e (remplacer pick ). Maintenant, enregistrez et sortez.

faites vos modifications, puis

git add -A
git commit --amend --no-edit
git rebase --continue

si vous voulez ajouter une suppression supplémentaire supprimez les options de la commande commit. Si vous voulez ajuster le message, omettez simplement l'option --no-edit .

156
répondu Adam Dymitruk 2016-11-08 22:58:30

j'ai préparé mon engagement que je voulais amender avec un ancien et j'ai été surpris de voir ce rebase-je me suis plaint que j'ai des changements non engagés. Mais je ne voulais pas refaire mes modifications en spécifiant l'option edit de l'ancienne commit. La solution était donc simple et simple:

  1. préparez votre mise à jour à l'ancien commit, ajoutez-le et commit
  2. git rebase -i <commit you want to amend>^ - notez le ^ ainsi vous voyez le dit commit dans le éditeur de texte
  3. vous 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
    
  4. maintenant pour combiner e23d23a avec 8c83e24 vous pouvez changer l'ordre de ligne 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
    
  5. écrivez et quittez le fichier, vous serez présent avec un éditeur pour fusionner les messages de propagation. Faire et enregistrer/quitter le document texte

  6. vous êtes fait, votre

crédit attribué à: http://git-scm.com/book/en/Git-Tools-Rewriting-History Il y a aussi d'autres Gits magiques.

82
répondu akostadinov 2013-09-03 13:27:33

vous pouvez utiliser git rebase pour réécrire l'historique de propagation. Cela peut être potentiellement destructeur pour vos changements, donc utilisez avec soin.

commettez D'abord votre Modification" Modifier " comme une propagation normale. Ensuite, faites un rebase interactif à partir du parent de votre plus ancien commit

git rebase -i 47175e84c2cb7e47520f7dde824718eae3624550^

cela va allumer votre éditeur avec toutes les propagations. Les réorganiser afin que votre "modifier" s'engager vient en dessous de celle que vous voulez modifier. Puis remplacer le premier mot sur la ligne avec le" modifier "commit avec s qui combinera ( s annuler) il avec le commit avant. Enregistrez et quittez votre éditeur et suivez les instructions.

11
répondu Benjamin Bannier 2012-01-11 19:17:33

vous pouvez utiliser git rebase --interactive , en utilisant la commande edit sur la propagation que vous voulez modifier.

9
répondu Avi 2012-01-11 19:01:30

j'ai utilisé un autre moyen pour quelques temps. En fait, il s'agit d'un manuel git rebase -i et il est utile lorsque vous voulez réarranger plusieurs commits y compris écraser ou diviser certains d'entre eux. Le principal avantage est que vous n'avez pas à décider du destin de chaque commit à un moment donné. Vous aurez également toutes les fonctionnalités Git disponibles au cours du processus, contrairement à ce qui se passe lors d'un rebase. Par exemple, vous pouvez afficher le journal de l'histoire originale et réécrite à tout moment, ou même faire une autre rebase!

je vais faire référence aux commits de la manière suivante, il est donc 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

Procédure

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 partager votre ancienne responsabilité 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-en:

git checkout master
git reset --hard rewrite-history  # make this branch master

C'est ça, vous pouvez push vos progrès maintenant.

9
répondu Melebius 2018-08-08 08:18:09

dans le cas où L'OP veut écraser les 2 propagations spécifiées en 1, Voici une autre façon de le faire sans rebaser

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

la syntaxe @{N) est pratique à savoir car elle vous permettra de faire référence à l'histoire de l'endroit où vos références étaient. Dans ce cas, C'est HEAD qui représente votre commit actuel.

2
répondu Adam Dymitruk 2012-01-11 20:52:29