有没有办法在Mercurial中删除单个文件的历史记录?

时间:2009-06-22 21:24:52

标签: version-control mercurial dvcs

我想我已经知道答案,但我想我会问:

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

5 个答案:

答案 0 :(得分:58)

从Mercurial中删除特定文件是正确的,因为这样做会破坏存储库中的所有变更集ID。更改变更集ID时,每个人都必须重新克隆存储库。有关在Mercurial中修改历史记录的后果的信息,请参阅Wiki page about editing history

如果您可以(公司内部存储库),那么请查看convert extension。它可以执行 hg→hg 转换,并且有一个 - filemap 参数,可用于排除文件等。

答案 1 :(得分:22)

不,你不能。阅读关于它的善变红皮书的 changes that should have never been 部分;特别是 what about sensitive changes that escape 小节,其中包含以下段落:

  

Mercurial也没有提供方法   完全创建文件或变更集   从历史中消失,因为那里   没有办法强制执行它   消失;有人可以轻松   将他们的Mercurial副本修改为   忽略这样的指令。此外,   即使Mercurial提供了这样的   能力,一个根本没有的人   拉了一下“让这个文件消失”   变更集不会受其影响,   网络爬虫也不会访问   错误的时间,磁盘备份或其他   机制。的确,没有分布式   修订控制系统可以制作数据   可靠地消失。提供   这种控制的幻觉很容易   给予一种虚假的安全感,并且   比根本不提供它更糟糕。

mercurial通过backout命令(同样,mercurial book:dealing with committed changes)支持恢复已提交更改的常用方法,但信息不会从存储库中消失:因为您永远不知道究竟是谁如上所述,克隆了您的存储库,这会产生错误的安全感。

答案 2 :(得分:7)

可以在本地,但不是全局,并且在添加文件之后更改每个提交的ID。为了使更改成为可能,您需要访问存储库的每个副本,特别是那些被拉出或推送的副本。

也就是说,我已遵循Mercurial wiki上描述的Editing History序列从我的某个存储库中删除文件。此序列假定修订版1301:5200a5a10d8b添加了文件path/to/badfile.cfg,该文件在任何后续版本中均未更改:

  1. .hgrc

    中启用MQ扩展程序
    [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
    
  8. 警告:除非您小心,否则此步骤可能会破坏工作。如果自上次你从上游撤出以来有人提交了任何东西,那么你必须在剥离之前重新开始这项工作。不幸的是,rebase扩展程序在这里没有帮助;您将不得不再次使用MQ,将新提交转换为您应用于新提示的补丁。

    祝你好运。

答案 3 :(得分:6)

可以在10分钟内完成。在一个存储库中,虽然有后果。

如何:按this excellent guide中所述使用hg转换。基本上,你"转换"将Hg repo转换为新的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集成的任何其他服务可能需要引起注意(例如问题跟踪器,代码审查系统等)。

答案 4 :(得分:-2)

hg移植,然后hg strip