50

我想我已经知道了这个问题的答案,但我想我还是会问:

我们有一个文件被添加到 Mercurial 存储库中,其中包含敏感信息。有没有办法在不删除整个仓库的情况下删除该文件及其更改历史记录?

4

5 回答 5

59

正确的是,您不能轻易地从 Mercurial 中删除特定文件,因为这样做会破坏存储库中的所有变更集 ID。当您更改变更集 ID 时,每个人都必须重新克隆存储库。有关在 Mercurial 中修改历史记录的后果的信息,请参阅有关编辑历史记录的 Wiki 页面。

如果这对您来说没问题(公司的内部存储库),那么看看convert extension。它可以进行hg → hg转换,并具有--filemap参数,可用于排除文件等。

于 2009-06-23T09:09:14.990 回答
24

不,你不能。阅读本不该出现在红皮书中的变化部分;尤其是逃逸小节的敏感变化怎么办,其中包含本段:

Mercurial 也没有提供使文件或变更集从历史中完全消失的方法,因为无法强制其消失;有人可以轻松地修改他们的 Mercurial 副本以忽略此类指令。此外,即使 Mercurial 提供了这样的功能,那些根本没有拉出“使这个文件消失”变更集的人也不会受到它的影响,网络爬虫也不会在错误的时间访问、磁盘备份或其他机制. 事实上,没有分布式修订控制系统可以使数据可靠地消失。提供这种控制的假象很容易给人一种虚假的安全感,而且比根本不提供更糟糕。

mercurial 通过backout命令支持恢复已提交更改的常用方法(同样,mercurial book:处理已提交的更改),但信息不会从存储库中消失:因为您永远不知道谁确切克隆了您的存储库,这将给出错误安全感,如上所述。

于 2009-06-23T03:07:47.857 回答
7

它在本地是可能的,但不是全局的,它会在添加文件之后更改每个提交的 ID。为了使更改生效,您需要访问存储库的每个副本,尤其是从中提取或推送的副本。

也就是说,我已经按照 Mercurial wiki 上描述的编辑历史顺序从我的一个存储库中删除了一个文件。此序列假定修订版 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,将新提交转换为您应用到新提示的补丁。

祝你好运。

于 2011-11-22T14:23:30.247 回答
7

它可以在 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

至于后果……

  • 添加要排除的文件后的所有变更集 ID 都将不同
  • 必须手动将新的“干净”主存储库替换现有的主存储库
  • 所有团队成员都必须对主仓库进行新的克隆
  • 与 Hg 集成的任何其他服务可能需要注意(例如问题跟踪器、代码审查系统等)
于 2015-09-04T09:52:19.683 回答
-2

hg移植,然后hg剥离

于 2009-06-23T06:30:22.307 回答