Supprimer les anciens commits git

88

Je suis très nouveau dans git, et je me demandais si quelque chose comme ça est possible?

>git log --pretty=oneline --abbrev-commit
2f05aba Added new feature
3371cec Fixed screw up    <-- I want to remove this
daed25c Screw up          <-- and remove this.
e2b2a84 First.                So it's like they never happend.

Est-ce possible?

Josh
la source

Réponses:

63

Ceci est possible avec git rebase. Essayez ce qui suit

git rebase -i HEAD~4

puis, suivez les instructions interactives de votre éditeur. Dans la première étape, vous «écrasez» les commits. Ça devrait ressembler a quelque chose comme ca:

pick 2f05aba ... will be preserved
squash 3371cec ... will be squashed with daed25c
squash daed25c ... will be squashed with e2b2a84
pick e2b2a84 .. will contain this and 3371cec and daed25c

Dans la deuxième étape, vous pouvez modifier les messages de validation.

Deve
la source
25
La question n'est-elle pas de supprimer les commits plutôt que de les écraser?
Richard
3
@Stony: Eh bien, vous pourriez probablement aussi les supprimer. Mais à partir des commentaires de commit dans l'OP ("Screw up" et "Fixed viss up"), j'ai supposé que l'un annule l'autre et que vous pourriez aussi bien écraser les deux.
Deve
85

Si vous souhaitez vraiment les supprimer (les effacer de l'historique, pour ne plus jamais les voir), vous pouvez

exécuter rebase:

git rebase -i HEAD~4

puis, supprimez (ou commentez) les lignes correspondant aux commits que vous souhaitez supprimer, comme ceci:

pick 2f05aba ... #will be preserved
#pick 3371cec ... #will be deleted
#pick daed25c ... #will be deleted
pick e2b2a84 ... #will be preserved
Shathur
la source
2
Je suis nouveau sur github, comment poussez-vous les changements après cela (quand je clique sur Sync, cela revient simplement à ce que j'ai fait) Je pense que je l'ai compris: git push origin HEAD --force
Nicolas Thery
@NicolasThery vous ne le faites pas. C'est pourquoi git push refuse de fonctionner sans --force, car vous réécrivez l'historique et vous casserez les référentiels d'autres personnes. Si vous avez déjà poussé, votre seule option est de faire un git revert. Ce qui, quand vous y réfléchissez, est judicieux parce que si vous tiriez le code de quelqu'un d'autre, vous ne voudriez pas qu'il puisse effacer vos anciens commits sans une sorte d'histoire, n'est-ce pas?
Angry Dan
Je suppose que cela fonctionne simplement dans le dépôt Git actuel et ne change rien en amont / tout autre nœud Git?
Alexander Mills
2
@AlexanderMills Cela ne change rien en amont tant que vous ne le poussez pas (et si vous le faites, vous devez ajouter le drapeau --force comme l'a dit Angry Dan).
Shathur
dou dropest la commande pour supprimer les commits de l'historique.
Panier abandonné
5

Pour supprimer complètement les commit (s), il existe dropmaintenant une nouvelle option pour les rebases interactifs git. Première exécution:

git rebase -i HEAD~4

Remplacez ensuite pickpar droppour le (s) commit (s) à supprimer:

pick 2f05aba ... #will be preserved
drop 3371cec ... #will be dropped
drop daed25c ... #will be dropped
pick e2b2a84 ... #will be preserved

Cela a fonctionné sur Fedora pour moi avec la version suivante:

$ git version
git version 2.21.0
russoue
la source
2

Squash est utile lorsque vous souhaitez générer une liste de commits fusionnés sous un seul hachage, mais si vous cherchez à prendre trois commits séparés et à avoir une sortie finale qui ressemble à un seul commit, je recommande fixup

git rebase -i HEAD~4

pick 2f05aba ... will be preserved
fixup 3371cec ... will be merged with daed25c
fixup daed25c ... will be merged with e2b2a84
pick e2b2a84 .. will include 3371cec and daed25c, but only the commit message of e2b2a84

Vous pouvez trouver plus d'informations dans la liste des commandes de l'interface utilisateur de rebase interactif.

Panier abandonné
la source