He estado experimentando con el uso de git subtree y me he encontrado con la siguiente situación.
Utilicé git subtree para agregar un proyecto externo a mi repositorio, guardé intencionalmente todo el historial del proyecto ascendente, ya que quiero poder referirme al historial del proyecto y también contribuir al proyecto ascendente más adelante.
Como resultado, otro contribuyente al proyecto ascendente introdujo accidentalmente un archivo grande en la rama maestra. Para solucionar esto, el proyecto aguas arriba reescribió la historia y la fuerza empujada al maestro. Al crear mi "monorepo", incluí este commit y también me gustaría eliminarlo.
¿Cómo puedo actualizar mi repositorio para reflejar el nuevo historial del subárbol?
Mi primer intento fue usar filter-branch para eliminar completamente el subárbol y todo el historial.
git filter-branch --index-filter 'git rm -rf --cached --ignore-unmatch upstream-project-dir' --prune-empty HEAD
Una vez que se eliminó la versión anterior del subárbol, pude volver a agregar el subárbol usando el nuevo maestro ascendente. Sin embargo, esto no funcionó porque, por alguna razón, el historial de confirmación aún se muestra en la salida del registro git.
Actualizar
He escrito los pasos para crear un ejemplo mínimamente reproducible.
Primero crea un repositorio git vacío.
git init test-monorepo cd ./test-monorepo
Crea una confirmación inicial.
echo hello world > README git add README git commit -m 'initial commit'
Ahora agregue un subárbol para un proyecto externo.
git remote add thirdparty [email protected]:teivah/algodeck.git git fetch thirdparty git subtree add --prefix algodeck thirdparty master
Haz algunos compromisos en el monorepo
echo dont panic >> algodeck/README.md git commit -a -m 'test commit'
Ahora intente usar git filter-branch para eliminar el subárbol.
git filter-branch --index-filter 'git rm -rf --cached --ignore-unmatch algodeck' --prune-empty HEAD
Examine la salida del registro de git, espero ver solo mi confirmación inicial.
git log
git gc --prune=now
solo eliminaría las confirmaciones que no aparecengit log
?git log
, sin argumentos y todavía veo los viejos commits.Respuestas:
ya tiene el mal compromiso en su historial y necesita deshacerse de él antes de continuar
supongamos que se
master
desvió la última confirmación y no he podido hacer nada más (realmente no tengo sus ramas a la vista, así que necesito asumir algo para comenzar)puede pasar por el commit anterior y empujar su marcador de rama 1 paso hacia atrás (o X pasos hacia atrás), lo que sería inofensivo en cualquier caso y luego volver a tirar
p.ej
git checkout master~1
para verificar el compromiso principal del maestro, git advierte que estamos fuera de las sucursalesgit branch master -f
para forzar que la comprobación actual vuelva a ser maestra, es decir, en realidad rebobina la rama maestra a su compromiso anterior (o X compromiso anterior), y desde aquí, no importa si el flujo ascendente hizo una fuerza o no, podemos reanudar normalmente, o incluso Si es necesario, regrese al paso anterior, solo podemos extraer el master nuevamente, sin perder nada del flujo ascendente (que para nosotros también podría ser de solo lectura, no empujaremos nada para esto)git checkout master
para estar en nuestra rama maestra "rebobinada", el mismo compromiso al que nos dirigimos, pero ahora estamos en la ramagit pull
para extraer el master nuevamente (puede ser con o sin--prune
), si se desvía aguas arriba, volveremos a la pista desde aquí, si no, obtendremos lo mismo que teníamos, si obtuvimos lo mismo y no se suponía, tal vez necesita volver al primer paso anterior y rebobinar más confirmaciones, por ejemplo,git checkout master~5
o lo que sea (según sea necesario)fuente
git subtree
en su repositorio, limpie el historial de confirmaciones para este control remoto:
Si uno de sus propios commits tiene un commit que incluye el archivo grande, reescriba su historial para que este archivo grande ya no sea referenciado
Con estos dos pasos, el archivo grande ya no será referenciado por ningún commit en su repositorio.
Además, se eliminará de su disco duro en algún momento, cuando git ejecuta su recolector de basura y se han alcanzado los retrasos de caducidad de las gotas colgantes.
Si tiene una necesidad urgente de eliminar este archivo grande lo antes posible de su disco duro:
Ejecutar manualmente
fuente