Can Mercurial be made to preserve file permissions?

Viewed 14906

I've seen a number of blog posts, and have experienced for myself, that Mercurial does not preserve the permissions on files pushed from one repo to another. Does anyone know of a Mercurial extension that would preserve the permissions? I'm assuming it can't be done with a hook, because what does a hook know about permissions at the originating repo?

Requested elaboration:

  • If the only change to a file is a change in permissions (e.g., chmod o+r filename), attempts to commit the file fail with a message saying that the file has not changed.

  • If I commit a file with permissions 600 (rw-------), then clone the repo, the same file in the clone has permissions 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
    

This examples shows that hg clone does not preserve permissions, but hg push does not preserve them either.

In my application, one repo is on a publically accessible path, and it's of major importance that

  • Multiple users have the right to change the repo

  • Files in the public repo become readable only when explicitly made readable.

5 Answers

I assumed that metastore was abandonware due to the dead git link on author's site so I whipped the below which is placed directly in repo's .hc/hgrc configuration file:

[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
Related