##// END OF EJS Templates
match: rename _fmap to _fileroots for clarity...
match: rename _fmap to _fileroots for clarity fmap isn't a very descriptive name for the set of the match's files.

File last commit:

r25149:3f0744ee default
r25189:1c8c33ea default
Show More
reposetup.py
375 lines | 16.7 KiB | text/x-python | PythonLexer
various
hgext: add largefiles extension...
r15168 # Copyright 2009-2010 Gregory P. Ward
# Copyright 2009-2010 Intelerad Medical Systems Incorporated
# Copyright 2010-2011 Fog Creek Software
# Copyright 2010-2011 Unity Technologies
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
'''setup for largefiles repositories: reposetup'''
import copy
import os
Martin von Zweigbergk
largefiles: replace manifestdict.__contains__, don't extend class...
r24276 from mercurial import error, match as match_, util
various
hgext: add largefiles extension...
r15168 from mercurial.i18n import _
Matt Harbison
largefiles: revert to lfilesrepo.status() being an unfiltered method...
r23958 from mercurial import scmutil, localrepo
various
hgext: add largefiles extension...
r15168
import lfcommands
import lfutil
def reposetup(ui, repo):
FUJIWARA Katsunori
hg: introduce "wirepeersetupfuncs" to setup wire peer by extensions (issue4109)...
r20858 # wire repositories should be given new wireproto functions
# by "proto.wirereposetup()" via "hg.wirepeersetupfuncs"
various
hgext: add largefiles extension...
r15168 if not repo.local():
FUJIWARA Katsunori
hg: introduce "wirepeersetupfuncs" to setup wire peer by extensions (issue4109)...
r20858 return
various
hgext: add largefiles extension...
r15168
Na'Tosha Bard
largefiles: remove use of underscores that breaks coding convention
r16247 class lfilesrepo(repo.__class__):
FUJIWARA Katsunori
largefiles: access to specific fields only if largefiles enabled (issue4547)...
r24158 # the mark to examine whether "repo" object enables largefiles or not
_largefilesenabled = True
various
hgext: add largefiles extension...
r15168 lfstatus = False
def status_nolfiles(self, *args, **kwargs):
Na'Tosha Bard
largefiles: remove use of underscores that breaks coding convention
r16247 return super(lfilesrepo, self).status(*args, **kwargs)
various
hgext: add largefiles extension...
r15168
Greg Ward
largefiles: improve comments, internal docstrings...
r15252 # When lfstatus is set, return a context that gives the names
# of largefiles instead of their corresponding standins and
# identifies the largefiles as always binary, regardless of
# their actual contents.
various
hgext: add largefiles extension...
r15168 def __getitem__(self, changeid):
Na'Tosha Bard
largefiles: remove use of underscores that breaks coding convention
r16247 ctx = super(lfilesrepo, self).__getitem__(changeid)
Matt Harbison
largefiles: revert to lfilesrepo.status() being an unfiltered method...
r23958 if self.lfstatus:
Na'Tosha Bard
largefiles: remove use of underscores that breaks coding convention
r16247 class lfilesctx(ctx.__class__):
various
hgext: add largefiles extension...
r15168 def files(self):
Na'Tosha Bard
largefiles: remove use of underscores that breaks coding convention
r16247 filenames = super(lfilesctx, self).files()
Martin Geisler
largefiles: use lfutil functions...
r15628 return [lfutil.splitstandin(f) or f for f in filenames]
various
hgext: add largefiles extension...
r15168 def manifest(self):
Na'Tosha Bard
largefiles: remove use of underscores that breaks coding convention
r16247 man1 = super(lfilesctx, self).manifest()
Martin von Zweigbergk
largefiles: fix typo with s/__class/__class__/...
r24428 class lfilesmanifest(man1.__class__):
Martin von Zweigbergk
largefiles: don't create chain of __contains__ calls...
r24287 def __contains__(self, filename):
orig = super(lfilesmanifest, self).__contains__
return (orig(filename) or
orig(lfutil.standin(filename)))
man1.__class__ = lfilesmanifest
various
hgext: add largefiles extension...
r15168 return man1
def filectx(self, path, fileid=None, filelog=None):
Martin von Zweigbergk
largefiles: extract 'orig' method in lfilesctx.filectx
r22517 orig = super(lfilesctx, self).filectx
various
hgext: add largefiles extension...
r15168 try:
Dan Villiom Podlaski Christiansen
largefiles: don't break filesets
r16141 if filelog is not None:
Martin von Zweigbergk
largefiles: extract 'orig' method in lfilesctx.filectx
r22517 result = orig(path, fileid, filelog)
Dan Villiom Podlaski Christiansen
largefiles: don't break filesets
r16141 else:
Martin von Zweigbergk
largefiles: extract 'orig' method in lfilesctx.filectx
r22517 result = orig(path, fileid)
various
hgext: add largefiles extension...
r15168 except error.LookupError:
# Adding a null character will cause Mercurial to
# identify this as a binary file.
Dan Villiom Podlaski Christiansen
largefiles: don't break filesets
r16141 if filelog is not None:
Martin von Zweigbergk
largefiles: extract 'orig' method in lfilesctx.filectx
r22517 result = orig(lfutil.standin(path), fileid,
filelog)
Dan Villiom Podlaski Christiansen
largefiles: don't break filesets
r16141 else:
Martin von Zweigbergk
largefiles: extract 'orig' method in lfilesctx.filectx
r22517 result = orig(lfutil.standin(path), fileid)
various
hgext: add largefiles extension...
r15168 olddata = result.data
result.data = lambda: olddata() + '\0'
return result
Na'Tosha Bard
largefiles: remove use of underscores that breaks coding convention
r16247 ctx.__class__ = lfilesctx
various
hgext: add largefiles extension...
r15168 return ctx
# Figure out the status of big files and insert them into the
Greg Ward
largefiles: improve comments, internal docstrings...
r15252 # appropriate list in the result. Also removes standin files
# from the listing. Revert to the original status if
# self.lfstatus is False.
Matt Harbison
largefiles: revert to lfilesrepo.status() being an unfiltered method...
r23958 # XXX large file status is buggy when used on repo proxy.
# XXX this needs to be investigated.
@localrepo.unfilteredmethod
various
hgext: add largefiles extension...
r15168 def status(self, node1='.', node2=None, match=None, ignored=False,
clean=False, unknown=False, listsubrepos=False):
listignored, listclean, listunknown = ignored, clean, unknown
Martin von Zweigbergk
largefiles: extract 'orig' method in reposetup.status
r22518 orig = super(lfilesrepo, self).status
Matt Harbison
largefiles: revert to lfilesrepo.status() being an unfiltered method...
r23958 if not self.lfstatus:
Martin von Zweigbergk
largefiles: extract 'orig' method in reposetup.status
r22518 return orig(node1, node2, match, listignored, listclean,
listunknown, listsubrepos)
Martin von Zweigbergk
largefiles: reduce indentation by dropping 'else' block after 'return'
r22515
# some calls in this function rely on the old version of status
Matt Harbison
largefiles: revert to lfilesrepo.status() being an unfiltered method...
r23958 self.lfstatus = False
Martin von Zweigbergk
largefiles: reduce indentation by dropping 'else' block after 'return'
r22515 ctx1 = self[node1]
ctx2 = self[node2]
working = ctx2.rev() is None
parentworking = working and ctx1 == self['.']
various
hgext: add largefiles extension...
r15168
Martin von Zweigbergk
largefiles: reduce indentation by dropping 'else' block after 'return'
r22515 if match is None:
match = match_.always(self.root, self.getcwd())
various
hgext: add largefiles extension...
r15168
Martin von Zweigbergk
largefiles: reduce indentation by dropping 'else' block after 'return'
r22515 wlock = None
try:
Mads Kiilerich
largefiles: wlock in status before lfdirstate.write()
r19056 try:
Martin von Zweigbergk
largefiles: reduce indentation by dropping 'else' block after 'return'
r22515 # updating the dirstate is optional
# so we don't wait on the lock
wlock = self.wlock(False)
except error.LockError:
pass
Na'Tosha Bard
largefiles: optimize status when files are specified (issue3144)...
r15653
Martin von Zweigbergk
largefiles: shortcircuit status code also for non-matching patterns...
r23146 # First check if paths or patterns were specified on the
# command line. If there were, and they don't match any
Martin von Zweigbergk
largefiles: reduce indentation by dropping 'else' block after 'return'
r22515 # largefiles, we should just bail here and let super
# handle it -- thus gaining a big performance boost.
lfdirstate = lfutil.openlfdirstate(ui, self)
Martin von Zweigbergk
largefiles: shortcircuit status code also for non-matching patterns...
r23146 if not match.always():
Martin von Zweigbergk
largefiles: reduce indentation by dropping 'else' block after 'return'
r22515 for f in lfdirstate:
if match(f):
break
else:
Martin von Zweigbergk
largefiles: extract 'orig' method in reposetup.status
r22518 return orig(node1, node2, match, listignored, listclean,
listunknown, listsubrepos)
various
hgext: add largefiles extension...
r15168
Martin von Zweigbergk
largefiles: reduce indentation by dropping 'else' block after 'return'
r22515 # Create a copy of match that matches standins instead
# of largefiles.
def tostandins(files):
if not working:
return files
newfiles = []
dirstate = self.dirstate
for f in files:
sf = lfutil.standin(f)
if sf in dirstate:
newfiles.append(sf)
elif sf in dirstate.dirs():
# Directory entries could be regular or
# standin, check both
newfiles.extend((f, sf))
else:
newfiles.append(f)
return newfiles
Mads Kiilerich
largefiles: unindent code
r18149
Martin von Zweigbergk
largefiles: reduce indentation by dropping 'else' block after 'return'
r22515 m = copy.copy(match)
m._files = tostandins(m._files)
Martin von Zweigbergk
largefiles: extract 'orig' method in reposetup.status
r22518 result = orig(node1, node2, m, ignored, clean, unknown,
listsubrepos)
Martin von Zweigbergk
largefiles: reduce indentation by dropping 'else' block after 'return'
r22515 if working:
Na'Tosha Bard
largefiles: optimize performance of status on largefiles repos (issue3136)
r15617
Martin von Zweigbergk
largefiles: reduce indentation by dropping 'else' block after 'return'
r22515 def sfindirstate(f):
sf = lfutil.standin(f)
dirstate = self.dirstate
return sf in dirstate or sf in dirstate.dirs()
Mads Kiilerich
largefiles: unindent code
r18149
Martin von Zweigbergk
largefiles: reduce indentation by dropping 'else' block after 'return'
r22515 match._files = [f for f in match._files
if sfindirstate(f)]
# Don't waste time getting the ignored and unknown
# files from lfdirstate
Martin von Zweigbergk
dirstate: separate 'lookup' status field from others...
r22911 unsure, s = lfdirstate.status(match, [], False, listclean,
False)
Martin von Zweigbergk
largefiles: access status fields by name rather than index
r22919 (modified, added, removed, clean) = (s.modified, s.added,
s.removed, s.clean)
Martin von Zweigbergk
largefiles: reduce indentation by dropping 'else' block after 'return'
r22515 if parentworking:
for lfile in unsure:
standin = lfutil.standin(lfile)
if standin not in ctx1:
# from second parent
modified.append(lfile)
elif ctx1[standin].data().strip() \
!= lfutil.hashfile(self.wjoin(lfile)):
modified.append(lfile)
else:
Martin von Zweigbergk
largefiles: remove unnecessary clearing of status fields...
r22523 if listclean:
clean.append(lfile)
Martin von Zweigbergk
largefiles: reduce indentation by dropping 'else' block after 'return'
r22515 lfdirstate.normal(lfile)
else:
tocheck = unsure + modified + added + clean
modified, added, clean = [], [], []
FUJIWARA Katsunori
largefiles: avoid exec-bit examination on the platform being unaware of it...
r23383 checkexec = self.dirstate._checkexec
Martin von Zweigbergk
largefiles: reduce indentation by dropping 'else' block after 'return'
r22515
for lfile in tocheck:
standin = lfutil.standin(lfile)
Mads Kiilerich
largefiles: inline redundant inctx function in status
r23043 if standin in ctx1:
FUJIWARA Katsunori
largefiles: add examination of exec bit in "hg status --rev REV" case...
r23090 abslfile = self.wjoin(lfile)
if ((ctx1[standin].data().strip() !=
lfutil.hashfile(abslfile)) or
FUJIWARA Katsunori
largefiles: avoid exec-bit examination on the platform being unaware of it...
r23383 (checkexec and
('x' in ctx1.flags(standin)) !=
FUJIWARA Katsunori
largefiles: add examination of exec bit in "hg status --rev REV" case...
r23090 bool(lfutil.getexecutable(abslfile)))):
various
hgext: add largefiles extension...
r15168 modified.append(lfile)
Martin von Zweigbergk
largefiles: remove unnecessary clearing of status fields...
r22523 elif listclean:
various
hgext: add largefiles extension...
r15168 clean.append(lfile)
Martin von Zweigbergk
largefiles: reduce indentation by dropping 'else' block after 'return'
r22515 else:
added.append(lfile)
various
hgext: add largefiles extension...
r15168
FUJIWARA Katsunori
largefiles: ignore removal status of files not managed in the target context...
r23089 # at this point, 'removed' contains largefiles
# marked as 'R' in the working context.
# then, largefiles not managed also in the target
# context should be excluded from 'removed'.
removed = [lfile for lfile in removed
if lfutil.standin(lfile) in ctx1]
Martin von Zweigbergk
largefiles: reduce indentation by dropping 'else' block after 'return'
r22515 # Standins no longer found in lfdirstate has been
# removed
Martin von Zweigbergk
largefiles: simplify iteration over standins...
r22525 for standin in ctx1.walk(lfutil.getstandinmatcher(self)):
Martin von Zweigbergk
largefiles: reduce indentation by dropping 'else' block after 'return'
r22515 lfile = lfutil.splitstandin(standin)
if not match(lfile):
continue
if lfile not in lfdirstate:
removed.append(lfile)
Martin Geisler
largefiles: handle merges between normal files and largefiles (issue3084)...
r15663
Martin von Zweigbergk
largefiles: reduce indentation by dropping 'else' block after 'return'
r22515 # Filter result lists
result = list(result)
Mads Kiilerich
largefiles: wlock in status before lfdirstate.write()
r19056
Martin von Zweigbergk
largefiles: reduce indentation by dropping 'else' block after 'return'
r22515 # Largefiles are not really removed when they're
# still in the normal dirstate. Likewise, normal
# files are not really removed if they are still in
# lfdirstate. This happens in merges where files
# change type.
removed = [f for f in removed
if f not in self.dirstate]
result[2] = [f for f in result[2]
if f not in lfdirstate]
Martin Geisler
largefiles: handle merges between normal files and largefiles (issue3084)...
r15663
Martin von Zweigbergk
largefiles: reduce indentation by dropping 'else' block after 'return'
r22515 lfiles = set(lfdirstate._map)
# Unknown files
result[4] = set(result[4]).difference(lfiles)
# Ignored files
result[5] = set(result[5]).difference(lfiles)
# combine normal files and largefiles
normals = [[fn for fn in filelist
if not lfutil.isstandin(fn)]
for filelist in result]
Martin von Zweigbergk
largefiles: access status fields by name rather than index
r22919 lfstatus = (modified, added, removed, s.deleted, [], [],
Martin von Zweigbergk
largefiles: avoid using 'lfiles' variable for two purposes...
r22524 clean)
Martin von Zweigbergk
largefiles: reduce indentation by dropping 'else' block after 'return'
r22515 result = [sorted(list1 + list2)
Martin von Zweigbergk
largefiles: avoid using 'lfiles' variable for two purposes...
r22524 for (list1, list2) in zip(normals, lfstatus)]
Mads Kiilerich
largefiles: inline redundant toname function in status...
r23044 else: # not against working directory
result = [[lfutil.splitstandin(f) or f for f in items]
Martin von Zweigbergk
largefiles: reduce indentation by dropping 'else' block after 'return'
r22515 for items in result]
Martin Geisler
largefiles: handle merges between normal files and largefiles (issue3084)...
r15663
Martin von Zweigbergk
largefiles: reduce indentation by dropping 'else' block after 'return'
r22515 if wlock:
lfdirstate.write()
finally:
if wlock:
wlock.release()
various
hgext: add largefiles extension...
r15168
Matt Harbison
largefiles: revert to lfilesrepo.status() being an unfiltered method...
r23958 self.lfstatus = True
Martin von Zweigbergk
status: update various other methods to return new class
r22914 return scmutil.status(*result)
various
hgext: add largefiles extension...
r15168
FUJIWARA Katsunori
largefiles: factor out procedures to update lfdirstate for post-committing...
r23184 def commitctx(self, ctx, *args, **kwargs):
node = super(lfilesrepo, self).commitctx(ctx, *args, **kwargs)
class lfilesctx(ctx.__class__):
def markcommitted(self, node):
orig = super(lfilesctx, self).markcommitted
return lfutil.markcommitted(orig, self, node)
ctx.__class__ = lfilesctx
various
hgext: add largefiles extension...
r15168 return node
Greg Ward
largefiles: more work on cleaning up comments...
r15254 # Before commit, largefile standins have not had their
# contents updated to reflect the hash of their largefile.
# Do that here.
various
hgext: add largefiles extension...
r15168 def commit(self, text="", user=None, date=None, match=None,
force=False, editor=False, extra={}):
Na'Tosha Bard
largefiles: remove use of underscores that breaks coding convention
r16247 orig = super(lfilesrepo, self).commit
various
hgext: add largefiles extension...
r15168
Pierre-Yves David
largefile: use `self` in repo method instead of `repo`...
r17803 wlock = self.wlock()
various
hgext: add largefiles extension...
r15168 try:
FUJIWARA Katsunori
largefiles: introduce "_lfcommithooks" to abstract pre-committing procedures...
r23186 lfcommithook = self._lfcommithooks[-1]
match = lfcommithook(self, match)
Levi Bard
largefiles: fix inappropriate locking (issue3182)...
r15794 result = orig(text=text, user=user, date=date, match=match,
various
hgext: add largefiles extension...
r15168 force=force, editor=editor, extra=extra)
Levi Bard
largefiles: fix inappropriate locking (issue3182)...
r15794 return result
various
hgext: add largefiles extension...
r15168 finally:
wlock.release()
def push(self, remote, force=False, revs=None, newbranch=False):
FUJIWARA Katsunori
largefiles: setup "largefiles" feature in each repositories individually...
r19779 if remote.local():
missing = set(self.requirements) - remote.local().supported
if missing:
msg = _("required features are not"
" supported in the destination:"
" %s") % (', '.join(sorted(missing)))
raise util.Abort(msg)
Long Vu
largefiles: call super class method with proper kwargs to respect API...
r20177 return super(lfilesrepo, self).push(remote, force=force, revs=revs,
newbranch=newbranch)
various
hgext: add largefiles extension...
r15168
FUJIWARA Katsunori
largefiles: factor out procedures to update standins for pre-committing...
r23185 # TODO: _subdirlfs should be moved into "lfutil.py", because
# it is referred only from "lfutil.updatestandinsbymatch"
Levi Bard
largefiles: commit directories that only contain largefiles (issue3548)...
r18064 def _subdirlfs(self, files, lfiles):
'''
Adjust matched file list
Mads Kiilerich
spelling: fixes from proofreading of spell checker issues
r23543 If we pass a directory to commit whose only committable files
Levi Bard
largefiles: commit directories that only contain largefiles (issue3548)...
r18064 are largefiles, the core commit code aborts before finding
the largefiles.
So we do the following:
For directories that only have largefiles as matches,
Mads Kiilerich
spelling: fix some minor issues found by spell checker
r18644 we explicitly add the largefiles to the match list and remove
Levi Bard
largefiles: commit directories that only contain largefiles (issue3548)...
r18064 the directory.
In other cases, we leave the match list unmodified.
'''
actualfiles = []
dirs = []
regulars = []
for f in files:
if lfutil.isstandin(f + '/'):
raise util.Abort(
_('file "%s" is a largefile standin') % f,
hint=('commit the largefile itself instead'))
# Scan directories
if os.path.isdir(self.wjoin(f)):
dirs.append(f)
else:
regulars.append(f)
for f in dirs:
matcheddir = False
d = self.dirstate.normalize(f) + '/'
# Check for matched normal files
for mf in regulars:
if self.dirstate.normalize(mf).startswith(d):
actualfiles.append(f)
matcheddir = True
break
if not matcheddir:
# If no normal match, manually append
# any matching largefiles
for lf in lfiles:
if self.dirstate.normalize(lf).startswith(d):
actualfiles.append(lf)
if not matcheddir:
Matt Harbison
largefiles: fix commit of a directory with no largefile changes (issue4330)...
r23923 # There may still be normal files in the dir, so
Mads Kiilerich
spelling: fixes from proofreading of spell checker issues
r24180 # add a directory to the list, which
Matt Harbison
largefiles: update _subdirlfs() comment...
r24007 # forces status/dirstate to walk all files and
# call the match function on the matcher, even
Mads Kiilerich
spelling: fixes from proofreading of spell checker issues
r24180 # on case sensitive filesystems.
Matt Harbison
largefiles: fix commit of a directory with no largefile changes (issue4330)...
r23923 actualfiles.append('.')
Levi Bard
largefiles: commit directories that only contain largefiles (issue3548)...
r18064 matcheddir = True
# Nothing in dir, so readd it
# and let commit reject it
if not matcheddir:
actualfiles.append(f)
# Always add normal files
actualfiles += regulars
return actualfiles
Na'Tosha Bard
largefiles: remove use of underscores that breaks coding convention
r16247 repo.__class__ = lfilesrepo
various
hgext: add largefiles extension...
r15168
FUJIWARA Katsunori
largefiles: introduce "_lfcommithooks" to abstract pre-committing procedures...
r23186 # stack of hooks being executed before committing.
# only last element ("_lfcommithooks[-1]") is used for each committing.
repo._lfcommithooks = [lfutil.updatestandinsbymatch]
FUJIWARA Katsunori
largefiles: introduce "_lfstatuswriters" to customize status reporting...
r23188 # Stack of status writer functions taking "*msg, **opts" arguments
Mads Kiilerich
spelling: fixes from proofreading of spell checker issues
r23543 # like "ui.status()". Only last element ("_lfstatuswriters[-1]")
FUJIWARA Katsunori
largefiles: introduce "_lfstatuswriters" to customize status reporting...
r23188 # is used to write status out.
repo._lfstatuswriters = [ui.status]
FUJIWARA Katsunori
largefiles: reuse "findcommonoutgoing()" result at "hg push"...
r21044 def prepushoutgoinghook(local, remote, outgoing):
if outgoing.missing:
toupload = set()
addfunc = lambda fn, lfhash: toupload.add(lfhash)
lfutil.getlfilestoupload(local, outgoing.missing, addfunc)
lfcommands.uploadlfiles(ui, local, remote, toupload)
repo.prepushoutgoinghooks.add("largefiles", prepushoutgoinghook)
various
hgext: add largefiles extension...
r15168 def checkrequireslfiles(ui, repo, **kwargs):
Augie Fackler
cleanup: use __builtins__.any instead of util.any...
r25149 if 'largefiles' not in repo.requirements and any(
various
hgext: add largefiles extension...
r15168 lfutil.shortname+'/' in f[0] for f in repo.store.datafiles()):
Eli Carter
largefiles: remove 1.9 compat code
r15312 repo.requirements.add('largefiles')
various
hgext: add largefiles extension...
r15168 repo._writerequirements()
Mads Kiilerich
config: set a 'source' in most cases where config don't come from file but code...
r20790 ui.setconfig('hooks', 'changegroup.lfiles', checkrequireslfiles,
'largefiles')
ui.setconfig('hooks', 'commit.lfiles', checkrequireslfiles, 'largefiles')