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 comenzar de nuevo eliminando el directorio /.git.
¿Hay alguna manera de eliminar todos los rastros de un archivo en particular en su historial de Git?
Respuestas:
¡Para todos los fines prácticos, lo primero que debe preocuparle es CAMBIAR SUS CONTRASEÑAS! No queda claro a partir de su pregunta si su repositorio git es completamente local o si todavía 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 corrija esto, tendrá una copia de sus contraseñas en su máquina local, y no hay forma de que pueda obligarlos a actualizar a su versión "fija" sin pasar del historial. Lo único seguro que puede hacer es cambiar su contraseña a otra en cualquier lugar donde la haya usado.
Con eso fuera del camino, aquí está cómo solucionarlo. GitHub respondió exactamente esa pregunta como una pregunta frecuente :
Nota para usuarios de Windows : use comillas dobles (") en lugar de simples en este comando
Actualización 2019:
Este es el código actual de las preguntas frecuentes:
Tenga en cuenta que una vez que haya insertado este código en un repositorio remoto como GitHub y otros hayan clonado ese repositorio remoto, ahora se encuentra en una situación en la que está reescribiendo el historial. Cuando otros intentan 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 .
Consejo : Ejecutar
git rebase --interactive
En el futuro, si accidentalmente confirma algunos cambios con información confidencial pero se da cuenta antes de pasar a un repositorio remoto, hay algunas soluciones 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:
Eso enmendará la confirmación anterior con cualquier cambio nuevo que haya realizado, incluidas las eliminaciones de archivos completos realizadas con a
git rm
. Si los cambios están más atrás en el historial pero aún no se envían a un repositorio remoto, puede hacer un cambio de base interactivo:Eso abre un editor con las confirmaciones que ha realizado desde su último antepasado común con el repositorio remoto. Cambie "elegir" a "editar" en cualquier línea que represente una confirmación con información confidencial, y guarde y salga. Git analizará los cambios y te dejará en un lugar donde puedes:
Para cada cambio con información sensible. Eventualmente, terminará de nuevo en su sucursal, y puede impulsar con seguridad los nuevos cambios.
fuente
filter-branch
código y el de la página de github a la que se vinculó. Por ejemplo, su tercera línea--prune-empty --tag-name-filter cat -- --all
. ¿Ha cambiado la solución o me falta algo?<introduction-revision-sha1>..HEAD
no funciona. Solo elimina el archivo del segundo commit en adelante. (¿Cómo incluyo el commit inicial en el rango de commits?) La forma de guardar se indica aquí: help.github.com/articles/…git filter-branch --force --index-filter \ 'git rm --cached --ignore-unmatch PATH-TO-YOUR-FILE-WITH-SENSITIVE-DATA' \ --prune-empty --tag-name-filter cat -- --all
Cambiar sus contraseñas es una buena idea, pero para el proceso de eliminar las contraseñas del historial de su repositorio, recomiendo el BFG Repo-Cleaner , una alternativa más rápida y sencilla que
git-filter-branch
la diseñada explícitamente para eliminar datos privados de repositorios de Git.Crear un
private.txt
archivo que enumere las contraseñas, etc., que desea eliminar (una entrada por línea) y luego ejecute este comando: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 coincidente (que no esté en su último commit) será reemplazada por la cadena "*** ELIMINADO ***". Luego puede usar
git gc
para limpiar los datos muertos:El BFG suele ser 10-50x más rápido que la ejecución
git-filter-branch
y las opciones se simplifican y se adaptan a estos dos casos de uso comunes:Divulgación completa: soy el autor del BFG Repo-Cleaner.
fuente
git commit
. De lo contrario, +1 para la nueva herramienta en la caja de herramientas del desarrollador :)These are your protected commits, and so their contents will NOT be altered
mientras recorre y revisa el resto de su historial de confirmación. Sin embargo, si necesita revertir, entonces sí, tendría que hacer una búsqueda***REMOVED***
en la confirmación a la que acaba de retroceder.Si presionó a GitHub, forzar el empuje no es suficiente, elimine el repositorio o póngase en contacto con el soporte
Incluso si fuerza el empuje un segundo después, no es suficiente como se explica a continuación.
Los únicos cursos de acción válidos son:
¿Qué se filtró una credencial modificable como una contraseña?
no (fotos desnudas):
¿te importa si se resuelven todos los problemas del repositorio?
si:
Forzar un segundo más tarde no es suficiente porque:
GitHub sigue colgando confirmaciones durante mucho tiempo.
Sin embargo, el personal de GitHub tiene el poder de eliminar tales confirmaciones pendientes si se contacta con ellos.
Experimenté esto de primera mano cuando subí todos los correos electrónicos de confirmación de GitHub a un repositorio , me pidieron que lo retirara, así que lo hice, y lo hicieron
gc
. Sin embargo, las solicitudes de extracción que contienen los datos deben eliminarse : los datos de repos permanecieron accesibles hasta un año después de la eliminación inicial debido a esto.Los compromisos de colgar se pueden ver a través de:
Una forma conveniente de obtener la fuente en ese commit es usar el método zip de descarga, que puede aceptar cualquier referencia, por ejemplo: https://github.com/cirosantilli/myrepo/archive/SHA.zip
Es posible obtener los SHA faltantes ya sea por:
type": "PushEvent"
. Por ejemplo, el mío: https://api.github.com/users/cirosantilli/events/public ( máquina Wayback )Hay scrappers como http://ghtorrent.org/ y https://www.githubarchive.org/ que regularmente agrupan datos de GitHub y los almacenan en otro lugar.
No pude encontrar si raspan el diff de confirmación real, y eso es poco probable porque habría demasiados datos, pero es técnicamente posible, y la NSA y sus amigos probablemente tengan filtros para archivar solo cosas vinculadas a personas o commits de interés.
Sin embargo, si elimina el repositorio en lugar de forzar el empuje, las confirmaciones desaparecen incluso de la API de inmediato y dan 404, por ejemplo, https://api.github.com/repos/cirosantilli/test-dangling-delete/commits/8c08448b5fbf0f891696819f3b2b2d653f7a3824 Esto funciona incluso si recrea otro repositorio con el mismo nombre.
Para probar esto, he creado un repositorio: https://github.com/cirosantilli/test-dangling e hice:
Consulte también: ¿Cómo eliminar una confirmación pendiente de GitHub?
fuente
Recomiendo este guión de David Underhill, funcionó de maravilla para mí.
Agrega estos comandos además de la rama de filtro de natacado para limpiar el desorden que deja:
Guión completo (todo el crédito a David Underhill)
Los dos últimos comandos pueden funcionar mejor si se cambian a los siguientes:
fuente
git gc --aggressive --prune=now
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: mala revisión --prune-empty', o realmente no le importa el historial de su repositorio.
Una alternativa sería:
Por supuesto, esto eliminará todas las ramas del historial de confirmaciones y los problemas tanto de su repositorio de github como de su repositorio de git local. Si esto es inaceptable, deberá utilizar un enfoque alternativo.
Llame a esto la opción nuclear.
fuente
Puedes usar
git forget-blob
.El uso es bastante simple.
git forget-blob file-to-forget
. Puedes obtener más información aquíhttps://ownyourbits.com/2017/01/18/completely-remove-a-file-from-a-git-repository-with-git-forget-blob/
Desaparecerá de todos los commits en tu historial, reflog, etiquetas, etc.
Me encuentro con el mismo problema de vez en cuando, y cada vez que tengo que volver a esta publicación y a otras, es por eso que automaticé el proceso.
Créditos a contribuyentes de Stack Overflow que me permitieron armar esto
fuente
Aquí está mi solución en windows
asegúrese de que la ruta sea correcta, de lo contrario no funcionará
Espero que ayude
fuente
Utilice filter-branch :
fuente
He tenido que hacer esto varias 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á 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 complételos en este comando:
git filter-branch --index-filter 'git rm --cached --ignore-unmatch <path-to-file>' -- <sha1-where-the-file-was-first-added>..
fuente
Entonces, se parece a esto:
fuente
En mi proyecto de Android tenía admob_keys.xml como archivo xml separado en la carpeta app / src / main / res / values / . Para eliminar este archivo confidencial, utilicé el siguiente script y funcioné perfectamente.
fuente