246 votes

Comment supprimer certaines entrées du journal des livraisons d'un dépôt Git tout en conservant leurs modifications ?

J'aimerais supprimer des entrées sélectionnées dans le journal des livraisons d'un arbre de livraison linéaire, afin que ces entrées n'apparaissent pas dans le journal des livraisons.

Mon arbre de commit ressemble à quelque chose comme :

R--A--B--C--D--E--HEAD

J'aimerais supprimer les entrées B et C afin qu'elles n'apparaissent pas dans le journal de livraison, mais les modifications de A à D doivent être préservées. Peut-être en introduisant un seul commit, de sorte que B et C deviennent BC et que l'arbre ressemble à ceci.

R--A--BC--D--E--HEAD

Ou, idéalement, après A vient directement D. D' représentant les changements de A à B, B à C et C à D.

R--A--D'--E--HEAD

Est-ce possible ? Si oui, comment ?

Il s'agit d'un projet relativement nouveau qui n'a pas de branches pour le moment, et donc pas de fusions non plus.

0 votes

@xk0der : "commits" est le bon terme ici. rebase peut supprimer d'anciens commits/créer de nouveaux. Je ne sais pas ce que signifie "commit log entries".

0 votes

@J.F.Sebastian Je ne vois pas de problème avec "commit log" - Journal de tous les commits. Et je voulais supprimer quelques entrées du journal - tout en gardant les changements réels (les commits).

0 votes

@xk0der : les commits git sont adressables par le contenu c'est-à-dire que si vous changez tout ce qui est dans un commit, par exemple, son message de journal ; vous créez un nouveau commit. Vous pouvez lisez le commit de git sans git et voyez par vous-même .

276voto

J.F. Sebastian Points 102961

git-rebase(1) fait exactement cela.

$ git rebase -i HEAD~5

git awsome-ness [git rebase --interactive] contient un exemple.

  1. N'utilisez pas git-rebase sur les commits publics (à distance).
  2. Assurez-vous que votre répertoire de travail est propre ( commit o stash vos changements actuels).
  3. Exécutez la commande ci-dessus. Elle lance votre $EDITOR .
  4. Remplacer pick avant C y D por squash . Il fusionnera C et D en B. Si vous voulez supprimer un commit, il suffit de supprimer sa ligne.

Si vous êtes perdu, tapez :

$ git rebase --abort

0 votes

Merci pour cette réponse rapide. Je dois donc extraire A et faire un rebasement, quelque chose comme git rebase -i D [A] ?

6 votes

3 votes

Comment le faire sur des dépôts distants ?

76voto

Charles Bailey Points 244082
# detach head and move to D commit
git checkout <SHA1-for-D>

# move HEAD to A, but leave the index and working tree as for D
git reset --soft <SHA1-for-A>

# Redo the D commit re-using the commit message, but now on top of A
git commit -C <SHA1-for-D>

# Re-apply everything from the old D onwards onto this new place 
git rebase --onto HEAD <SHA1-for-D> master

0 votes

Cela fonctionne aussi et m'a aidé à comprendre ce qu'est une réinitialisation douce. Je reconnais que la réponse "supérieure" est également correcte et plus courte, mais merci pour cette réponse également.

41voto

rado Points 1709

Voici un moyen de supprimer un identifiant de commit spécifique en ne connaissant que l'identifiant de commit que vous souhaitez supprimer.

git rebase --onto commit-id^ commit-id

Notez que cela supprime en fait le changement qui a été introduit par le commit.

7 votes

Le HEAD supplémentaire dans cette commande fera que le rebasement se terminera avec un 'detached HEAD', ce qui n'est pas souhaitable. Il doit être omis.

3 votes

Cela annule les changements introduits par mon commit-id, le PO veut conserver les changements, il faut juste écraser les commits.

1 votes

-1 parce qu'il ne fait pas ce que le PO a demandé (il détruit plutôt quelque chose qu'il voulait explicitement conserver).

20voto

idbrise Points 4551

Pour développer la réponse de J.F. Sebastian :

Vous pouvez utiliser git-rebase pour apporter facilement toutes sortes de modifications à votre historique de livraison.

Après avoir exécuté git rebase --interactive, vous obtenez ce qui suit dans votre $EDITOR :

pick 366eca1 This has a huge file
pick d975b30 delete foo
pick 121802a delete bar
# Rebase 57d0b28..121802a onto 57d0b28
#
# Commands:
#  p, pick = use commit
#  r, reword = use commit, but edit the commit message
#  e, edit = use commit, but stop for amending
#  s, squash = use commit, but meld into previous commit

Vous pouvez déplacer des lignes pour changer l'ordre des commits et supprimer des lignes pour supprimer ce commit. Ou vous pouvez ajouter une commande pour combiner (écraser) deux commits en un seul (le commit précédent est le commit ci-dessus), éditer les commits (ce qui a été changé), ou reformuler les messages de commit.

Je pense que le choix signifie simplement que vous voulez laisser cet engagement tranquille.

(L'exemple est tiré de aquí )

14voto

Head Points 2233

Vous pouvez, de manière non-interactive supprimer B et C dans votre exemple avec :

git rebase --onto HEAD~5 HEAD~3 HEAD

ou symboliquement,

git rebase --onto A C HEAD

Notez que les changements en B et C no être en D ; ils seront disparu .

0 votes

Voir ici pour plus d'informations : sethrobertson.github.io/GitFixUm/fixup.html#remove_deep

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X