可以制作 Mercurial 以保留文件权限吗?

Posted

技术标签:

【中文标题】可以制作 Mercurial 以保留文件权限吗?【英文标题】:Can Mercurial be made to preserve file permissions? 【发布时间】:2010-11-20 08:41:09 【问题描述】:

我看过许多博客文章,并且亲身体验过,Mercurial 不会保留从一个存储库推送到另一个存储库的文件的权限。有谁知道会保留权限的 Mercurial 扩展?我假设它不能用钩子完成,因为钩子对原始仓库的权限了解多少?

要求详细说明:

如果对文件的唯一更改是权限更改(例如,chmod o+r filename),则尝试提交文件失败并显示文件未更改的消息。

如果我提交一个权限为 600 (rw-------) 的文件,然后克隆 repo,克隆中的同一文件具有权限 664 (rw-rw-r--):

: nr@yorkie 6522 ; hg clone one two
updating working directory
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
: nr@yorkie 6523 ; ls -l one two
one:
total 4
-rw------- 1 nr nr 8 Aug 18 21:50 foo

two:
total 4
-rw-rw-r-- 1 nr nr 8 Aug 18 21:51 foo

这个例子表明hg clone 不保留权限,但hg push 也不保留它们。

在我的应用程序中,一个 repo 位于可公开访问的路径上,这一点非常重要

多个用户有权更改repo

公共存储库中的文件只有在明确设为可读时才变得可读。

【问题讨论】:

你能详细说明一下吗?我可以更改本地文件的权限,提交更改,将它们推送到克隆,当我更新它时,克隆将更改权限。关键是我必须同时提交和更新。您是否希望推送到克隆以仅从推送中更改权限?要在没有提交的情况下注意到本地更改?推断所有现有权限?确切的问题是什么/我错过了什么? @quark:它是怎么做的?我在 Debian Linux 上使用 hg 1.2.1,我什至无法承认 permissinos 的更改是值得提交的更改。 (注意,我已根据您的要求进行了详细说明。) Norman:原来我缺少的是你想坚持更改为“r”和“w”的事实,而我所说的是对“x”的更改(Mercurial 自 0.6 以来一直在跟踪)。我应该意识到你的意思是读/写不可执行。 我同意不能轻松管理远程权限可能是一个真正的痛苦。在工作中通过使用setfacl 来解决我们的许多权限问题,但它 (a) 要求您在服务器上实际进行更改,并且 (b) 更改权限仍然只是文件所有者的领域. (b) 意味着即使 hg 确实允许记录对“rw”的更改,它仍然需要运行 setuid 以在远程端进行更改,除了存储库所有者之外的所有人。 【参考方案1】:

由于作者网站上的dead git 链接,我认为 metastore 是废弃软件,所以我将下面的内容直接放在 repo 的 .hc/hgrc 配置文件中:

[paths]
default = ...

[hooks]
# NOTE: precommit is different than pre-commit, see https://www.mercurial-scm.org/repo/hg/help/hgrc for list of hooks
pre-commit  =
        # export permissions
        hg st -camn0 | sort -z | xargs -0 getfacl > .hg.hook.pre-commit.acl.export
        hg add .hg.hook.pre-commit.acl.export

        # export timestamps
        hg st -camn0 | sort -z | xargs -0 stat > .hg.hook.pre-commit.stat.export
        hg add .hg.hook.pre-commit.stat.export

update =
        # import permissions
        setfacl --restore=.hg.hook.pre-commit.acl.export

        # import timestamps
        # TODO: use touch to restore timestamps

【讨论】:

【参考方案2】:

使用Mercurial FAQ 的这个解决方案怎么样:

如果您使用 Mercurial 进行配置 文件管理,您可能想要 跟踪文件属性(所有权和 权限)。仅水银 跟踪每个的可执行位 文件。

这是一个如何保存的示例 属性以及文件(作品 如果你有 acl 包,在 Linux 上 已安装):

# cd /etc && getfacl -R . >/tmp/acl.$$ && mv /tmp/acl.$$ .acl
# hg commit

这远非完美,但你明白了。如需更复杂的解决方案,请查看 etckeeper。

【讨论】:

【参考方案3】:

看起来可以使用钩子和辅助工具(以及一点口香糖和打包线)来完成:

    获取 David Hardeman 的 Metastore,它可以保存和恢复文件元数据。

    更改源,使其忽略目录.hg.git

    使用以下 Mercurial 钩子:

     precommit.meta = metastore -s
    
     changegroup.update = hg update
     update.meta   = /usr/unsup/nr/bin/metastore -a
    

您必须将 .metadata 文件添加到 repo。

此 lashup 大部分时间都可以使用,但如果您更改 权限并希望传播它,则必须运行 metastore -s 才能将这些更改推送到 .metadata hg 将看到更改的文件;否则提交认为没有什么是新的。

【讨论】:

与 Devid Hardeman 的链接已过时。新链接:github.com/przemoc/metastore.git 顺便说一句。这里:***.com/a/17583212/751932 被提到了另一个工具 git-cache-meta.sh gist.github.com/Cojad/9205547【参考方案4】:

对于 /etc 目录的具体情况,etckeeper 看起来很有趣。

【讨论】:

【参考方案5】:

在 VCS 中存储权限不是一个好主意。但是,Mercurial 支持“可执行”标志(这与权限不同,尽管在 Unix 中可执行标志是权限的一部分)。

【讨论】:

一般来说这可能不是一个好主意,但在我的应用程序中,权限是关键的元数据,它们必须是正确的。 DVCS 不是理想的工具,但似乎是最好的。

以上是关于可以制作 Mercurial 以保留文件权限吗?的主要内容,如果未能解决你的问题,请参考以下文章

在 Mercurial 中拆分文件并保留双方的历史记录

Mercurial:忽略文件权限/模式(chmod)更改

Mercurial:我可以在路径中混合斜杠和反斜杠吗?

用于跳过文件以忽略 Mercurial 文件的 Google App Engine App.yaml 配置

制作没有前缀的 mercurial 存档

Mercurial - 如何重新启动分支[重复]