simplify flag handling
add _checklink var to dirstate
introduce dirstate.flagfunc
switch users of util.execfunc/linkfunc to flagfunc
change manifestdict.set to take a flags string
change ctx.fileflags to ctx.flags
change gitmode func to a dict
remove util.execfunc/linkfunc
--- a/hgext/keyword.py Thu Jun 26 13:46:33 2008 -0500
+++ b/hgext/keyword.py Thu Jun 26 13:46:34 2008 -0500
@@ -387,7 +387,7 @@
files += unknown
files.sort()
wctx = repo.changectx(None)
- islink = lambda p: 'l' in wctx.fileflags(p)
+ islink = lambda p: 'l' in wctx.flags(p)
kwfiles = [f for f in files if kwt.iskwfile(f, islink)]
cwd = pats and repo.getcwd() or ''
kwfstats = not opts.get('ignore') and (('K', kwfiles),) or ()
--- a/mercurial/commands.py Thu Jun 26 13:46:33 2008 -0500
+++ b/mercurial/commands.py Thu Jun 26 13:46:34 2008 -0500
@@ -2480,7 +2480,7 @@
if not opts.get('dry_run'):
def checkout(f):
fc = ctx[f]
- repo.wwrite(f, fc.data(), fc.fileflags())
+ repo.wwrite(f, fc.data(), fc.flags())
audit_path = util.path_auditor(repo.root)
for f in remove[0]:
--- a/mercurial/context.py Thu Jun 26 13:46:33 2008 -0500
+++ b/mercurial/context.py Thu Jun 26 13:46:34 2008 -0500
@@ -118,7 +118,7 @@
def filenode(self, path):
return self._fileinfo(path)[0]
- def fileflags(self, path):
+ def flags(self, path):
try:
return self._fileinfo(path)[1]
except revlog.LookupError:
@@ -237,9 +237,9 @@
def filerev(self): return self._filerev
def filenode(self): return self._filenode
- def fileflags(self): return self._changectx.fileflags(self._path)
- def isexec(self): return 'x' in self.fileflags()
- def islink(self): return 'l' in self.fileflags()
+ def flags(self): return self._changectx.flags(self._path)
+ def isexec(self): return 'x' in self.flags()
+ def islink(self): return 'l' in self.flags()
def filelog(self): return self._filelog
def rev(self):
@@ -509,16 +509,14 @@
man = self._parents[0].manifest().copy()
copied = self._repo.dirstate.copies()
- is_exec = util.execfunc(self._repo.root,
- lambda p: man.execf(copied.get(p,p)))
- is_link = util.linkfunc(self._repo.root,
- lambda p: man.linkf(copied.get(p,p)))
+ cf = lambda x: man.flags(copied.get(x, x))
+ ff = self._repo.dirstate.flagfunc(cf)
modified, added, removed, deleted, unknown = self._status[:5]
for i, l in (("a", added), ("m", modified), ("u", unknown)):
for f in l:
man[f] = man.get(copied.get(f, f), nullid) + i
try:
- man.set(f, is_exec(f), is_link(f))
+ man.set(f, ff(f))
except OSError:
pass
@@ -555,7 +553,7 @@
def children(self):
return []
- def fileflags(self, path):
+ def flags(self, path):
if '_manifest' in self.__dict__:
try:
return self._manifest.flags(path)
@@ -565,12 +563,9 @@
pnode = self._parents[0].changeset()[0]
orig = self._repo.dirstate.copies().get(path, path)
node, flag = self._repo.manifest.find(pnode, orig)
- is_link = util.linkfunc(self._repo.root,
- lambda p: flag and 'l' in flag)
- is_exec = util.execfunc(self._repo.root,
- lambda p: flag and 'x' in flag)
try:
- return (is_link(path) and 'l' or '') + (is_exec(path) and 'x' or '')
+ ff = self._repo.dirstate.flagfunc(lambda x: flag or '')
+ return ff(path)
except OSError:
pass
@@ -724,6 +719,7 @@
def clean(self): return self._status[5]
def branch(self): return self._extra['branch']
def extra(self): return self._extra
+ def flags(self, f): return self[f].flags()
def parents(self):
"""return contexts for each parent changeset"""
@@ -750,7 +746,7 @@
def __str__(self): return "%s@%s" % (self.path(), self._changectx)
def path(self): return self._path
def data(self): return self._data
- def fileflags(self): return self._flags
+ def flags(self): return self._flags
def isexec(self): return 'x' in self._flags
def islink(self): return 'l' in self._flags
def renamed(self): return self._copied
--- a/mercurial/dirstate.py Thu Jun 26 13:46:33 2008 -0500
+++ b/mercurial/dirstate.py Thu Jun 26 13:46:34 2008 -0500
@@ -70,6 +70,9 @@
elif name == '_slash':
self._slash = self._ui.configbool('ui', 'slash') and os.sep != '/'
return self._slash
+ elif name == '_checklink':
+ self._checklink = util.checklink(self._root)
+ return self._checklink
elif name == '_checkexec':
self._checkexec = util.checkexec(self._root)
return self._checkexec
@@ -91,6 +94,34 @@
def folding(self):
return self._folding
+ def flagfunc(self, fallback):
+ if self._checklink:
+ if self._checkexec:
+ def f(x):
+ p = os.path.join(self._root, x)
+ if os.path.islink(p):
+ return 'l'
+ if util.is_exec(p):
+ return 'x'
+ return ''
+ return f
+ def f(x):
+ if os.path.islink(os.path.join(self._root, x)):
+ return 'l'
+ if 'x' in fallback(x):
+ return 'x'
+ return ''
+ return f
+ if self._checkexec:
+ def f(x):
+ if 'l' in fallback(x):
+ return 'l'
+ if util.is_exec(os.path.join(self._root, x)):
+ return 'x'
+ return ''
+ return f
+ return fallback
+
def getcwd(self):
cwd = os.getcwd()
if cwd == self._root: return ''
--- a/mercurial/filemerge.py Thu Jun 26 13:46:33 2008 -0500
+++ b/mercurial/filemerge.py Thu Jun 26 13:46:34 2008 -0500
@@ -146,7 +146,7 @@
if tool == "internal:local":
return 0
if tool == "internal:other":
- repo.wwrite(fd, fco.data(), fco.fileflags())
+ repo.wwrite(fd, fco.data(), fco.flags())
return 0
if tool == "internal:fail":
return 1
--- a/mercurial/localrepo.py Thu Jun 26 13:46:33 2008 -0500
+++ b/mercurial/localrepo.py Thu Jun 26 13:46:34 2008 -0500
@@ -837,19 +837,16 @@
self.ui.note(f + "\n")
try:
fctx = wctx.filectx(f)
+ newflags = fctx.flags()
new[f] = self.filecommit(fctx, m1, m2, linkrev, trp, changed)
- new_exec = fctx.isexec()
- new_link = fctx.islink()
if ((not changed or changed[-1] != f) and
m2.get(f) != new[f]):
# mention the file in the changelog if some
# flag changed, even if there was no content
# change.
- old_exec = m1.execf(f)
- old_link = m1.linkf(f)
- if old_exec != new_exec or old_link != new_link:
+ if m1.flags(f) != newflags:
changed.append(f)
- m1.set(f, new_exec, new_link)
+ m1.set(f, newflags)
if use_dirstate:
self.dirstate.normal(f)
@@ -1009,14 +1006,9 @@
fixup = []
# do a full compare of any files that might have changed
ctx = self.changectx('')
- mexec = lambda f: 'x' in ctx.fileflags(f)
- mlink = lambda f: 'l' in ctx.fileflags(f)
- is_exec = util.execfunc(self.root, mexec)
- is_link = util.linkfunc(self.root, mlink)
- def flags(f):
- return is_link(f) and 'l' or is_exec(f) and 'x' or ''
+ ff = self.dirstate.flagfunc(ctx.flags)
for f in lookup:
- if (f not in ctx or flags(f) != ctx.fileflags(f)
+ if (f not in ctx or ff(f) != ctx.flags(f)
or ctx[f].cmp(self.wread(f))):
modified.append(f)
else:
@@ -1042,11 +1034,10 @@
# generate a pseudo-manifest for the working dir
# XXX: create it in dirstate.py ?
mf2 = mfmatches(self.dirstate.parents()[0])
- is_exec = util.execfunc(self.root, mf2.execf)
- is_link = util.linkfunc(self.root, mf2.linkf)
+ ff = self.dirstate.flagfunc(mf2.flags)
for f in lookup + modified + added:
mf2[f] = ""
- mf2.set(f, is_exec(f), is_link(f))
+ mf2.set(f, ff(f))
for f in removed:
if f in mf2:
del mf2[f]
--- a/mercurial/manifest.py Thu Jun 26 13:46:33 2008 -0500
+++ b/mercurial/manifest.py Thu Jun 26 13:46:34 2008 -0500
@@ -24,10 +24,8 @@
def linkf(self, f):
"test for symlink in manifest flags"
return "l" in self.flags(f)
- def set(self, f, execf=False, linkf=False):
- if linkf: self._flags[f] = "l"
- elif execf: self._flags[f] = "x"
- else: self._flags[f] = ""
+ def set(self, f, flags):
+ self._flags[f] = flags
def copy(self):
return manifestdict(dict.copy(self), dict.copy(self._flags))
--- a/mercurial/patch.py Thu Jun 26 13:46:33 2008 -0500
+++ b/mercurial/patch.py Thu Jun 26 13:46:34 2008 -0500
@@ -1193,16 +1193,6 @@
return
ctx2 = repo.changectx(node2)
- if node2:
- execf2 = ctx2.manifest().execf
- linkf2 = ctx2.manifest().linkf
- else:
- execf2 = util.execfunc(repo.root, None)
- linkf2 = util.linkfunc(repo.root, None)
- if execf2 is None:
- mc = ctx2.parents()[0].manifest().copy()
- execf2 = mc.execf
- linkf2 = mc.linkf
if repo.ui.quiet:
r = None
@@ -1219,6 +1209,8 @@
all.sort()
gone = {}
+ gitmode = {'l': '120000', 'x': '100755', '': '100644'}
+
for f in all:
to = None
tn = None
@@ -1230,18 +1222,16 @@
tn = getfilectx(f, ctx2).data()
a, b = f, f
if opts.git:
- def gitmode(x, l):
- return l and '120000' or (x and '100755' or '100644')
def addmodehdr(header, omode, nmode):
if omode != nmode:
header.append('old mode %s\n' % omode)
header.append('new mode %s\n' % nmode)
if f in added:
- mode = gitmode(execf2(f), linkf2(f))
+ mode = gitmode[ctx2.flags(f)]
if f in copy:
a = copy[f]
- omode = gitmode(man1.execf(a), man1.linkf(a))
+ omode = gitmode[man1.flags(a)]
addmodehdr(header, omode, mode)
if a in removed and a not in gone:
op = 'rename'
@@ -1260,11 +1250,11 @@
if f in copy and copy[f] in added and copy[copy[f]] == f:
dodiff = False
else:
- mode = gitmode(man1.execf(f), man1.linkf(f))
- header.append('deleted file mode %s\n' % mode)
+ header.append('deleted file mode %s\n' %
+ gitmode[man1.flags(f)])
else:
- omode = gitmode(man1.execf(f), man1.linkf(f))
- nmode = gitmode(execf2(f), linkf2(f))
+ omode = gitmode[man1.flags(f)]
+ nmode = gitmode[ctx2.flags(f)]
addmodehdr(header, omode, nmode)
if util.binary(to) or util.binary(tn):
dodiff = 'binary'
--- a/mercurial/util.py Thu Jun 26 13:46:33 2008 -0500
+++ b/mercurial/util.py Thu Jun 26 13:46:34 2008 -0500
@@ -933,12 +933,6 @@
return False
return not (new_file_has_exec or exec_flags_cannot_flip)
-def execfunc(path, fallback):
- '''return an is_exec() function with default to fallback'''
- if checkexec(path):
- return lambda x: is_exec(os.path.join(path, x))
- return fallback
-
def checklink(path):
"""check whether the given path is on a symlink-capable filesystem"""
# mktemp is not racy because symlink creation will fail if the
@@ -951,12 +945,6 @@
except (OSError, AttributeError):
return False
-def linkfunc(path, fallback):
- '''return an is_link() function with default to fallback'''
- if checklink(path):
- return lambda x: os.path.islink(os.path.join(path, x))
- return fallback
-
_umask = os.umask(0)
os.umask(_umask)