简体   繁体   English

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

[英]Is there a way to remove the history for a single file in Mercurial?

I think I already know the answer to this but thought I would ask anyway: 我想我已经知道答案,但我想我会问:

We have a file that got added to a Mercurial repository with sensitive information in it. 我们有一个文件被添加到Mercurial存储库中,其中包含敏感信息。 Is there any way to remove that file along with its change history without removing the whole repo? 有没有办法删除该文件及其更改历史记录而不删除整个回购?

It is correct that you cannot easily remove a particular file from Mercurial in the sense that doing so will disrupt all the changeset IDs in your repository. 从Mercurial中删除特定文件是正确的,因为这样做会破坏存储库中的所有变更集ID。 When you change the changeset IDs, everybody has to re-clone the repository. 更改变更集ID时,每个人都必须重新克隆存储库。 See the Wiki page about editing history for information about the consequences of modifying the history in Mercurial. 有关修改Mercurial中历史记录的后果的信息,请参阅有关编辑历史记录Wiki页面

If that is okay to you (internal repository in a company), then take a look at the convert extension . 如果您可以(公司内部存储库),那么请查看转换扩展 It can do hg → hg conversions and has a --filemap argument which can be used to exclude files, among other things. 它可以执行hg→hg转换,并且有一个--filemap参数,可用于排除文件等。

No, you can't. 不,你不能。 Read the changes that should have never been section of the mercurial red book about it; 阅读应该从未出现过关于它的多变红皮书的变化 ; and particularly the what about sensitive changes that escape subsection, which contains this paragraph: 特别是关于逃避子部分的敏感变化,包含这一段:

Mercurial also does not provide a way to make a file or changeset completely disappear from history, because there is no way to enforce its disappearance; Mercurial也没有提供使文件或变更集完全从历史中消失的方法,因为没有办法强制执行它的消失; someone could easily modify their copy of Mercurial to ignore such directives. 有人可以轻松修改他们的Mercurial副本以忽略这些指令。 In addition, even if Mercurial provided such a capability, someone who simply hadn't pulled a “make this file disappear” changeset wouldn't be affected by it, nor would web crawlers visiting at the wrong time, disk backups, or other mechanisms. 此外,即使Mercurial提供了这样的功能,只是没有提取“使此文件消失”变更集的人不会受到影响,网络爬虫也不会在错误的时间访问,磁盘备份或其他机制。 Indeed, no distributed revision control system can make data reliably vanish. 实际上,没有分布式修订控制系统可以使数据可靠地消失。 Providing the illusion of such control could easily give a false sense of security, and be worse than not providing it at all. 提供这种控制的幻觉很容易给人一种虚假的安全感,并且比根本不提供它更糟糕。

The usual way to revert committed changes is supported by mercurial through the backout command (again, mercurial book: dealing with committed changes ) but the information does not disappear from the repository: since you never know who exactly cloned your repository, that would give a false sense of security, as explained above. mercurial通过backout命令支持恢复已提交更改的常用方法(同样,mercurial书: 处理已提交的更改 ),但信息不会从存储库中消失:因为您永远不知道谁确切地克隆了您的存储库,这将给出一个如上所述,错误的安全感。

It is possible locally, but not globally, and it changes the ID of each commit after the point at which the file was added. 它可以在本地,但不是全局,并且在添加文件之后更改每个提交的ID。 In order for the change to stick, you'll need access to every single copy of the repository, particularly the ones that get pulled or pushed from. 为了使更改成为可能,您需要访问存储库的每个副本,特别是那些被拉出或推送的副本。

That said, I have followed the Editing History sequence described on the Mercurial wiki to remove a file from one of my repositories. 也就是说,我已经按照Mercurial wiki上描述的编辑历史序列来删除我的一个存储库中的文件。 This sequence assumes that revision 1301:5200a5a10d8b added the file path/to/badfile.cfg , which was not changed in any subsequent revision: 此序列假定修订版1301:5200a5a10d8b将文件path/to/badfile.cfg添加path/to/badfile.cfg ,这在以后的任何修订版中都没有更改:

  1. Enable the MQ extension in your .hgrc : .hgrc启用MQ扩展:

     [extensions] mq = 
  2. Pull recent changes from upstream. 从上游拉出最近的变化。

     hg pull 
  3. Import everything from the file addition onward into MQ: 将文件添加的所有内容导入MQ:

     hg qimport -r 1301:tip hg qpop -a 
  4. Remove the file from the commit that added it. 从添加它的提交中删除该文件。

     hg qpush 1301.diff hg forget path/to/badfile.cfg hg qrefresh 
  5. Convert the patches into new Mercurial revisions. 将修补程序转换为新的Mercurial修订版。

     hg qpush -a hg qfinish -a 
  6. Push the new revisions upstream. 将新版本推向上游。

     hg push -f 
  7. On the upstream repository and every single other copy, remove the old revisions. 在上游存储库和每个其他副本上,删除旧版本。

     hg strip 5200a5a10d8b 

Warning : This step may destroy work, unless you're careful. 警告 :除非您小心,否则此步骤可能会破坏工作。 If anybody has committed anything since the last time you pulled from upstream, then you'll have to rebase that work before stripping. 如果自上次你从上游撤出以来有人提交了任何东西,那么你必须在剥离之前重新开始这项工作。 Unfortunately, the rebase extension is not helpful here; 不幸的是, rebase扩展在这里没有用; you'll have to use MQ again, converting the new commits into patches that you apply onto the new tip. 您将不得不再次使用MQ,将新提交转换为您应用于新提示的修补程序。

Good luck. 祝好运。

It can be done in under 10 min. 它可以在10分钟内完成。 in a single repository, although there are consequences. 在单个存储库中,虽然有后果。

How: use hg convert as described in this excellent guide . 方法:使用hg转换,如本优秀指南中所述 Basically, you "convert" an Hg repo into a new Hg repo, but you get to specify a list of files to exclude during conversion. 基本上,您将Hg仓库“转换”为新的Hg仓库,但您可以指定要在转换期间排除的文件列表。 This is an excerpt of the key steps: 这是关键步骤的摘录:

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

As for the consequences... 至于后果......

  • all changeset IDs after the files you want to exclude were added will be different 添加要排除的文件后,所有变更集ID都将不同
  • the new "clean" main repository will have to be manually put in place of the existing one 必须手动放置新的“干净”主存储库来代替现有存储库
  • all team members will have to make new clones of the main repo 所有团队成员都必须制作主要回购的新克隆
  • any other services which integrate with Hg may require attention (eg the issue tracker, a code review system etc.) 与Hg集成的任何其他服务可能需要注意(例如问题跟踪器,代码审查系统等)

hg移植,然后hg strip

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM