versiones control version-control mercurial dvcs

version-control - control - mercurial vs git



¿Hay alguna manera de eliminar el historial de un solo archivo en Mercurial? (5)

Creo que ya sé la respuesta a esto, pero pensé en preguntar de todos modos:

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?


Es correcto que no se puede eliminar fácilmente un archivo en particular de Mercurial en el sentido de que hacerlo interrumpirá todos los ID de los conjuntos de cambios en su repositorio. Cuando cambia los ID del conjunto de cambios, todos tienen que volver a clonar el repositorio. Consulte la página Wiki sobre el historial de edición para obtener información sobre las consecuencias de modificar la historia en Mercurial.

Si eso está bien para usted (repositorio interno en una empresa), entonces eche un vistazo a la extensión de conversión . Puede hacer conversiones hg → hg y tiene un argumento --filemap que puede usarse para excluir archivos, entre otras cosas.


Es posible localmente, pero no globalmente, y cambia el ID de cada confirmación después del punto en el 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 de Editar Historial descrita en la wiki de Mercurial para eliminar un archivo de uno de mis repositorios. Esta secuencia supone que la revisión 1301: 5200a5a10d8b agregó la path/to/badfile.cfg del archivo path/to/badfile.cfg , que no se modificó en ninguna revisión posterior:

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

    [extensions] mq =

  2. Tire de los cambios recientes desde la parte superior.

    hg pull

  3. Importe todo desde la adición del archivo hacia adelante en MQ:

    hg qimport -r 1301:tip hg qpop -a

  4. Elimine el archivo de la confirmación que lo agregó.

    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 en sentido ascendente y en cada otra copia, elimine las revisiones anteriores.

    hg strip 5200a5a10d8b

Advertencia : este paso puede destruir el trabajo, a menos que tenga cuidado. 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. Desafortunadamente, la extensión de 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.


No, no puedes. Lea los cambios que nunca deberían haber sido la sección del libro rojo mercurial al respecto; y particularmente, ¿qué pasa con los cambios sensibles que escapan a la subsección, que contiene este párrafo:

Mercurial tampoco proporciona una forma de hacer que un archivo o conjunto de cambios desaparezca completamente del historial, porque no hay forma de imponer su desaparición; alguien podría modificar fácilmente su copia de Mercurial para ignorar tales directivas. Además, incluso si Mercurial proporcionara tal capacidad, alguien que simplemente no hubiera sacado un conjunto de cambios "make this file disappear" no se vería afectado por él, ni los rastreadores web lo visitarían en el 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 dicho control podría fácilmente dar una falsa sensación de seguridad y ser peor que no proporcionarlo en absoluto.

La forma habitual de revertir los cambios confirmados es respaldada por mercurial a través del comando de backout (de nuevo, mercurial book: se trata de cambios comprometidos ) pero la información no desaparece del repositorio: ya que nunca se sabe quién clonó exactamente su repositorio, eso daría un falso sentido de seguridad, como se explicó anteriormente.


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

Cómo: use hg convert como se describe en jitbit.com/alexblog/232-removing-files-from-mercurial-history . 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 del conjunto de cambios después de agregarse los archivos que desea excluir serán diferentes
  • el nuevo repositorio principal "limpio" tendrá que ponerse manualmente en lugar del existente
  • todos los miembros del equipo tendrán que hacer nuevos clones del repositorio principal
  • cualquier otro servicio que se integre con Hg puede requerir atención (por ejemplo, el rastreador de problemas, un sistema de revisión de códigos, etc.)

hg transplant, luego hg strip