Eliminar archivos confidenciales y sus confirmaciones del historial de Git
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 borrando el /.directorio git.
¿Hay alguna forma de eliminar todos los rastros de un archivo en particular en tu historial de Git?
10 answers
Para todos los propósitos prácticos, el primero lo que debería preocuparle es CAMBIAR SUS CONTRASEÑAS! No está claro a partir de su pregunta si su repositorio git es completamente local o si ya tiene un repositorio remoto en otro lugar; si es remoto y no está protegido de otros, tiene un problema. Si alguien ha clonado ese repositorio antes de que arregles esto, tendrán una copia de tus contraseñas en su máquina local, y no hay manera de que puedas forzarlos a actualizar a su versión" fija " con él ido de la historia. La única cosa segura que puede hacer es cambiar su contraseña a otra cosa donde quiera que la haya usado.
Con eso fuera del camino, aquí está cómo arreglarlo. GitHub respondió exactamente esa pregunta como una FAQ :
Nota para usuarios de Windows: use comillas dobles ( " ) en lugar de simples 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 ha enviado este código a un repositorio remoto como GitHub y otros tienen clonado ese repositorio remoto, ahora estás en una situación en la que estás reescribiendo la historia. Cuando otros intenten bajar 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 arreglar esto, tendrán que eliminar su repositorio existente y volver a clonarlo, o seguir las instrucciones en "RECUPERANDO DE REBASE ASCENDENTE" en la página de manual git-rebase.
En el futuro, si accidentalmente confirme algunos cambios con información sensible, pero nota antes de enviar a un repositorio remoto, hay algunas correcciones más fáciles. 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
Que modificará la confirmación anterior con cualquier cambio nuevo que hayas hecho, incluyendo la eliminación completa de archivos hecha con un git rm
. Si los cambios están más atrás en la historia pero aún no se envían a un control remoto repositorio, puede hacer un rebase interactivo:
git rebase -i origin/master
Que abre un editor con las confirmaciones que ha realizado desde su último ancestro común con el repositorio remoto. Cambie " pick "a" edit " en cualquier línea que represente un commit con información confidencial, y guarde y salga. Git recorrerá los cambios y te dejará en un lugar donde puedas:
$EDITOR file-to-fix
git commit -a --amend
git rebase --continue
Para cada cambio con información sensible. Eventualmente, usted terminará de nuevo en su rama, y usted puede empujar con seguridad el nuevo cambio.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-05-26 12:16:07
Cambiar sus contraseñas es una buena idea, pero para el proceso de eliminación de contraseñas del historial de su repositorio, recomiendo el BFG Repo-Cleaner, una alternativa más rápida y simple a git-filter-branch
diseñada explícitamente para eliminar datos privados de los repositorios Git.
Cree un archivo private.txt
que enumere 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
Todos los archivos bajo un tamaño de umbral (1MB por defecto) en el historial de su repositorio serán escaneado, y cualquier cadena coincidente (que no esté en su última confirmación) será reemplazada por la cadena "***REMOVED***". Luego puede usar git gc
para limpiar los datos muertos:
$ git gc --prune=now --aggressive
El BFG es típicamente 10-50x más rápido que ejecutar git-filter-branch
y las opciones se simplifican y adaptan en torno a estos dos casos de uso comunes:
- Eliminar Archivos grandes locos
- Eliminando Contraseñas, Credenciales y otras Privadas datos
Revelación completa: Soy el autor del Repo-Cleaner de BFG.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-07-11 06:41:03
Recomiendoeste guion de David Underhill, funcionó como un encanto para mí.
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 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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-01-14 03:53:50
Si ya has empujado a GitHub, los datos se ven comprometidos incluso si los empujas un segundo más tarde porque:
-
GitHub sigue colgando confirmaciones durante mucho tiempo.
GitHub personal tiene el poder de eliminar dicha colgando confirma si usted en contacto con ellos, sin embargo, que es lo que debe hacer: Cómo quitar un colgando cometer desde GitHub?
Las confirmaciones colgantes se pueden ver a través de:
- la interfaz web de confirmación: https://github.com/cirosantilli/test-dangling/commit/53df36c09f092bbb59f2faa34eba15cd89ef8e83 (Wayback machine )
- la API: https://api.github.com/repos/cirosantilli/test-dangling/commits/53df36c09f092bbb59f2faa34eba15cd89ef8e83 ( Wayback machine)
Una forma conveniente de obtener el código fuente en ese commit es usar el método download zip, que puede aceptar cualquier referencia, p. ej.: https://github.com/cirosantilli/myrepo/archive/SHA.zip
-
Es posible obtener los SHAs faltantes ya sea por:
- listado de eventos API con
type": "PushEvent"
. P. ej. mío: https://api.github.com/users/cirosantilli/events/public ( Wayback machine ) - más convenientemente a veces, mirando los SHAs de pull requests que intentaron eliminar el contenido
- listado de eventos API con
-
Hay raspadores como http://ghtorrent.org / y https://www.githubarchive.org / que agrupan regularmente los datos de GitHub y los almacenan en otro lugar.
No pude encontrar si raspan la diferencia real de commit, pero es técnicamente posible.
Para probar esto, he creado un repo: https://github.com/cirosantilli/test-dangling y hecho:
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
Si elimina el repositorio sin embargo, las confirmaciones desaparecen incluso de la API inmediatamente y dan 404, e. g.https://api.github.com/repos/cirosantilli/test-dangling-delete/commits/8c08448b5fbf0f891696819f3b2b2d653f7a3824 Esto funciona incluso si recreas otro repositorio con el mismo nombre.
Así que mi curso de acción recomendado es:
-
Cambie sus credenciales
-
Si eso no es suficiente (por ejemplo, fotos desnudas):
- eliminar el repositorio
- póngase en contacto con el soporte
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-24 21:23:06
Para ser claros: La respuesta aceptada es correcta. Pruébalo primero. Sin embargo, puede ser innecesariamente complejo para algunos casos de uso, particularmente si encuentra errores desagradables como 'fatal: bad revision pr prune-empty', o realmente no le importa el historial de su repositorio.
Una alternativa sería:
- cd a la rama base del proyecto
- Elimine el código / archivo sensible
- rm-rf .git / # Eliminar toda la información de git de su código
- Vaya a github y elimine su 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/
Esto, por supuesto, eliminará todas las ramas del historial de confirmaciones y los problemas tanto de tu repositorio de github como de tu repositorio de git local. Si esto es inaceptable, tendrá que utilizar un enfoque alternativo.
Llame a esto la opción nuclear.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-01-25 23:38:51
Aquí está mi solución en windows
Git filter-branch tree tree-filter "rm-f' filedir / filename '" HEAD
Git push force force
Asegúrese de que la ruta es correcta de lo contrario no funcionará
Espero que ayude
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-12-02 19:19:31
Use filter-branch :
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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-09-17 14:50:54
Puede usar git forget-blob
.
El uso es bastante simple git forget-blob file-to-forget
. Puede obtener más información aquí
Desaparecerá de todas las confirmaciones en tu historial, reflog, etiquetas, etc.
Me encuentro con el mismo problema de vez en cuando, y cada vez que tengo que volver a este post y otros, es por eso que automatizé el proceso.
Créditos a colaboradores de Stack Overflow que me permitieron armar esto
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-01-23 07:41:12
He tenido que hacer esto un par de veces hasta la fecha. Tenga en cuenta que esto solo funciona en 1 archivo a la vez.
-
Obtiene una lista de todas las confirmaciones que modificaron un archivo. El que está en la parte inferior será el primer commit:
git log --pretty=oneline --branches -- pathToFile
-
Para eliminar el archivo del historial use el primer commit 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>..
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-03-21 18:23:36
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
.gitignore
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-02-16 04:53:08