¿Cómo aplastas todo tu repositorio hasta la primera confirmación?
Puedo cambiar la base a la primera confirmación, pero eso me dejaría con 2 confirmaciones. ¿Hay alguna manera de hacer referencia al commit antes del primero?
git
rebase
git-rebase
squash
git-rewrite-history
Verhogen
fuente
fuente
--root
realidad no es la mejor solución para aplastar todos los commits si hay muchos de ellos para aplastar): ¿ Combinar los dos primeros commits de un repositorio Git? .Respuestas:
Quizás la forma más fácil es crear un nuevo repositorio con el estado actual de la copia de trabajo. Si desea conservar todos los mensajes de confirmación que puede hacer primero
git log > original.log
y luego editarlos para su mensaje de confirmación inicial en el nuevo repositorio:o
fuente
git rebase -i --root
. Ver: stackoverflow.com/a/9254257/109618A partir de git 1.6.2 , puedes usar
git rebase --root -i
.Para cada confirmación, excepto la primera, cambie
pick
asquash
.fuente
squash
para todos los commits. El primero tiene que serpick
.Actualizar
He hecho un alias
git squash-all
.Ejemplo de uso :
git squash-all "a brand new start"
.Advertencia : recuerde proporcionar un comentario; de lo contrario, se usará el mensaje de confirmación predeterminado "Un nuevo comienzo".
O puede crear el alias con el siguiente comando:
Un trazador de líneas
Nota : aquí "
A new start
" es solo un ejemplo, siéntase libre de usar su propio idioma.TL; DR
No es necesario aplastar, usar
git commit-tree
para crear una confirmación huérfana e ir con ella.Explique
crear una única confirmación a través de
git commit-tree
Lo que
git commit-tree HEAD^{tree} -m "A new start"
hace es:La expresión
HEAD^{tree}
significa el objeto del árbol correspondienteHEAD
, es decir, la punta de su rama actual. ver Tree-Objects y Commit-Objects .restablecer la rama actual a la nueva confirmación
Luego,
git reset
simplemente restablezca la rama actual al objeto de confirmación recién creado.De esta manera, no se toca nada en el espacio de trabajo, ni hay necesidad de rebase / squash, lo que lo hace realmente rápido. Y el tiempo necesario es irrelevante para el tamaño del repositorio o la profundidad del historial.
Variación: Nuevo repositorio de una plantilla de proyecto
Esto es útil para crear el "commit inicial" en un nuevo proyecto usando otro repositorio como template / archetype / seed / skeleton. Por ejemplo:
Esto evita agregar el repositorio de plantillas como un control remoto (
origin
o de otro modo) y contrae el historial del repositorio de plantillas en su confirmación inicial.fuente
git push -f
para propagación.git clone
. Si se agrega--hard
agit reset
e interruptorHEAD
conFETCH_HEAD
elgit commit-tree
que puede crear una inicial confirmación después de ir a buscar el repositorio de plantillas. He editado la respuesta con una sección al final que demuestra esto.${1?Please enter a message}
Si todo lo que quiere hacer es aplastar todas sus confirmaciones hasta la confirmación raíz, entonces mientras
puede funcionar, no es práctico para una gran cantidad de confirmaciones (por ejemplo, cientos de confirmaciones), porque la operación de rebase probablemente se ejecutará muy lentamente para generar la lista interactiva de confirmaciones del editor de rebase, así como ejecutar la rebase en sí.
Aquí hay dos soluciones más rápidas y más eficientes cuando está aplastando una gran cantidad de confirmaciones:
Solución alternativa # 1: ramas huérfanas
Simplemente puede crear una nueva rama huérfana en la punta (es decir, la confirmación más reciente) de su rama actual. Esta rama huérfana forma la confirmación raíz inicial de un árbol de historial de confirmación completamente nuevo y separado, que es efectivamente equivalente a aplastar todas sus confirmaciones:
Documentación:
Solución alternativa # 2: restablecimiento parcial
Otra solución eficiente es simplemente usar un reinicio mixto o suave en la confirmación raíz
<root>
:Documentación:
fuente
git push origin master --force
.git push --force
Esto creará una confirmación huérfana con el árbol de HEAD y generará su nombre (SHA-1) en stdout. Luego simplemente reinicie su rama allí.
fuente
git reset $(git commit-tree HEAD^{tree} -m "commit message")
Lo haría más fácil.echo "message" | git commit-tree "HEAD^{tree}"
Así es como terminé haciendo esto, en caso de que funcione para otra persona:
Recuerde que siempre existe el riesgo de hacer cosas como esta, y nunca es una mala idea crear una rama de salvar antes de comenzar.
Comience por iniciar sesión
Desplácese hasta la primera confirmación, copie SHA
Reemplace
<#sha#>
con el SHA copiado del registroAsegúrese de que todo esté verde, de lo contrario, ejecute
git add -A
Modifique todos los cambios actuales a la primera confirmación actual
Ahora forzar a empujar esta rama y sobrescribirá lo que hay allí.
fuente
Leí algo sobre el uso de injertos pero nunca lo investigé mucho.
De todos modos, puedes aplastar esos 2 últimos commits manualmente con algo como esto:
fuente
La forma más fácil es usar el comando 'plomería'
update-ref
para eliminar la rama actual.No puede usarlo
git branch -D
ya que tiene una válvula de seguridad para evitar que elimine la rama actual.Esto lo devuelve al estado de 'confirmación inicial' donde puede comenzar con una nueva confirmación inicial.
fuente
Primero, aplasta todos tus commits en un solo commit usando
git rebase --interactive
. Ahora te quedan dos commits para aplastar. Para hacerlo, lea cualquiera defuente
En una línea de 6 palabras
fuente
git help checkout
sobre--orphan
git help checkout --orphan
crear una copia de seguridad
restablecer a commit especificado
luego agregue todos los archivos a la puesta en escena
confirmar sin actualizar el mensaje
empujar una nueva rama con compromisos aplastados para repo
fuente
<root>
commit # 1 será el commit al que restablecerá nuevamente.git commit --amend --no-edit
confirmará todos los cambios en la confirmación actual<root>
sin necesidad de editar el mensaje de confirmación.Para aplastar usando injertos
Agregue un archivo
.git/info/grafts
, coloque allí el hash de confirmación que desea convertir en su raízgit log
ahora comenzará desde ese commitPara hacerlo correr 'real'
git filter-branch
fuente
Esta respuesta mejora en un par de arriba (por favor, vótelos), suponiendo que, además de crear una confirmación (sin padres, sin historial), también desea conservar todos los datos de confirmación de esa confirmación:
Por supuesto, el commit-SHA del commit nuevo / único cambiará, porque representa un nuevo (no) historial, convirtiéndose en un commit sin padre / root.
Esto se puede hacer leyendo
git log
y configurando algunas variables paragit commit-tree
. Suponiendo que desea crear una única confirmación desdemaster
una nueva ramaone-commit
, conservando los datos de confirmación anteriores:fuente
Para hacer esto, puede restablecer su repositorio git local al primer hashtag de confirmación, para que todos sus cambios después de esa confirmación no se realicen, y luego puede confirmar con la opción --amend.
Y luego edite el primer commit nam si es necesario y guarde el archivo.
fuente
Para mí funcionó así: tenía 4 commits en total, y usé rebase interactivo:
El primer commit permanece y tomé los 3 últimos commits.
En caso de que esté atascado en el editor que aparece a continuación, verá algo como:
Tienes que tomar el primer compromiso y aplastar a los demás. Lo que debes tener es:
Para eso use la tecla INSERT para cambiar el modo 'insertar' y 'editar'.
Para guardar y salir del editor use
:wq
. Si su cursor está entre esas líneas de confirmación o en otro lugar, presione ESC e intente nuevamente.Como resultado, tuve dos commits: el primero que permaneció y el segundo con el mensaje "Esta es una combinación de 3 commits".
Verifique los detalles aquí: https://makandracards.com/makandra/527-squash-several-git-commits-into-a-single-commit
fuente
Usualmente lo hago así:
Asegúrese de que todo esté confirmado y escriba la última ID de confirmación en caso de que algo salga mal, o cree una rama separada como copia de seguridad
Ejecute
git reset --soft `git rev-list --max-parents=0 --abbrev-commit HEAD`
para restablecer su cabeza a la primera confirmación, pero deje su índice sin cambios. Todos los cambios desde la primera confirmación ahora aparecerán listos para ser confirmados.Ejecute
git commit --amend -m "initial commit"
para modificar su confirmación en la primera confirmación y cambie el mensaje de confirmación, o si desea conservar el mensaje de confirmación existente, puede ejecutargit commit --amend --no-edit
Corre
git push -f
para forzar tus cambiosfuente