Есть ли способ удалить историю для одного файла в Mercurial? - PullRequest
47 голосов
/ 23 июня 2009

Я думаю, что уже знаю ответ на этот вопрос, но подумал, что я все равно задам вопрос:

У нас есть файл, который был добавлен в репозиторий Mercurial с конфиденциальной информацией в нем. Есть ли способ удалить этот файл вместе с историей изменений, не удаляя весь репо?

Ответы [ 5 ]

58 голосов
/ 23 июня 2009

Это правильно, что вы не можете легко удалить определенный файл из Mercurial в том смысле, что это нарушит все идентификаторы набора изменений в вашем хранилище. Когда вы меняете идентификаторы набора изменений, все должны повторно клонировать репозиторий. См. Страницу Wiki об истории редактирования для получения информации о последствиях изменения истории в Mercurial.

Если это нормально (внутренний репозиторий в компании), взгляните на расширение convert . Он может выполнять преобразования hg → hg и имеет аргумент - filemap , который может использоваться для исключения файлов, среди прочего.

22 голосов
/ 23 июня 2009

Нет, вы не можете. Прочитайте изменения, которые никогда не должны были быть разделом ртутной красной книги об этом; и особенно насчет чувствительных изменений, которые выходят из подраздела , который содержит этот абзац:

Mercurial также не предоставляет способ сделать файл или набор изменений полностью исчезнуть из истории, потому что там нет способа обеспечить его исчезновение; кто-то мог легко изменить их копию Mercurial для игнорировать такие директивы. К тому же, даже если Mercurial предоставил такой способность, тот, кто просто не имел вытащил «сделать этот файл исчезнуть» изменения не будут затронуты этим, сканеры веб-сайтов, посещающие неправильное время, резервное копирование диска или другое механизмы. Действительно, нет распределенных система контроля версий может делать данные надежно исчезают. Предоставление иллюзия такого контроля может легко дать ложное чувство безопасности и быть хуже, чем вообще не предоставлять.

Обычный способ вернуть зафиксированные изменения поддерживается Mercurial с помощью команды backout (опять же, книга Mercurial: , имеющая дело с зафиксированными изменениями ), но информация не исчезает репозиторий: поскольку вы никогда не знаете, кто именно клонировал ваш репозиторий, это дало бы ложное чувство безопасности, как объяснялось выше.

7 голосов
/ 22 ноября 2011

Это возможно локально, но не глобально, и оно меняет идентификатор каждого коммита после точки, в которую был добавлен файл. Чтобы изменения вступили в силу, вам потребуется доступ к каждой копии хранилища, особенно к тем, которые извлекаются или выталкиваются.

Тем не менее, я следовал последовательности История редактирования , описанной в вики Mercurial, чтобы удалить файл из одного из моих репозиториев. Эта последовательность предполагает, что в ревизии 1301: 5200a5a10d8b добавлен файл path/to/badfile.cfg, который не был изменен ни в одной из последующих ревизий:

  1. Включите расширение MQ в вашем .hgrc:

    [extensions]
    mq =
    
  2. Извлечь последние изменения из апстрима.

    hg pull
    
  3. Импортировать все, начиная с добавления файла, в MQ:

    hg qimport -r 1301:tip
    hg qpop -a
    
  4. Удалить файл из коммита, который его добавил.

    hg qpush 1301.diff
    hg forget path/to/badfile.cfg
    hg qrefresh
    
  5. Преобразование исправлений в новые версии Mercurial.

    hg qpush -a
    hg qfinish -a
    
  6. Выдвиньте новые ревизии вверх по течению.

    hg push -f
    
  7. В вышестоящем репозитории и каждой другой копии удалите старые ревизии.

    hg strip 5200a5a10d8b
    

Предупреждение : Этот шаг может разрушить работу, если вы не будете осторожны. Если кто-то совершил что-либо с тех пор, как вы в последний раз вышли из апстрима, вам придется перебазировать эту работу, прежде чем убирать. К сожалению, расширение rebase здесь не поможет; вам придется снова использовать MQ, преобразовывая новые коммиты в патчи, которые вы применяете к новому совету.

Удачи.

6 голосов
/ 04 сентября 2015

Это можно сделать менее чем за 10 мин. в одном хранилище, хотя есть последствия.

Как: используйте hg convert, как описано в этого превосходного руководства . По сути, вы «конвертируете» репозиторий Hg в новый репозиторий Hg, но вы можете указать список файлов, которые необходимо исключить при конвертации. Это выдержка из ключевых шагов:

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

Что касается последствий ...

  • все идентификаторы изменений после добавления файлов, которые вы хотите исключить, будут другими
  • новый «чистый» основной репозиторий должен быть вручную вставлен вместо существующего
  • все члены команды должны будут сделать новые клоны основного репо
  • любые другие службы, которые интегрируются с Hg, могут требовать внимания (например, средство отслеживания ошибок, система проверки кода и т. Д.)
0 голосов
/ 23 июня 2009

рт.ст. трансплантация, затем рт.ст.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...