ultimo soft sirve repositorio remoto qué para modificar eliminar ejemplo borrar archivo git git-filter-branch

git - soft - modificar ultimo commit



¿Cómo elimino el historial anterior de un repositorio git? (10)

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 commits. Quisiéramos eliminar todo el historial antes del 1 de enero de 2010, para hacerlo más pequeño y más fácil de tratar (mantendríamos una copia completa del historial en un repositorio de archivos).

Sé que el compromiso que deseo tener se convirtió en la raíz del nuevo repositorio. No puedo, sin embargo, descubrir el git mojo correcto para truncar el repositorio para comenzar con ese commit. Supongo que alguna variante de

git filter-branch

involucrar injertos sería necesario; también podría ser necesario tratar cada una de las más de 200 sucursales que queremos mantener por separado y luego volver a unir el repositorio (algo que sé hacer).

¿Alguien ha hecho algo como esto? Tengo git 1.7.2.3 si eso importa.


  1. eliminar datos de git, rm .git
  2. git init
  3. agregar un control remoto git
  4. fuerza empujar

Como alternativa a la reescritura de la historia, considere usar git replace como en este artículo del libro de 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.


Cuando se rebase o empuje a la cabeza / maestro, este error puede ocurrir

remote: GitLab: You are not allowed to access some of the refs! To git@giturl:main/xyz.git ! [remote rejected] master -> master (pre-receive hook declined) error: failed to push some refs to ''git@giturl:main/xyz.git''

Para resolver este problema, en el panel de git, se debe eliminar la rama principal de "Ramas protegidas"

entonces puedes ejecutar este comando

git push -f origin master

o

git rebase --onto temp $1 master


Este method es fácil de entender y funciona bien. El argumento para el guión ( $1 ) es una referencia (etiqueta, hash, ...) al compromiso a partir del cual desea conservar su historial.

#!/bin/bash git checkout --orphan temp $1 # create a new branch without parent history git commit -m "Truncated history" # create a first commit on this branch git rebase --onto temp $1 master # now rebase the part of master branch that we want to keep onto this branch git branch -D temp # delete the temp branch # The following 2 commands are optional - they keep your git repo in good shape. git prune --progress # delete all the objects w/o references git gc --aggressive # aggressively collect garbage; may take a lot of time on large repos

TEN 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 informaciones 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!


Necesitaba leer varias respuestas y otra información para entender lo que estaba haciendo.

1. Ignorar todo lo anterior a un cierto compromiso

El archivo .git/info/grafts puede definir padres falsos para una confirmación. Una línea con solo una identificación de confirmación, dice que la confirmación no tiene un padre. Si quisiéramos decir que solo nos importan las últimas 2000 confirmaciones, podemos escribir:

git rev-parse HEAD~2000 > .git/info/grafts

git rev-parse nos da el id. de confirmación del padre 2000 del compromiso actual. El comando anterior sobrescribirá el archivo de injertos si está presente. Compruebe si está allí primero.

2. Reescribe el historial de Git (opcional)

Si desea que este falso padre injertado sea real, ejecute:

git filter-branch -- --all

Cambiará todos los identificadores de commit. Cada copia de este repositorio necesita ser actualizada con fuerza.

3. Limpiar el espacio del disco

No hice el paso 3. Quería que mi copia fuera compatible con la versión anterior. Solo quería ahorrar espacio en el disco. Para olvidar todos los viejos commits:

git prune git gc

Alternativa: copias superficiales

Si tiene una copia superficial de otro repositorio y solo desea guardar algo de espacio en disco, puede actualizar .git/shallow . Pero tenga cuidado de que nada esté apuntando a un compromiso de antes. Entonces podrías ejecutar algo como esto:

git fetch --prune git rev-parse HEAD~2000 > .git/shallow git prune git gc

La entrada en aguas poco profundas funciona como un injerto. Pero tenga cuidado de no usar injertos y poca profundidad al mismo tiempo. Al menos, no tienen las mismas entradas, fallarán.

Si todavía tiene algunas referencias antiguas (etiquetas, ramas, encabezados remotos) que apuntan a confirmaciones más antiguas, no se limpiarán y no ahorrará más espacio en el disco.


