Giorgos Keramidas avatar Giorgos Keramidas committed b321ab2

Add a 'rechmod' extension for fixing workspace permissions

Comments (0)

Files changed (1)

+# rechmod.py - restore working directory file permissions
+#
+# Copyright 2009 Giorgos Keramidas <keramida@ceid.upatras.gr>
+#
+# This software may be used and distributed according to the terms
+# of the GNU General Public License, incorporated herein by reference.
+#
+# hg rechmod [FILE | DIR] ...
+
+'''Restore the permissions of working area files to their last recorded
+state.'''
+
+from mercurial.posix import umask
+from mercurial.node import hex
+from mercurial.commands import dryrunopts, walkopts
+from mercurial import cmdutil
+from mercurial.i18n import _
+import os
+
+def chmod(ui, file, mode=None):
+    '''Set the mode of FILE to MODE, but turn off any bits set in the current
+    file-creation umask.'''
+    if file and (mode is None):
+        ui.warn(_("no mode for file %s\n") % f)
+
+    mode = mode & 0777
+    mode = mode & ~umask
+    try:
+        os.chmod(file, mode)
+    except OSError:
+        ui.warn(_("cannot reset file mode: %s\n") % file)
+
+def rechmod(ui, repo, *pats, **opts):
+    """restore file permissions to their last recorded state
+
+    Restore the file mode of files or subdirectories of the working copy to
+    their last recorded state.  If -r REV is used, use the manifest of that
+    revision instead of the working copy parent.
+
+    With --debug flag, print file modes as they are set."""
+
+    rev = repo.dirstate.parents()[0]
+    if opts.get('rev'):
+        rev = opts.get('rev')
+    node = rev
+
+    decor = {'l':'644 s ', 'x':'755 x ', '':'644 f '}
+    ctx = repo[node]
+    mf = ctx.manifest()
+    m = cmdutil.match(repo, pats, opts)
+    for f in repo.walk(m, node):
+        if not f in ctx:
+            ui.warn(_("file %s not in rev %s") % (f, node))
+            continue
+        if ui.debugflag:
+            ui.write("%40s " % hex(mf[f]))
+        if ui.verbose or opts.get('dry_run'):
+            ui.write(decor[ctx.flags(f)])
+            ui.write("%s\n" % f)
+        mode = 'x' in ctx.flags(f) and 0777 or 0666
+        if not opts.get('dry_run'):
+            fpath = "%s/%s" % (repo.root, f)
+            chmod(ui, fpath, mode)
+    return None
+
+cmdtable = {
+"rechmod":
+        (rechmod,
+         walkopts + dryrunopts +
+         [('r', 'rev', '', _('restore permissions from specified revision'))],
+        _('hg rechmod [-r REV] [FILE]...')),
+}
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.