regresar - Elimina los archivos confidenciales y sus confirmaciones del historial de Git.
git ver commits pendientes (10)
Aquí está mi solución en windows
git filter-branch --tree-filter "rm -f ''de archivo / nombre de archivo''" HEAD
git push - force
Asegúrate de que el camino sea correcto, de lo contrario no funcionará.
Espero que ayude
Me gustaría poner un proyecto Git en GitHub pero contiene ciertos archivos con datos confidenciales (nombres de usuario y contraseñas, como /config/deploy.rb para capistrano).
Sé que puedo agregar estos nombres de archivo a .gitignore , pero esto no eliminaría su historial dentro de Git.
Tampoco quiero volver a empezar eliminando el directorio /.git.
¿Hay alguna forma de eliminar todos los rastros de un archivo en particular en su historial de Git?
Cambiar sus contraseñas es una buena idea, pero para el proceso de eliminar las contraseñas del historial de su repo, recomiendo BFG Repo-Cleaner , una alternativa más rápida y sencilla a git-filter-branch
explícitamente diseñada para eliminar datos privados de los repositorios de Git.
Cree un archivo private.txt
con las contraseñas, etc., que desea eliminar (una entrada por línea) y luego ejecute este comando:
$ java -jar bfg.jar --replace-text private.txt my-repo.git
Se escanearán todos los archivos con un tamaño de umbral (1 MB por defecto) en el historial de su repositorio, y cualquier cadena que coincida (que no esté en su última confirmación) será reemplazada por la cadena "*** REMOVED ***". Luego puedes usar git gc
para limpiar los datos muertos:
$ git gc --prune=now --aggressive
El BFG suele ser 10-50 veces más rápido que ejecutar git-filter-branch
y las opciones se simplifican y se adaptan a estos dos casos de uso comunes:
- Eliminar archivos grandes locos
- Eliminar contraseñas, credenciales y otros datos privados
Revelación completa: soy el autor de BFG Repo-Cleaner.
Entonces, se ve algo como esto:
git rm --cached /config/deploy.rb
echo /config/deploy.rb >> .gitignore
Elimine la caché para el archivo rastreado de git y agregue ese archivo a la lista de
.gitignore
He tenido que hacer esto unas cuantas veces hasta la fecha. Tenga en cuenta que esto solo funciona en 1 archivo a la vez.
Obtenga una lista de todas las confirmaciones que modificaron un archivo. El que está abajo será el primero en cometer:
git log --pretty=oneline --branches -- pathToFile
Para eliminar el archivo del historial, use la primera confirmación sha1 y la ruta al archivo del comando anterior, y rellénelos en este comando:
git filter-branch --index-filter ''git rm --cached --ignore-unmatch <path-to-file>'' -- <sha1-where-the-file-was-first-added>..
Para ser claros: la respuesta aceptada es correcta. Pruébalo primero. Sin embargo, puede ser innecesariamente complejo para algunos casos de uso, especialmente si encuentra errores desagradables como ''fatal: revisión incorrecta --prune-vacío'', o si realmente no le importa el historial de su repositorio.
Una alternativa sería:
- cd a rama base del proyecto
- Eliminar el código / archivo sensible
- rm -rf .git / # Elimina toda la información de git de tu código
- Ve a github y borra tu repositorio.
- Siga esta guía para enviar su código a un nuevo repositorio como lo haría normalmente: https://help.github.com/articles/adding-an-existing-project-to-github-using-the-command-line/
Por supuesto, esto eliminará todas las ramas del historial de confirmaciones y los problemas tanto de su repositorio github como de su repositorio git local. Si esto es inaceptable, tendrá que utilizar un enfoque alternativo.
Llama a esto la opción nuclear.
Puedes usar git forget-blob
.
El uso es bastante simple git forget-blob file-to-forget
. Puedes obtener más información aquí
Desaparecerá de todas las confirmaciones en su historial, englobadas, etiquetas, etc.
Me encuentro con el mismo problema de vez en cuando, y cada vez que tengo que volver a esta publicación y otras, es por eso que automaticé el proceso.
Créditos a colaboradores de que me permitieron juntar esto
Recomiendo este guión de David Underhill, trabajado para mí como un encanto.
Agrega estos comandos además de la rama de filtro de natacado para limpiar el desorden que deja atrás:
rm -rf .git/refs/original/
git reflog expire --all
git gc --aggressive --prune
Guión completo (todo el crédito a David Underhill)
#!/bin/bash
set -o errexit
# Author: David Underhill
# Script to permanently delete files/folders from your git repository. To use
# it, cd to your repository''s root and then run the script with a list of paths
# you want to delete, e.g., git-delete-history path1 path2
if [ $# -eq 0 ]; then
exit 0
fi
# make sure we''re at the root of git repo
if [ ! -d .git ]; then
echo "Error: must run this script from the root of a git repository"
exit 1
fi
# remove all paths passed as arguments from the history of the repo
files=$@
git filter-branch --index-filter /
"git rm -rf --cached --ignore-unmatch $files" HEAD
# remove the temporary history git-filter-branch
# otherwise leaves behind for a long time
rm -rf .git/refs/original/ && /
git reflog expire --all && /
git gc --aggressive --prune
Los dos últimos comandos pueden funcionar mejor si se cambian a lo siguiente:
git reflog expire --expire=now --all && /
git gc --aggressive --prune=now
Utilice filtro-rama :
git filter-branch --force --index-filter ''git rm --cached --ignore-unmatch *file_path_relative_to_git_repo*'' --prune-empty --tag-name-filter cat -- --all
git push origin *branch_name* -f
Si ya presionó a GitHub, los datos se verán comprometidos incluso si los presiona un segundo más tarde porque:
GitHub mantiene comprometidos colgando durante mucho tiempo.
Sin embargo, el personal de GitHub tiene el poder de eliminar tales compromisos colgantes si los contactas, que es lo que debes hacer: ¿Cómo eliminar un compromiso colgante de GitHub?
Los compromisos colgantes se pueden ver a través de:
- la interfaz de usuario web de confirmación: https://github.com/cirosantilli/test-dangling/commit/53df36c09f092bbb59f2faa34eba15cd89ef8e83 ( máquina Wayback )
- la API: https://api.github.com/repos/cirosantilli/test-dangling/commits/53df36c09f092bbb59f2faa34eba15cd89ef8e83 ( máquina Wayback )
Una forma conveniente de obtener el código fuente de ese compromiso es utilizar el método de descarga zip, que puede aceptar cualquier referencia, por ejemplo: https://github.com/cirosantilli/myrepo/archive/SHA.zip
Es posible obtener los SHA que faltan, ya sea por:
- listado de eventos API con el
type": "PushEvent"
. Por ejemplo, mina: https://api.github.com/users/cirosantilli/events/public ( máquina Wayback ) - más convenientemente a veces, mirando las SHA de las solicitudes de extracción que intentaron eliminar el contenido
- listado de eventos API con el
Hay scrappers como http://ghtorrent.org/ y https://www.githubarchive.org/ que https://www.githubarchive.org/ regularmente los datos de GitHub y los almacenan en otro lugar.
No pude encontrar si raspan la diferencia de compromiso real, pero es técnicamente posible.
Para probar esto, he creado un repositorio: https://github.com/cirosantilli/test-dangling y listo:
git init
git remote add origin [email protected]:cirosantilli/test-dangling.git
touch a
git add .
git commit -m 0
git push
touch b
git add .
git commit -m 1
git push
touch c
git rm b
git add .
git commit --amend --no-edit
git push -f
Sin embargo, si elimina el repositorio , los compromisos desaparecen incluso de la API de inmediato y se asigna 404, por ejemplo, https://api.github.com/repos/cirosantilli/test-dangling-delete/commits/8c08448b5fbf0f891696819f3b2b2d653f7a3824 Esto funciona incluso si usted recrea otra. repositorio con el mismo nombre.
Así que mi curso de acción recomendado es:
cambia tus credenciales
Si eso no es suficiente (por ejemplo, fotos desnudas):
- borrar el repositorio
- soporte de contacto
Para todos los propósitos prácticos, lo primero que debe preocuparle es ¡ CAMBIAR SUS CONTRASEÑAS! De su pregunta no queda claro si su repositorio git es completamente local o si todavía tiene un repositorio remoto en otra parte; Si es remoto y no está protegido de otros, tiene un problema. Si alguien ha clonado ese repositorio antes de que arregle esto, tendrán una copia de sus contraseñas en su máquina local, y no hay forma de forzarlas a que actualicen su versión "fija" sin que haya pasado el historial. Lo único seguro que puede hacer es cambiar su contraseña a otra parte donde la haya usado.
Con eso fuera del camino, aquí está cómo arreglarlo. GitHub respondió exactamente esa pregunta como una pregunta frecuente :
Nota para los usuarios de Windows : use comillas dobles (") en lugar de sencillos en este comando
git filter-branch --index-filter /
''git update-index --remove filename'' <introduction-revision-sha1>..HEAD
git push --force --verbose --dry-run
git push --force
Tenga en cuenta que una vez que haya insertado este código en un repositorio remoto como GitHub y otros que hayan clonado ese repositorio remoto, ahora se encuentra en una situación en la que está reescribiendo el historial. Cuando otros intenten desplegar sus últimos cambios después de esto, recibirán un mensaje que indica que los cambios no se pueden aplicar porque no es un avance rápido.
Para solucionar esto, tendrán que eliminar su repositorio existente y volver a clonarlo, o seguir las instrucciones en "RECUPERACIÓN DE LA REBASE DE UPSTREAM" en la página de manual de git-rebase .
En el futuro, si confirma algunos cambios con información confidencial, pero se da cuenta de que antes de ingresar a un repositorio remoto, existen algunas soluciones más sencillas. Si la última confirmación es la que agrega la información confidencial, simplemente puede eliminar la información confidencial y luego ejecutar:
git commit -a --amend
Eso modificará la confirmación previa con cualquier cambio nuevo que haya realizado, incluida la eliminación completa de archivos con un git rm
. Si los cambios están más atrás en el historial pero aún no se han enviado a un repositorio remoto, puede hacer una rebase interactiva:
git rebase -i origin/master
Eso abre un editor con las confirmaciones que ha realizado desde su último antepasado común con el repositorio remoto. Cambie "pick" a "edit" en cualquier línea que represente una confirmación con información confidencial, y guarde y salga. Git recorrerá los cambios y te dejará en un lugar donde puedes:
$EDITOR file-to-fix
git commit -a --amend
git rebase --continue
Para cada cambio con información sensible. Finalmente, terminará de regreso en su sucursal y podrá impulsar los nuevos cambios de manera segura.