Pregunta Aplaste mi última X se compromete con Git


¿Cómo puedo aplastar mis últimos X commits en un commit usando Git?


2314
2018-03-04 04:11


origen


Respuestas:


Utilizar git rebase -i <after-this-commit> y reemplace "pick" en el segundo y subsiguientes commits con "squash" o "fixup", como se describe en el manual.

En este ejemplo, <after-this-commit> es el hash SHA1 o la ubicación relativa del HEAD de la rama actual desde la cual se analizan los commits para el comando rebase. Por ejemplo, si el usuario desea ver 5 confirmaciones desde HEAD actual en el pasado, el comando es git rebase -i HEAD~5.


1267
2018-03-04 04:18



Puedes hacer esto bastante fácilmente sin git rebase o git merge --squash. En este ejemplo, aplastaremos los últimos 3 commits.

Si desea escribir el nuevo mensaje de compromiso desde cero, esto es suficiente:

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

Si desea comenzar a editar el nuevo mensaje de confirmación con una concatenación de los mensajes de confirmación existentes (es decir, similar a lo que es pick / squash / squash / ... / squash git rebase -i la lista de instrucciones comenzaría con), entonces necesita extraer esos mensajes y pasarlos a git commit:

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

Ambos métodos aplastan las últimas tres confirmaciones en una única confirmación nueva de la misma manera. El reinicio suave solo redirige HEAD al último commit que no desea aplastar. Ni el índice ni el árbol de trabajo son tocados por el reinicio por software, dejando el índice en el estado deseado para su nueva confirmación (es decir, ya tiene todos los cambios de las confirmaciones que está a punto de "descartar").


2587
2018-03-05 04:19



Puedes usar git merge --squash para esto, que es un poco más elegante que git rebase -i. Supongamos que está dominado y quiere aplastar los últimos 12 commits en uno.

ADVERTENCIA: Primero asegúrese de comprometer su trabajo; compruebe que git status está limpio (desde git reset --hard arrojará cambios por etapas y sin escena)

Entonces:

# 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

los documentación para git merge describe el --squash opción en más detalle.


Actualizar: la única ventaja real de este método sobre el más simple git reset --soft HEAD~12 && git commit sugerido por Chris Johnsen en su respuesta es que obtienes el mensaje de confirmación lleno de cada mensaje de compromiso que estás aplastando.


573
2018-03-04 06:10



Recomiendo evitar git reset cuando sea posible, especialmente para los principiantes Git. A menos que realmente necesite automatizar un proceso basado en un número de commits, hay una forma menos exótica ...

  1. Coloque los commits aplastados en una rama activa (si aún no lo están) - use gitk para esto
  2. Verifique la rama de destino (por ejemplo, 'maestro')
  3. git merge --squash (working branch name)
  4. git commit

El mensaje de confirmación se rellenará previamente en función de la calabaza.


135
2018-03-14 23:24



Residencia en La respuesta de Chris Johnsen,

Agregue un alias global de "squash" de bash: (o Git Bash en Windows)

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

... o usando el símbolo del sistema de Windows:

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


Tu ~/.gitconfig ahora debería contener este alias:

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


Uso:

git squash N

... que automáticamente aplasta la última N commits, inclusive

Nota: El mensaje de confirmación resultante es una combinación de todos los commit aplastados, en orden. Si no estás contento con eso, siempre puedes git commit --amendpara modificarlo manualmente (O edite el alias para que coincida con sus gustos).


97
2018-02-19 19:21



Si usa TortoiseGit, puede usar la función Combine to one commit:

  1. Abrir el menú contextual de TortoiseGit
  2. Seleccionar Show Log
  3. Marque las confirmaciones relevantes en la vista de registro
  4. Seleccionar Combine to one commit desde el menú contextual

Combine commits

Esta función ejecuta automáticamente todos los pasos de git individuales necesarios. Desafortunadamente, solo está disponible para Windows.


46
2017-11-06 12:51



Gracias a esta práctica publicación de blog Descubrí que puedes usar este comando para aplastar las últimas 3 confirmaciones:

git rebase -i HEAD~3

Esto es útil, ya que funciona incluso cuando se encuentra en una sucursal local sin información de seguimiento / repositorio remoto.

El comando abrirá el editor de rebase interactivo que luego le permite reordenar, aplastar, reescribir, etc., como lo hace normalmente.


46
2018-05-17 06:19