2010-01-21 7 views
14

Empecé a trabajar recientemente en un pequeño script de Python para FTP. Para empezar, tenía los detalles de servidor, inicio de sesión y contraseña para un sitio FTP cableado en el script, pero esto no importaba porque solo estaba trabajando en él localmente.Redacción en git

Tuve la genial idea de poner el proyecto en github. Me di cuenta de mi error poco después y reemplacé los detalles cableados con una solución que involucraba .netrc. Ahora eliminé el proyecto de github, ya que cualquiera podía ver el historial y ver los detalles de inicio de sesión en texto sin formato.

La pregunta es, ¿hay alguna manera de pasar por el historial de git y eliminar el nombre de usuario y la contraseña en todo momento, pero de lo contrario dejar el historial intacto? ¿O necesito comenzar un nuevo repositorio sin historial?

+0

Duplicado de http://stackoverflow.com/questions/2004024/how-to-permanently-delete-a-file-stored-in-git – Thomas

+0

@Thomas - No es una tontería, esa pregunta es sobre borrar un archivo. Solo quiero borrar una línea en un archivo. – Skilldrick

+0

Bien, esta pregunta no es un dup. La otra pregunta es sobre eliminar un archivo completo, donde la respuesta es usar 'git filter-branch --index-filter'. En el caso de querer eliminar o modificar una línea en un archivo, necesita 'git filter-branch --tree-filter'. –

Respuesta

21

En primer lugar, debe cambiar la contraseña en el sitio FTP. La contraseña ya se ha hecho pública; no puede garantizar que nadie haya clonado el repositorio, o que no esté en texto sin formato en una copia de seguridad en alguna parte, o algo por el estilo. Si la contraseña es valiosa, la consideraría comprometida por ahora.

Ahora, para su pregunta sobre cómo editar el historial. El comando git filter-branch está destinado a este fin; recorrerá cada commit en el historial de su repositorio, aplicará un comando para modificarlo y luego creará un nuevo commit.

En particular, usted quiere git filter-branch --tree-filter. Esto le permite editar el contenido del árbol (los archivos y directorios reales) para cada confirmación. Ejecutará un comando en un directorio que contiene todo el árbol, su comando puede editar archivos, agregar nuevos archivos, eliminar archivos, moverlos, etc. Git luego creará un nuevo objeto de confirmación con todos los mismos metadatos (mensaje de confirmación, fecha, etc.) como el anterior, pero con el árbol modificado por su comando, tratando los nuevos archivos como agregados, archivos perdidos como borrados, etc. (por lo tanto, su comando no necesita hacer git add o git rm, solo necesita modificar el árbol).

para sus propósitos, algo así como lo siguiente debería funcionar, con la expresión regular apropiada y el nombre dependiendo de su situación exacta:

git filter-branch --tree-filter "sed -i -e 's/SekrtPassWrd/REDACTED/' myscript.py" -- --all 

Recuerda hacer esto de una copia de su repositorio, así que si algo sale mal, todavía tendrá el original y puede comenzar de nuevo. filter-branch también guardará las referencias a sus ramas originales, como original/refs/heads/master y así sucesivamente, por lo que podrá recuperar incluso si olvida hacerlo; Cuando hago alguna modificación global en mi historial de código fuente, me gusta asegurarme de tener múltiples resguardos en caso de que algo salga mal.

Para explicar cómo funciona esto en más detalle:

sed -i -e 's/SekrtPassWrd/REDACTED/' myscript.py 

Esto reemplazará SekrtPassWrd en su archivo myscript.py con REDACTED; La opción -i de sed le dice que edite el archivo en su lugar, sin ningún archivo de copia de seguridad (ya que Git lo recuperaría como un archivo nuevo).

Si necesita hacer algo más complicado que una sola sustitución, puede escribir una secuencia de comandos e invocarla para su comando; solo asegúrese de llamarlo con una ruta de acceso absoluta, ya que git filter-branch llama a su comando desde un directorio temporal.

git filter-branch --tree-filter <command> -- --all 

Esto le dice git para ejecutar un filtro de árbol, como se describió anteriormente, sobre todas las ramas en su repositorio. La parte -- --all le dice a Git que aplique esto a todas las ramas; sin él, solo edita el historial de la rama actual, dejando sin cambios todas las otras ramas (que probablemente no es lo que desea).

Consulte la documentación en GitHub en Removing Sensitive Data (como originally pointed out by MBO) para obtener más información sobre cómo tratar las copias de la información que se envió a GitHub. Tenga en cuenta que reiteran mi consejo de cambiar su contraseña y brindan algunos consejos para tratar con copias almacenadas en caché que GitHub aún puede tener.

+2

Esto es muy útil, muchas gracias. También la nota sobre cambiar la contraseña: necesitaba que pateara el culo, aplausos. – Skilldrick

+1

Útil, gracias. – blindsnowmobile

+1

Seguí recibiendo archivos de copia de seguridad con un sufijo "-e" todas mis confirmaciones (es decir, "Video.swift" y "Video-e.swift"). Para solucionar esto, tuve que agregar '''' (dos comillas simples) después de la opción '-i'. Así que todo el comando fue 'git filter-branch --tree-filter" sed -i '' -e 's/SekrtPassWrd/REDACTED /' myscript.py '- --all'. Verificando 'man sed' dice que la opción' -i' creará un archivo de copia de seguridad con el sufijo proporcionado después de la bandera a menos que se proporcione un valor vacío. – donut

3

Creo que deberías poder cambiar todas tus confirmaciones usando el comando filter-branch. Ver the section in the ProGit book para más detalles.

Sin embargo, como enlace @MBO 's señala

no borra commit en el repositorio remoto fuerza de empuje, simplemente introduce otros nuevos y se mueve el puntero rama para que apunte a ellos

Por lo tanto, tendrá que eliminar el repositorio completamente de GitHub para eliminar esos commits (es decir, incluso si no están en su historial de commits, todavía están flotando en el repositorio)

5

Quizás solo sea más fácil ch ¿Quieres ingresar tu contraseña en el sitio FTP? A menos que esté avergonzado por el código ...

+1

+1, Incluso si elimina con éxito el archivo del historial de git, la contraseña y la cuenta asociada se deben tratar como comprometidas. – Kevin

1

Para agregar al chosen answer por @Brian Campbell, tuve problemas con su código en mi caso de uso. Simplemente me faltaba el archivo en cuestión en las confirmaciones anteriores. Estoy seguro que no soy la única persona en esta situación, así que hice un arreglo simple/hackear

git filter-branch --tree-filter "sed -i -e 's/SekrtPassWrd/REDACTED/' myscript.py || echo 'fail'" -- --all 

único que hice fue agregar || echo 'fail' para asegurar el código sería seguir funcionando incluso cuando el archivo no se encontró en el commit . Espero que alguien más lo encuentre útil o pueda responder con un método mejor para manejar los archivos que faltan. No tengo suficientes representantes, así que tuve que hacer una nueva respuesta.