Para encontrar los archivos más grandes almacenados en el historial accesible de Git de un repositorio en macOS, abra Terminal, vaya al repositorio y canalice la lista de objetos de Git a través de git cat-file y sort. Esto muestra el tamaño sin comprimir en bytes de cada blob y una pista de la ruta. Puede revelar archivos que fueron eliminados o reemplazados pero que aún permanecen en commits accesibles desde ramas o etiquetas.

Ejecute un escaneo del historial desde Terminal

En Terminal, use cd para ingresar al repositorio. Ponga la ruta de la carpeta entre comillas si contiene espacios. Luego ejecute:

git rev-list --objects --all |
  git cat-file --batch-check='%(objecttype) %(objectsize) %(objectname) %(rest)' |
  awk '$1 == "blob"' |
  sort -k2,2nr |
  head -20

La salida se ordena de mayor a menor. Cada fila muestra el tipo de objeto, el recuento de bytes, el ID del objeto y, cuando Git proporciona una, una pista de la ruta. git rev-list --objects --all recorre los objetos a los que hacen referencia los commits accesibles desde referencias, como ramas locales y etiquetas; git cat-file --batch-check reporta el tipo y tamaño de cada objeto. La tubería filtra por blobs, los objetos que contienen el contenido de los archivos. La documentación de rev-list de Git describe el recorrido y los nombres de los objetos, y cat-file documenta la salida por lotes de tamaño y tipo.

sort -k2,2nr utiliza el comando sort integrado de macOS para ordenar numéricamente en orden inverso por el segundo campo separado por espacios en blanco, el tamaño en bytes. head -20 limita la visualización a 20 filas; cambie el número o elimine esa última línea para ver más. El comando solo lee datos del repositorio. No modifica commits ni archivos.

Interprete los resultados con cuidado

Una fila identifica un objeto blob, no necesariamente un archivo presente en el árbol de trabajo actual. Un objeto grande puede provenir de una versión antigua de un archivo, y una pista de ruta no es un índice histórico completo de rutas: Git documenta que con --objects, los nombres son pistas, pueden modificarse por saltos de línea, y cuando un objeto tiene múltiples nombres, es posible que solo se muestre uno. Trate la ruta indicada como una pista, y luego inspeccione los commits relevantes para confirmar cuándo y dónde apareció el contenido. Las notas sobre nombres de objetos de rev-list de Git explican estas limitaciones.

Este escaneo cubre los objetos accesibles desde referencias descubiertas mediante --all, no todos los objetos que puedan permanecer físicamente en la base de datos de objetos. Para verificar el almacenamiento local de objetos, incluidos los inalcanzables, ejecute:

git cat-file --batch-all-objects \
  --batch-check='%(objecttype) %(objectsize) %(objectname)' |
  awk '$1 == "blob"' |
  sort -k2,2nr |
  head -20

--batch-all-objects examina todos los objetos en el repositorio y en los almacenes de objetos alternativos, incluidos los objetos que no son accesibles desde referencias. Este segundo comando omite las rutas de los archivos, por lo que deberá utilizar el ID del objeto para investigar más a fondo. La documentación de cat-file destaca tanto la cobertura más amplia de objetos como el hecho de que cada objeto se muestra una sola vez, incluso si está almacenado varias veces.

El tamaño del blob no equivale al espacio en disco

El objectsize indicado es el tamaño sin comprimir de un objeto de Git. Git puede comprimir objetos o almacenarlos como deltas dentro de archivos pack, por lo que un blob grande no consume necesariamente esa cantidad exacta de disco. Para obtener una vista general del uso del almacenamiento, ejecute git count-objects -vH; su campo size-pack reporta el tamaño de los datos empaquetados y sus otros campos resumen los objetos sueltos y el almacenamiento relacionado. El manual de count-objects de Git documenta estas cifras. Para inspeccionar los tamaños de los objetos empaquetados y los detalles de los deltas, git verify-pack -v enumera el tamaño de cada objeto empaquetado y su tamaño dentro del archivo pack, pero requiere el archivo .idx correspondiente. El manual de verify-pack define dicha salida.

Si encuentra un archivo histórico de gran tamaño

Primero decida si su tarea consiste en entender el checkout actual o reducir el historial del repositorio. Para la versión actual únicamente, inspeccione los archivos en Finder o use un listado de tamaños de archivo en Terminal; el escaneo del historial responde a una pregunta diferente al buscar objetos de Git accesibles.

Si se debe eliminar un archivo grande de cada revisión, borrarlo en un nuevo commit por sí solo no eliminará las copias antiguas del historial. Reescribir el historial cambia los ID de los commits y afecta a otras personas que utilizan el repositorio, así que coordine antes de hacerlo y conserve una copia de seguridad. El proyecto git-filter-repo ofrece un modo de análisis de solo lectura, git filter-repo --analyze, que genera reportes para ayudar a decidir qué filtrar; no realiza la reescritura en el modo de análisis. La documentación del proyecto describe la opción de análisis y advierte que el filtrado reescribe el historial.

La primera tubería es el punto de partida práctico cuando el objetivo es encontrar el contenido de los archivos más grandes detrás del historial de un repositorio local. Utilice el escaneo de todos los objetos cuando los restos inalcanzables sean importantes, y compare los tamaños de los objetos de Git con el almacenamiento en packs antes de atribuir el uso de disco a un blob en particular.

Fuentes