¿Cómo puedo purgar una palabra de la historia de git mientras mantengo la mayor cantidad de historia posible?

TL; DR: Hay una frase en nuestro repository de git que debe eliminarse del historial , no solo las cabezas de las twigs. ¿Qué otras forms hay además de eliminarlo del departamento de desarrollo y hacer un nuevo repository? Queremos mantener la mayor cantidad de historia posible.

Fondo

Por razones legales repulsivas, mi equipo y yo tenemos que eliminar todas las instancias de una palabra de nuestro código base (llamémoslo Voldemort solo por diversión y relevancia). Lo molesto es que no solo tenemos que eliminar a Voldemort de las puntas de las twigs, tenemos que eliminarlo de cada compromiso en nuestros repositorys (la demanda es algo así como "ningún desarrollador debe ser razonablemente capaz de revertir" a un estado donde Voldemort estaba en el código " ).

Ya no usamos Voldemort, pero hay algunos lugares en el código donde aún se mencionan como comentarios. (Sí, como parte de una demanda legal, debemos eliminar los comentarios infractores de nuestro código).

El plan original era purgar la palabra que no se debe mencionar y luego crear un nuevo repository e insert el estado actual como la confirmación inicial. ¡No queremos perder toda nuestra historia 1 sin embargo! Entonces queremos saber si hay una manera de evitar eso.

Entonces, la pregunta es ¿cómo eliminamos Voldemort, la palabra que no se debe mencionar, de la historia mientras se mantiene la mayor cantidad posible de la historia 1 ? Además, ¿qué podemos hacer para asegurarnos de que no esté en ningún compromiso? Queremos saber cómo verificar nuestro trabajo para asegurarnos de que se haya ido.

1: Por historia, no me refiero a los commits específicos, solo me refiero a poder ver la historia de un file y saber quién hizo qué, está bien para mí si la historia se ha ido como en "reescribir la historia" en el git. sentido, en realidad estoy adivinando que es el único enfoque.

Información sobre el estado del repository

  • Actualmente la twig de desarrollo está libre de Voldemort, pero tenemos confirmaciones "significativas" antes y después de los commits de purga
  • Probablemente solo el commit inicial tenga algo que agregue líneas con Voldemort (porque migramos de SVN a git y Voldemort se agregó hace años)
  • Probablemente los únicos commits que modifican cualquier file con Voldemort son los que lo eliminaron (como dije, es bastante viejo)

Conjeturas para un acercamiento

Parece que nos gustaría hacer algo como git log --patch | grep 'Voldemort' git log --patch | grep 'Voldemort' para encontrar commits que agreguen Voldemort y luego hagan una database interactiva de todo lo que edite los commits donde se agregó Voldemort para agregar alguna otra cosa o nada en absoluto.

Echa un vistazo a git filter-branch aquí .

Utilice el BFG Repo Cleaner , que es más rápido y fácil de usar que git filter-branch .

Para replace todas las apariciones de Voldemort , en todos los files, con el text *** REMOVED *** , puede simplemente:

 % echo 'Voldemort' > badwords.txt % bfg --replace-text badwords.txt myrepo.git 

Le agradezco a Ewan Mellor por apuntarme en la dirección correcta, pero la respuesta es muy pequeña y creo que esto necesita más detalles.


Recordatorio

Si haces una copy nueva del repository antes de hacer esto, asegúrate de tener las twigs locales de todos los controles remotos (por ej., git checkout master; git checkout develop; git checkout feature/some-undone-feature etc.).


Lo que hicimos

 > git filter-branch --tree-filter "~/purge.sh" \ --msg-filter "sed -e 's/voldemort/<word removed due to lawsuit>/gI'" \ --tag-name-filter "cat" \ -- --all 

El script de purga (probablemente podría ser una línea, pero es más limpio como este):

 #!/bin/bash files=$(grep -rli 'voldemort') for file in ${files}; do sed -i -e 's/voldemort/<word removed due to lawsuit>/gI' ${file} done 

Próximos pasos

Ahora que ha terminado, querrá verificar estas preguntas:

  1. Eliminar refs / original / heads / master de git repo after filter-branch –tree-filter? : Esto le mostrará cómo eliminar la copy de security que hace la git filter-branch .
  2. Listado y eliminación de confirmaciones de Git que no están bajo ninguna twig (¿colgando?) : Esto asegurará que no haya malas palabras en su repository local. Esto es necesario en nuestro caso porque si la mala palabra está en nuestra computadora portátil, la compañía puede ser demandada y / o pueden realizar una limpieza remota si encuentran el software Voldemort. Es posible que desee ejecutar esto en su repository remoto, pero si no puede hacer una nueva (con un nombre o URL ligeramente diferente para asegurarse de que nadie lo presione por error o se fusione, ¡deshaga todo su trabajo!) .

Explicación

  • --tree-filter "~/purge.sh"
    • para cada confirmación, ejecute el script ~/purge.sh contra el tree de trabajo ( --tree-filter ... )
      • hacer una list de files que contienen voldemort ( grep ... 'voldemort' )
      • recursivamente desde aquí, enumerando el nombre (no el contenido), y sin tener en count el caso ( -rli )
      • para cada file en la list ( for file in ${files}; do )
        • reemplace cada instancia de la palabra frase voldemort con <word removed due to lawsuit> en ese file ( sed ... -es/.../.../ ${file} )
        • en su lugar sin respaldo ( -i )
  • --msg-filter "sed -e 's/voldemort/<word removed due to lawsuit>/gI'"
    • Reemplaza cada instancia de la palabra frase voldemort con <word removed due to lawsuit> (sed -e s/.../.../ )
    • incluso si hay dos en una línea y sin importar el caso ( /gI )
    • en los posts de confirmación --msg-filter ...
  • --tag-name-filter "cat"
    • para cada label, renómbrela como su nombre anterior en la nueva confirmación (si no está presente, las tags no se transferirán)
  • -- --all
    • haga esto para cada confirmación en el repository (sí, eso es dos guiones seguidos por un espacio y luego otros dos guiones)

Nota sobre el performance

Usted se estará preguntando por qué no hicimos simplemente sed -i -e 's/voldemort/<word removed due to lawsuit>/gI' en cada file en --tree-filter . La razón es porque esto es mucho más lento. Creo que porque está reescribiendo cada file … en cada confirmación … incluso si la palabra que no debe nombrarse no está en el file. Se aceleró mucho el process (al less 10x, tal vez 100x, no quería esperar la primera manera de terminar) para get primero una list de files problemáticos por grep -rli 'voldemort' .