2011-07-30 15 views
53

Tengo la costumbre de hacer un gran número de commits pequeños, y estoy de acuerdo. Pero me gustaría, de vez en cuando, tomar un montón de esos compromisos lineales y colapsarlos juntos ya que solo uno se compromete con la capacidad de escribir un nuevo mensaje de compromiso.Colapsando un grupo de commits en uno en Git

He revisado la documentación, pero me pareció un poco críptico. ¿Alguien sabe cómo hacer eso?

+1

ver este Preguntas y Respuestas http: // stackoverflow.com/questions/250238/collapsing-a-git-repositorys-history – iafonov

Respuesta

47

Suponga que quiere volver a escribir la historia del árbol que se remonta hasta (pero no incluyendo) comprometerse a739b0d.

export EDITOR=vim # or your favorite editor 
git rebase a739b0d --interactive 

Asegúrese de leer en interactive rebasing primero.

+2

Pero digamos que los commits que quiero "rebase" están en el pasado, antes de un grupo de fusiones y ramas ... ¿Es esto? ¿todavía válido? – Rodrogo

+1

Sí. Primero puede volver a ordenar las confirmaciones cuando vuelva a establecer la base para que las confirmaciones que desea aplastar estén en una secuencia que siga a todas las fusiones. Entonces puedes aplastar esos commits juntos en un commit. – yfeldblum

+1

Su enlace no fue a ninguna parte específica para mí. http://git-scm.com/book/es/Git-Branching-Rebasing es la página de rebase; http://git-scm.com/book/en/Git-Tools-Rewriting-History tiene más de una visión general. –

5

Puede aplastar cualquier número de confirmaciones en una sola, utilizando

git rebase --interactive <commit> 
+3

Es importante considerar el caso cuando usted o algunos de sus colaboradores han ingresado en su repositorio en Github. Ver http://stackoverflow.com/questions/5667884/how-to-squash-commits-in-git-after-they-have-been-pushed – e3matheus

+0

Ese es un punto válido, pero dado que '-i' es lo mismo que '--interactive', la única diferencia es el' push'. –

+0

Mmm sí. Pero comenté eso solo para aclarar, que si ya presionaste para dominar antes de la rebase, este empuje debe hacerse a través de --force, ¿no ?. Y que si otro de tus colaboradores hizo un esfuerzo, no deberías hacer una rebase en absoluto. – e3matheus

13

Utilice el comando git rebase -i <commit> donde <commit> es el SHA de la última confirmación estable.

Esto lo llevará a su editor donde puede reemplazar la etiqueta pick que está al lado de cada confirmación desde el <commit> que incluyó como argumento para su comando de rebase interactivo. En el comando en el que desee comenzar el colapso, reemplace pick con reword, y para cada confirmación a partir de la cual desee colapsar, reemplace pick con fixup. Guarde, y luego se le permitirá proporcionar un nuevo mensaje de confirmación.

+2

en realidad, la mejor explicación que he visto de forma concisa y articulada ... –

+0

Sí, la manera más fácil. –

39

Suponiendo que no le importe retener ninguno de sus mensajes de confirmación existentes, hay una receta de git ingeniosa (y rápida) que puede usar. Primero, asegúrese de que su sucursal esté desprotegida:

git checkout <branch-to-squash> 

Por seguridad, permite etiquetar el compromiso actual.

git tag my-branch-backup 

A continuación, mover el cabezal de rama de vuelta a su última buena comprometerse (sin modificar el espacio de trabajo o índice):

git reset --soft <last-good-commit> 

Usando git status, se dará cuenta de que todos los cambios en su rama de la característica son ahora en escena Todo lo que queda por hacer es ...

git commit 

Este método es ideal para la consolidación, historias enrevesadas git largos y retorcidos fusiones. ¡Además, no hay conflictos de fusión/rebase para resolver!

Ahora, si necesita conservar alguno de sus mensajes de confirmación existentes o hacer algo más elegante que el anterior, querrá usar git rebase --interactive.

Solución derivados de: http://makandracards.com/makandra/527-squash-several-git-commits-into-a-single-commit

Referencia: http://git-scm.com/docs/git-reset

Referencia: http://git-scm.com/docs/git-rebase

+3

Esta es una gran respuesta. Tuvimos 310 commits para squash, aparentemente cada commit introdujo errores de rebase. Usar su enfoque fue rápido, indoloro y correcto. – tbm

+2

¿Qué es "el último compromiso bueno" en este contexto? –

+6

@MarceloMason Buena pregunta. Por favor, interprete "último compromiso correcto" como "el compromiso más reciente en su sucursal que desea conservar". Por ejemplo, si quiere aplastar el historial de su rama de temas hasta el punto en que diverge de la rama principal, la última confirmación correcta sería la 'combinación-base' del maestro y su rama de tema. Si tiene diez commits en su sucursal y solo desea consolidar los cinco primeros, la última confirmación sería 'HEAD ~ 5'. –

Cuestiones relacionadas