Me temo que no pude encontrar nada como este escenario en particular.
Tengo un repositorio git con mucha historia: más de 500 sucursales, más de 500 etiquetas, desde mediados de 2007. Contiene ~ 19,500 confirmaciones. Nos gustaría eliminar todo el historial antes del 1 de enero de 2010, para que sea más pequeño y más fácil de manejar (mantendríamos una copia completa del historial en un repositorio de archivos).
Conozco el commit que quiero que se haya convertido en la raíz del nuevo repositorio. Sin embargo, no puedo encontrar el git mojo correcto para truncar el repositorio para comenzar con ese commit. Estoy adivinando alguna variante de
git filter-branch
implicaría injertos sería necesario; También podría ser necesario tratar cada una de las más de 200 ramas que queremos mantener por separado y luego volver a unir el repositorio (algo que sí sé hacer).
¿Alguien ha hecho algo como esto? Tengo git 1.7.2.3 si eso importa.
fuente
git filter-branch --tag-name-filter cat -- --all
para actualizar las etiquetas. Pero también tengo etiquetas más antiguas que apuntan al historial antiguo que quiero eliminar. ¿Cómo puedo deshacerme de todas esas etiquetas viejas? Si no los elimino, el historial anterior no desaparece y aún puedo verlogitk --all
.echo "<NEW-ROOT-HASH>" > .git/info/grafts
Tal vez sea demasiado tarde para publicar una respuesta, pero como esta página es el primer resultado de Google, aún puede ser útil.
Si desea liberar algo de espacio en su repositorio de git, pero no desea reconstruir todos sus commits (rebase o injerto), y aún así puede empujar / tirar / fusionarse de las personas que tienen el repositorio completo, puede usar el git clone clon superficial ( - parámetro de profundidad ).
Es posible que pueda reducir su repositorio existente siguiendo estos pasos:
¿Cómo eliminar todas las etiquetas locales de git?
Ps: las versiones anteriores de git no admitían clonar / empujar / tirar de / a repositorios poco profundos.
fuente
cd
a una carpeta que acaba de ser eliminada? Siento que falta información aquí. Además, ¿hay alguna forma de aplicar estos cambios al repositorio remoto?git clone file:///Users/me/Projects/myProject myClonedProject --shallow-since=2016-09-02
Funciona como un encanto!git filter-branch -- --all
. Esto cambiará todos los hashes, pero después de eso podrás llevarlo a un nuevo repositorioEste método es fácil de entender y funciona bien. El argumento de la secuencia de comandos (
$1
) es una referencia (etiqueta, hash, ...) a la confirmación a partir de la cual desea mantener su historial.Tenga en cuenta que las etiquetas antiguas seguirán presentes; por lo que es posible que deba eliminarlos manualmente
Observación: Sé que esto es casi lo mismo que @yoyodin, pero aquí hay algunos comandos e información adicionales importantes. Traté de editar la respuesta, pero como es un cambio sustancial a la respuesta de @yoyodin, mi edición fue rechazada, ¡así que aquí está la información!
fuente
git prune
ygit gc
. ¿Hay alguna explicación para el resto de los comandos en el script? Tal como está, no está claro qué argumentos se le están pasando y qué está haciendo cada comando. Gracias.-p
alrebase
comando, como se sugiere en otra respuestaPruebe este método Cómo truncar el historial de git :
Aquí
$1
es SHA-1 de la confirmación desea mantener y el script creará nueva rama que contiene todos los envíos entre$1
ymaster
y toda la historia más antigua se descarta. Tenga en cuenta que este script simple asume que no tiene una rama existente llamadatemp
. También tenga en cuenta que este script no borra los datos de git para el historial antiguo. Corregit gc --prune=all && git repack -a -f -F -d
después de que hayas verificado que realmente quieres perder todo el historial. Es posible que también necesite,rebase --preserve-merges
pero tenga en cuenta que la implementación de git de esa característica no es perfecta. Inspeccione los resultados manualmente si lo usa.fuente
rebase
paso. Extraño: no esperaba que los conflictos de fusión pudieran ser posibles en estas circunstancias.git commit --allow-empty -m "Truncate history"
si la confirmación que desprotegió no contiene ningún archivo.Como alternativa a la reescritura del historial, considere usar
git replace
como en este artículo del libro Pro Git . El ejemplo discutido implica reemplazar un compromiso principal para simular el comienzo de un árbol, mientras se mantiene el historial completo como una rama separada para su custodia.fuente
git replace
. Creo que esto se corrigió en otra pregunta donde publicaste esta respuesta.git replace
versusgit graft
en stackoverflow.com/q/6800692/873282Si desea mantener el repositorio ascendente con un historial completo , pero con pagos locales más pequeños, haga un clon superficial con
git clone --depth=1 [repo]
.Después de presionar un commit, puedes hacer
git fetch --depth=1
para podar los viejos commits. Esto hace que los viejos commits y sus objetos sean inalcanzables.git reflog expire --expire-unreachable=now --all
. Para caducar todos los commits antiguos y sus objetosgit gc --aggressive --prune=all
para eliminar los objetos viejosConsulte también ¿Cómo eliminar el historial local de git después de una confirmación?.
Tenga en cuenta que no puede empujar este repositorio "superficial" a otro lugar: "actualización superficial no permitida". Consulte Remoto rechazado (actualización superficial no permitida) después de cambiar la URL remota de Git . Si quieres hacerlo, debes seguir con el injerto.
fuente
Necesitaba leer varias respuestas y otra información para entender lo que estaba haciendo.
1. Ignora todo lo anterior que cierta confirmación
El archivo
.git/info/grafts
puede definir padres falsos para un commit. Una línea con solo una identificación de confirmación dice que la confirmación no tiene un elemento primario. Si quisiéramos decir que solo nos importan los últimos 2000 commits, podemos escribir:git rev-parse nos da la identificación del commit del padre número 2000 del commit actual. El comando anterior sobrescribirá el archivo de injertos si está presente. Comprueba si está allí primero.
2. Reescribe el historial de Git (opcional)
Si desea hacer que este padre falso injertado sea real, ejecute:
Cambiará todos los ID de confirmación. Cada copia de este repositorio debe actualizarse con fuerza.
3. Limpie el espacio en disco
No hice el paso 2, porque quería que mi copia siguiera siendo compatible con el flujo ascendente. Solo quería ahorrar algo de espacio en disco. Para olvidar todas las confirmaciones anteriores:
Alternativa: copias poco profundas
Si tiene una copia superficial de otro repositorio y solo quiere ahorrar algo de espacio en disco, puede actualizar
.git/shallow
. Pero tenga cuidado de que nada apunta a una confirmación de antes. Entonces podrías ejecutar algo como esto:La entrada en poca profundidad funciona como un injerto. Pero tenga cuidado de no usar injertos y poco profundos al mismo tiempo. Al menos, no tiene las mismas entradas allí, fallará.
Si todavía tiene algunas referencias antiguas (etiquetas, ramas, cabezales remotos) que apuntan a confirmaciones anteriores, no se limpiarán y no ahorrará más espacio en disco.
fuente
git replace
lugar. Ver stackoverflow.com/questions/6800692/…Cuando se cambia la base o se empuja al encabezado / maestro, puede ocurrir este error
Para resolver este problema en el panel de git, debe eliminar la rama maestra de "Ramas protegidas"
entonces puedes ejecutar este comando
o
fuente
Aquí hay demasiadas respuestas que no son actuales y algunas no explican completamente las consecuencias. Esto es lo que funcionó para mí para recortar el historial usando el último git 2.26:
Primero crea una confirmación ficticia. Esta confirmación aparecerá como la primera confirmación en su repositorio truncado. Necesita esto porque esta confirmación mantendrá todos los archivos base para el historial que está manteniendo. El SHA es el ID de la confirmación anterior de la confirmación que desea mantener (en este ejemplo,
8365366
). La cadena 'Inicial' aparecerá como mensaje de confirmación de la primera confirmación. Si está utilizando Windows, escriba el siguiente comando desde el símbolo del sistema de Git Bash.El comando anterior imprimirá SHA, por ejemplo,
d10f7503bc1ec9d367da15b540887730db862023
.Ahora solo escribe:
Esto primero colocará todos los archivos como confirmación
8365366
en la confirmación ficticiad10f750
. Luego reproducirá todas las confirmaciones después de 8365366 sobre la parte superiord10f750
. Finalmentemaster
, el puntero de rama se actualizará a la última confirmación reproducida.Ahora, si desea impulsar estos repositorios truncados, simplemente haga
git push -f
.Algunas cosas a tener en cuenta (esto se aplica tanto a otros métodos como a este): las etiquetas no se transfieren. Mientras se conservan las ID de confirmación y las marcas de tiempo, verá que GitHub muestra estas confirmaciones en un encabezado como
Commits on XY date
.Afortunadamente, es posible mantener el historial truncado como "archivo" y luego puede volver a unir el repositorio recortado con el repositorio de archivo. Para hacer esto, vea esta guía .
fuente
puede eliminar el directorio, los archivos y también todo el historial relacionado con el directorio o el archivo usando el jar [descargarlo] y los comandos mencionados a continuación
Archivo bfg.jar: https://rtyley.github.io/bfg-repo-cleaner/
git clone --bare repo-url cd repo_dir java -jar bfg.jar --delete-folder folder_name git reflog expire --expire = now --all && git gc --prune = now --aggressive git push --mirror repo_url
fuente
fuente