Prueba este método Cómo truncar el historial de git :

#!/bin/bash git checkout --orphan temp $1 git commit -m "Truncated history" git rebase --onto temp $1 master git branch -D temp

Aquí $1 es SHA-1 de la confirmación que desea conservar y la secuencia de comandos creará una nueva rama que contenga todas las confirmaciones entre $1 y el master y se descartará todo el historial anterior. Tenga en cuenta que este script simple asume que no tiene una bifurcación existente llamada temp . También tenga en cuenta que este script no borra los datos de git para el historial anterior. Ejecute git gc --prune=all && git repack -a -f -F -d después de que haya verificado que realmente desea 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 función no es perfecta. Inspeccione los resultados manualmente si los usa.


Quizás sea demasiado tarde para publicar una respuesta, pero como esta es el primer resultado de Google, puede ser útil.

Si quieres liberar algo de espacio en tu git repo, pero no quieres reconstruir todas tus confirmaciones (rebase o injerto), y aún así poder presionar / jalar / fusionar de las personas que tienen el repositorio completo, puedes usar el git Clon superficial clon ( --depth parámetro).

; Clone the original repo into limitedRepo git clone file:///path_to/originalRepo limitedRepo --depth=10 ; Remove the original repo, to free up some space rm -rf originalRepo cd limitedRepo git remote rm origin

Es posible que pueda actualizar su repositorio existente siguiendo estos pasos:

; Shallow to last 5 commits git rev-parse HEAD~5 > .git/shallow ; Manually remove all other branches, tags and remotes that refers to old commits ; Prune unreachable objects git fsck --unreachable ; Will show you the list of what will be deleted git gc --prune=now ; Will actually delete your data

Ps: Las versiones anteriores de git no soportaban clones / push / pull desde / a repos superficiales.


Si desea mantener el repositorio en sentido ascendente con el historial completo , pero las cajas más pequeñas locales, haga una copia superficial con git clone --depth=1 [repo] .

Después de presionar un commit, puedes hacer

  1. git fetch --depth=1 para podar los commits antiguos. Esto hace que los viejos commits y sus objetos sean inalcanzables.
  2. git reflog expire --expire-unreachable=now --all . Para caducar todos los commits antiguos y sus objetos
  3. git gc --aggressive --prune=all para eliminar los objetos viejos

Consulte también ¿Cómo eliminar el historial de git local después de una confirmación? .

Tenga en cuenta que no puede enviar este repositorio "poco profundo" 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.


Simplemente cree un graft del padre de su nueva confirmación raíz a ningún padre (o a una confirmación vacía, por ejemplo, la confirmación raíz real de su repositorio). Por ejemplo, echo "<NEW-ROOT-SHA1>" > .git/info/grafts

Después de crear el injerto, tiene efecto de inmediato; deberías poder mirar el git log y ver que los commits antiguos no deseados se hayan ido:

$ echo 4a46bc886318679d8b15e05aea40b83ff6c3bd47 > .git/info/grafts $ git log --decorate | tail --lines=11 commit cb3da2d4d8c3378919844b29e815bfd5fdc0210c Author: Your Name <[email protected]> Date: Fri May 24 14:04:10 2013 +0200 Another message commit 4a46bc886318679d8b15e05aea40b83ff6c3bd47 (grafted) Author: Your Name <[email protected]> Date: Thu May 23 22:27:48 2013 +0200 Some message

Si todo parece como se pretende, puedes hacer una simple git filter-branch -- --all para que sea permanente.

CUIDADO: después de hacer el paso de filtrar rama , todos los identificadores de compilación habrán cambiado, por lo que cualquiera que use el repo antiguo nunca debe fusionarse con nadie que use el repositorio nuevo.


puede eliminar el directorio, los archivos y también todo el historial relacionado con el directorio o archivo utilizando el jar [download it] y los comandos que se mencionan 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-folders nombre_carpeta git reflog expire --expire = ahora --todo y& git gc --prune = ahora --aggressive git push --mirror repo_url