2009-06-22 11 views
46

Creo que ya sé la respuesta a esto, pero pensé en preguntar de todos modos:¿Hay alguna manera de eliminar el historial de un solo archivo en Mercurial?

Tenemos un archivo que se agregó a un repositorio de Mercurial con información sensible. ¿Hay alguna forma de eliminar ese archivo junto con su historial de cambios sin eliminar todo el repositorio?

+0

esta respuesta me ayudó, aunque no es "eliminar" sino convertir el repositorio a sí mismo (y se pierden todos los ID de conjuntos de cambios): http: // stackoverflow.com/a/22607889/714733 – jazzcat

Respuesta

22

No, no puedes. Lea la sección changes that should have never been del libro rojo mercurial al respecto; y en particular la what about sensitive changes that escape inciso, que contiene este párrafo:

Mercurial tampoco proporciona una manera para hacer un archivo o conjunto de cambios completamente desaparecer de la historia, porque hay hay manera de hacer cumplir su desaparición ; alguien podría fácilmente modificar su copia de Mercurial a ignorar tales directivas. Además, incluso si Mercurial proporciona una capacidad de tales , alguien que simplemente no tenían sacó un “hacer desaparecer este archivo” conjunto de cambios no se vería afectada por ella, ni tampoco rastreadores web visitante en la momento equivocado, copias de seguridad de disco u otros mecanismos . De hecho, ningún sistema de control de revisión distribuido puede hacer que los datos desaparezcan de manera confiable. Proporcionar la ilusión de tal control fácilmente podría dar una falsa sensación de seguridad, y ser peor que no proporcionarlo en absoluto.

La forma habitual para revertir los cambios confirmados es apoyado por mercurio a través del comando backout (de nuevo, el libro de mercurio: dealing with committed changes) pero la información no desaparece desde el repositorio: ya que nunca se sabe quién exactamente clona el repositorio, que daría una falsa sensación de seguridad, como se explicó anteriormente.

+12

Sí puede: https://www.jitbit.com/alexblog/232-removing-files-from-mercurial-history/ Por supuesto, todos ustedes deben reclonear sus repositorios, pero no lo hacen pierde toda la historia – wrzasa

+0

Si bien esta es la respuesta aceptada, no es la respuesta correcta. @wrzasa hizo referencia a la respuesta correcta en su comentario. Personalmente he hecho lo que el OP me preguntó varias veces usando información de ese enlace. – Chris

-2

trasplante de Hg, a continuación, la tira hg

+0

El archivo pasa por casi todo el historial de cambios. ¿Puede ampliar cómo podría usar los comandos anteriores para purgar el historial de archivos del repositorio y dejar intacto el historial de cambios para los otros archivos? –

+1

No se puede usar trasplante para eliminar un solo archivo de un conjunto de cambios; el trasplante solo sabe cómo mover conjuntos de cambios completos de una rama o depósito a otro (es como hg export | hg import). Ver mi respuesta sobre la extensión de conversión. –

58

Es cierto que no se puede quitar fácilmente un archivo en particular de Mercurial en el sentido de que al hacerlo interrumpirá todas las identificaciones del conjunto de cambios en su repositorio. Cuando cambia los ID del conjunto de cambios, todos tienen que volver a clonar el repositorio. Consulte el Wiki page about editing history para obtener información sobre las consecuencias de modificar el historial en Mercurial.

Si le parece bien (repositorio interno de una empresa), eche un vistazo al convert extension. Puede hacer hg → hg conversiones y tiene un argumento --filemap que se puede usar para excluir archivos, entre otras cosas.

+1

Consulte http://stackoverflow.com/questions/10103227/how-do-you-remove-big-files-from-history-in-mercurial para tratar un problema en una determinada versión de Mercurial. –

+1

Gracias Martin, rescató un depósito masivamente hinchado lleno de objetos binarios compilados. ¡Salvó el día! –

7

Es posible localmente, pero no globalmente, y cambia el ID de cada confirmación después del punto en que se agregó el archivo. Para que el cambio se mantenga, necesitarás acceso a cada copia del repositorio, especialmente las que se extraen o se expulsan.

Dicho esto, he seguido la secuencia Editing History descrita en el wiki de Mercurial para eliminar un archivo de uno de mis repositorios.Esta secuencia asume que la revisión 1301: 5200a5a10d8b añadió el archivo path/to/badfile.cfg, que no se cambia de ninguna revisión posterior:

  1. habilitar la extensión MQ en su .hgrc:

    [extensions] 
    mq = 
    
  2. extraer los cambios recientes de aguas arriba .

    hg pull 
    
  3. importación de todo, desde la adición de archivos en adelante en MQ:

    hg qimport -r 1301:tip 
    hg qpop -a 
    
  4. eliminar el archivo de la confirmación de que se ha añadido.

    hg qpush 1301.diff 
    hg forget path/to/badfile.cfg 
    hg qrefresh 
    
  5. Convierta los parches en nuevas revisiones de Mercurial.

    hg qpush -a 
    hg qfinish -a 
    
  6. Empuje las nuevas revisiones aguas arriba.

    hg push -f 
    
  7. En el repositorio aguas arriba y cada una de las demás copiar, eliminar las viejas revisiones.

    hg strip 5200a5a10d8b 
    

Advertencia: Este paso puede destruir la obra, a menos que seas cuidadoso. Si alguien ha cometido algo desde la última vez que sacó de la corriente ascendente, tendrá que volver a calcular ese trabajo antes de pelar. Lamentablemente, la extensión rebase no es útil aquí; tendrá que volver a usar MQ, convirtiendo los nuevos commit en parches que aplique en el nuevo consejo.

Buena suerte.

+0

Tuve que 'hg phase --secret --force 1301' antes de que funcionara como un hechizo. –

+0

Interesante. Sin embargo, parece que las fases son un poco diferentes, ya que ocultan la confirmación completa en lugar de eliminar un archivo de la confirmación. También es probable que no eliminen u oculten la confirmación para el repositorio en sentido ascendente. – eswald

4

Se puede hacer en menos de 10 min. en un único repositorio, aunque hay consecuencias.

Cómo: utilice la conversión de hg como se describe en this excellent guide. Básicamente, "convierte" un repositorio de Hg en un nuevo repositorio de Hg, pero puede especificar una lista de archivos para excluir durante la conversión. Este es un extracto de los pasos clave:

Make sure all your teammates have pushed their local changes to the central repo (if any) 
Backup your repository 
Create a "map.txt" file: 

# this filemap is used to exclude specific files 
exclude "subdir/filename1.ext" 
exclude "subdir/filename2.ext" 
exclude "subdir2" 

Run this command: 
hg convert --filemap map.txt c:/oldrepo c:/newrepo 
NOTE: You have to use "forward-slash" in paths, even on windows. 
Wait and be patient 
Now you have a new repo at c:\newrepo but without the files 

En cuanto a las consecuencias ...

  • todos los ID de conjunto de cambios después de los archivos que desea excluir se añadieron será diferente
  • el nuevo " clean "repositorio principal tendrá que ponerse manualmente en lugar del existente
  • todos los miembros del equipo tendrán que hacer nuevos clones del repo principal
  • cualquier otro servicio que se integre con Hg puede requieren atención (p. el rastreador de problemas, un sistema de revisión de códigos, etc.)
Cuestiones relacionadas