5425 votes

Squash mon dernier X s'engage à l'aide de Git

Comment puis-je squash mon dernier X s'engage dans un commit avec Git?

5630voto

Chris Johnsen Points 50064

Vous pouvez le faire assez facilement, sans git rebase ou git merge --squash.

Si vous voulez écrire le nouveau message de commit à partir de zéro, cela suffit:

git reset --soft HEAD~3 &&
git commit

Si vous voulez commencer à éditer le nouveau message de commit avec une concaténation de l'existant, des messages de commit (c'est à dire similaire à ce qu'un pick/squash/squash/.../squash git rebase -i liste d'instructions serait de commencer à vous), alors vous avez besoin pour extraire ces messages et de les transmettre git commit:

git reset --soft HEAD~3 && 
git commit --edit -m"$(git log --format=%B --reverse HEAD..HEAD@{1})"

Ces deux méthodes de squash les trois dernières s'engage dans un nouveau s'engager dans la même voie. Le soft reset viens de re-points de la TÊTE au dernier commit que vous ne voulez pas de la courge. Ni index, ni l'arbre de travail sont touchés par le soft reset, laissant l'index dans l'état souhaité pour votre nouveau commit (c'est à dire qu'il a déjà toutes les modifications dans les commits que vous êtes sur le point de "jeter").

2967voto

Anomie Points 43759

Utiliser git rebase -i <after-this-commit> et remplacer "pick" sur la deuxième et les suivantes s'engage à "écraser" ou "correction", comme décrit dans le manuel.

1006voto

Mark Longair Points 93104

Vous pouvez utiliser git merge --squash pour ce, qui est un peu plus élégant que d' git rebase -i. Supposons que vous êtes sur le master et vous souhaitez écraser les 12 derniers s'engage dans une. Vérifiez d'abord que l' git status est propre (depuis git reset --hard jetteront mise en scène et unstaged les modifications), puis:

# Reset the current branch to the commit just before the last 12:
git reset --hard HEAD~12

# HEAD@{1} is where the branch was just before the previous command.
# This command sets the state of the index to be as it would just
# after a merge from that commit:
git merge --squash HEAD@{1}

# Commit those squashed changes.  The commit message will be helpfully
# prepopulated with the commit messages of all the squashed commits:
git commit

La documentation pour l' git merge décrit l' --squash option plus en détail.


Mise à jour: le seul véritable avantage de cette méthode de plus simple, git reset --soft HEAD~12 && git commit proposé par Chris Brown dans sa réponse est que vous obtenez le message de commit préremplie avec chaque message de commit que vous êtes à l'écraser.

320voto

nobar Points 5849

Je recommande d'éviter git reset lorsque cela est possible-en particulier pour Git-novices. Sauf si vous avez vraiment besoin pour automatiser un processus basé sur un certain nombre de commits, il est moins exotique façon...

  1. Mis à être écrasé s'engage sur un plan de travail de la branche (si elles ne le sont pas déjà) -- utiliser gitk pour cette
  2. Découvrez la branche cible (par exemple, "maître")
  3. git merge --squash (working branch name)
  4. git commit

Le message de commit sera prédéfinie basée sur la courge.

163voto

EthanB Points 2165

Basé sur Chris Brown réponse:

J'ai ajouté cette ligne à l' [alias] section de mon git config fichier (~/.gitconfig):

squash = "!f(){ git reset --soft HEAD~${1} && git commit --edit -m\"$(git log --format=%B --reverse HEAD..HEAD@{1})\"; };f"


Utilisation:

git squash N

... Qui automatiquement de courges la dernière N s'engage, inclusivement.




Ma solution précédente était-ce [alias]:

squash = "!f(){ git rebase -i HEAD~${1}; }; f"

... qui a le même usage, mais vous oblige à modifier le "git-git rebase-todo" fichier (et le changement pick de squash).

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