##// END OF EJS Templates
_checkunknownfiles: turn 'conflicts' into a set...
_checkunknownfiles: turn 'conflicts' into a set We'll check for membership in this set in an upcoming patch.

File last commit:

r27586:42910f9f default
r27654:95dc67f1 default
Show More
overrides.py
1435 lines | 53.4 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.
'''Overridden Mercurial commands and functions for the largefiles extension'''
import os
import copy
FUJIWARA Katsunori
largefiles: remove meaningless code path for "hg pull --rebase"...
r23183 from mercurial import hg, util, cmdutil, scmutil, match as match_, \
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 archival, pathutil, revset, error
various
hgext: add largefiles extension...
r15168 from mercurial.i18n import _
import lfutil
import lfcommands
Mads Kiilerich
largefiles: fix cat of non-largefiles from subdirectory...
r18974 import basestore
various
hgext: add largefiles extension...
r15168
Na'Tosha Bard
largefiles: implement addremove (issue3064)...
r15792 # -- Utility functions: commonly/repeatedly needed functionality ---------------
Matt Harbison
largefiles: introduce the 'composelargefilematcher()' method...
r23617 def composelargefilematcher(match, manifest):
'''create a matcher that matches only the largefiles in the original
matcher'''
m = copy.copy(match)
lfile = lambda f: lfutil.standin(f) in manifest
m._files = filter(lfile, m._files)
Drew Gottlieb
match: rename _fmap to _fileroots for clarity...
r25189 m._fileroots = set(m._files)
Matt Harbison
largefiles: introduce the 'composelargefilematcher()' method...
r23617 m._always = False
origmatchfn = m.matchfn
m.matchfn = lambda f: lfile(f) and origmatchfn(f)
return m
Matt Harbison
largefiles: don't print files as both large and normal in addremove dryruns
r23769 def composenormalfilematcher(match, manifest, exclude=None):
excluded = set()
if exclude is not None:
excluded.update(exclude)
Matt Harbison
largefiles: split the creation of a normal matcher out of its install method...
r23428 m = copy.copy(match)
notlfile = lambda f: not (lfutil.isstandin(f) or lfutil.standin(f) in
Matt Harbison
largefiles: don't print files as both large and normal in addremove dryruns
r23769 manifest or f in excluded)
Matt Harbison
largefiles: split the creation of a normal matcher out of its install method...
r23428 m._files = filter(notlfile, m._files)
Drew Gottlieb
match: rename _fmap to _fileroots for clarity...
r25189 m._fileroots = set(m._files)
Matt Harbison
largefiles: split the creation of a normal matcher out of its install method...
r23428 m._always = False
origmatchfn = m.matchfn
m.matchfn = lambda f: notlfile(f) and origmatchfn(f)
return m
various
hgext: add largefiles extension...
r15168 def installnormalfilesmatchfn(manifest):
Mads Kiilerich
largefiles: clarify installmatchfn documentation
r21090 '''installmatchfn with a matchfn that ignores all largefiles'''
Pierre-Yves David
largefiles: remove a mutable default argument...
r26337 def overridematch(ctx, pats=(), opts=None, globbed=False,
Matt Harbison
scmutil: add an optional parameter to matcher factories for a bad() override...
r25467 default='relpath', badfn=None):
Pierre-Yves David
largefiles: remove a mutable default argument...
r26337 if opts is None:
opts = {}
Matt Harbison
scmutil: add an optional parameter to matcher factories for a bad() override...
r25467 match = oldmatch(ctx, pats, opts, globbed, default, badfn=badfn)
Matt Harbison
largefiles: split the creation of a normal matcher out of its install method...
r23428 return composenormalfilematcher(match, manifest)
Na'Tosha Bard
largefiles: remove use of underscores that breaks coding convention
r16247 oldmatch = installmatchfn(overridematch)
various
hgext: add largefiles extension...
r15168
def installmatchfn(f):
Mads Kiilerich
largefiles: clarify installmatchfn documentation
r21090 '''monkey patch the scmutil module with a custom match function.
Warning: it is monkey patching the _module_ on runtime! Not thread safe!'''
Na'Tosha Bard
largefiles: remove pre-1.9 code from extension first bundled with 1.9
r15224 oldmatch = scmutil.match
various
hgext: add largefiles extension...
r15168 setattr(f, 'oldmatch', oldmatch)
Na'Tosha Bard
largefiles: remove pre-1.9 code from extension first bundled with 1.9
r15224 scmutil.match = f
various
hgext: add largefiles extension...
r15168 return oldmatch
def restorematchfn():
Mads Kiilerich
largefiles: clarify installmatchfn documentation
r21090 '''restores scmutil.match to what it was before installmatchfn
various
hgext: add largefiles extension...
r15168 was called. no-op if scmutil.match is its original function.
Mads Kiilerich
largefiles: clarify installmatchfn documentation
r21090 Note that n calls to installmatchfn will require n calls to
Mads Kiilerich
spelling: fixes from proofreading of spell checker issues
r23543 restore the original matchfn.'''
Mads Kiilerich
largefiles: remove silent handling of incorrect invocation of restorematchfn...
r21092 scmutil.match = getattr(scmutil.match, 'oldmatch')
various
hgext: add largefiles extension...
r15168
Lucas Moscovicz
largefiles: changed overridelog to work with graphlog...
r21110 def installmatchandpatsfn(f):
oldmatchandpats = scmutil.matchandpats
setattr(f, 'oldmatchandpats', oldmatchandpats)
scmutil.matchandpats = f
return oldmatchandpats
def restorematchandpatsfn():
'''restores scmutil.matchandpats to what it was before
Mads Kiilerich
spelling: fixes from proofreading of spell checker issues
r23139 installmatchandpatsfn was called. No-op if scmutil.matchandpats
Lucas Moscovicz
largefiles: changed overridelog to work with graphlog...
r21110 is its original function.
Mads Kiilerich
spelling: fixes from proofreading of spell checker issues
r23139 Note that n calls to installmatchandpatsfn will require n calls
Mads Kiilerich
spelling: fixes from proofreading of spell checker issues
r23543 to restore the original matchfn.'''
Lucas Moscovicz
largefiles: changed overridelog to work with graphlog...
r21110 scmutil.matchandpats = getattr(scmutil.matchandpats, 'oldmatchandpats',
scmutil.matchandpats)
Matt Harbison
largefiles: align the output messages for an added file with core methods...
r23767 def addlargefiles(ui, repo, isaddremove, matcher, **opts):
Matt Harbison
largefiles: don't pop largefile-specific arguments to the add command...
r23884 large = opts.get('large')
Greg Ward
largefiles: factor out lfutil.getminsize()
r15227 lfsize = lfutil.getminsize(
Matt Harbison
largefiles: don't pop largefile-specific arguments to the add command...
r23884 ui, lfutil.islfilesrepo(repo), opts.get('lfsize'))
various
hgext: add largefiles extension...
r15168
lfmatcher = None
Michal Sznajder
largefiles: tiny code clean up...
r15739 if lfutil.islfilesrepo(repo):
Greg Ward
largefiles: use ui.configlist() to split largefiles.patterns
r15229 lfpats = ui.configlist(lfutil.longname, 'patterns', default=[])
various
hgext: add largefiles extension...
r15168 if lfpats:
lfmatcher = match_.match(repo.root, '', list(lfpats))
lfnames = []
Matt Harbison
largefiles: replace match.bad() monkey patching with match.badmatch()...
r25440 m = matcher
various
hgext: add largefiles extension...
r15168 wctx = repo[None]
Matt Harbison
largefiles: replace match.bad() monkey patching with match.badmatch()...
r25440 for f in repo.walk(match_.badmatch(m, lambda x, y: None)):
various
hgext: add largefiles extension...
r15168 exact = m.exact(f)
lfile = lfutil.standin(f) in wctx
nfile = f in wctx
exists = lfile or nfile
Matt Harbison
largefiles: align the output messages for an added file with core methods...
r23767 # addremove in core gets fancy with the name, add doesn't
if isaddremove:
name = m.uipath(f)
else:
name = m.rel(f)
various
hgext: add largefiles extension...
r15168 # Don't warn the user when they attempt to add a normal tracked file.
# The normal add code will do that for us.
if exact and exists:
if lfile:
Matt Harbison
largefiles: align the output messages for an added file with core methods...
r23767 ui.warn(_('%s already a largefile\n') % name)
various
hgext: add largefiles extension...
r15168 continue
Matt Harbison
largefiles: ensure addlargefiles() doesn't add a standin as a largefile...
r17232 if (exact or not exists) and not lfutil.isstandin(f):
Matt Harbison
largefiles: fix a traceback when addremove follows a remove (issue3507)...
r17231 # In case the file was removed previously, but not committed
# (issue3507)
Matt Harbison
largefiles: convert addlargefiles() to vfs
r23733 if not repo.wvfs.exists(f):
Matt Harbison
largefiles: fix a traceback when addremove follows a remove (issue3507)...
r17231 continue
Greg Ward
largefiles: cosmetics, whitespace, code style...
r15255 abovemin = (lfsize and
Matt Harbison
largefiles: convert addlargefiles() to vfs
r23733 repo.wvfs.lstat(f).st_size >= lfsize * 1024 * 1024)
Greg Ward
largefiles: cosmetics, whitespace, code style...
r15255 if large or abovemin or (lfmatcher and lfmatcher(f)):
various
hgext: add largefiles extension...
r15168 lfnames.append(f)
if ui.verbose or not exact:
Matt Harbison
largefiles: align the output messages for an added file with core methods...
r23767 ui.status(_('adding %s as a largefile\n') % name)
various
hgext: add largefiles extension...
r15168
bad = []
Greg Ward
largefiles: improve comments, internal docstrings...
r15252 # Need to lock, otherwise there could be a race condition between
# when standins are created and added to the repo.
various
hgext: add largefiles extension...
r15168 wlock = repo.wlock()
try:
if not opts.get('dry_run'):
Mads Kiilerich
largefiles: move initialization of standins variable to clarify its "scope"
r23041 standins = []
various
hgext: add largefiles extension...
r15168 lfdirstate = lfutil.openlfdirstate(ui, repo)
for f in lfnames:
standinname = lfutil.standin(f)
lfutil.writestandin(repo, standinname, hash='',
executable=lfutil.getexecutable(repo.wjoin(f)))
standins.append(standinname)
if lfdirstate[f] == 'r':
lfdirstate.normallookup(f)
else:
lfdirstate.add(f)
lfdirstate.write()
Greg Ward
largefiles: cosmetics, whitespace, code style...
r15255 bad += [lfutil.splitstandin(f)
Mads Kiilerich
largefiles: remove trivial portability wrappers
r18154 for f in repo[None].add(standins)
Greg Ward
largefiles: cosmetics, whitespace, code style...
r15255 if f in m.files()]
Matt Harbison
largefiles: return the list of added files from addlargefiles()...
r23768
added = [f for f in lfnames if f not in bad]
various
hgext: add largefiles extension...
r15168 finally:
wlock.release()
Matt Harbison
largefiles: return the list of added files from addlargefiles()...
r23768 return added, bad
various
hgext: add largefiles extension...
r15168
Matt Harbison
largefiles: pass a matcher instead of a raw file list to removelargefiles()...
r23741 def removelargefiles(ui, repo, isaddremove, matcher, **opts):
Na'Tosha Bard
largefiles: fix confusion upon removal of added largefile (issue3176)...
r15786 after = opts.get('after')
Matt Harbison
largefiles: pass a matcher instead of a raw file list to removelargefiles()...
r23741 m = composelargefilematcher(matcher, repo[None].manifest())
various
hgext: add largefiles extension...
r15168 try:
repo.lfstatus = True
Matt Harbison
largefiles: pass a matcher instead of a raw file list to removelargefiles()...
r23741 s = repo.status(match=m, clean=not isaddremove)
various
hgext: add largefiles extension...
r15168 finally:
repo.lfstatus = False
Na'Tosha Bard
largefiles: implement addremove (issue3064)...
r15792 manifest = repo[None].manifest()
Greg Ward
largefiles: cosmetics, whitespace, code style...
r15255 modified, added, deleted, clean = [[f for f in list
if lfutil.standin(f) in manifest]
Martin von Zweigbergk
largefiles: access status fields by name rather than index
r22919 for list in (s.modified, s.added,
s.deleted, s.clean)]
various
hgext: add largefiles extension...
r15168
Mads Kiilerich
largefiles: align rm warnings with warnings used in core
r18066 def warn(files, msg):
various
hgext: add largefiles extension...
r15168 for f in files:
Mads Kiilerich
largefiles: align rm warnings with warnings used in core
r18066 ui.warn(msg % m.rel(f))
Matt Harbison
largefiles: exit from remove with 1 on warnings...
r17576 return int(len(files) > 0)
result = 0
various
hgext: add largefiles extension...
r15168
Na'Tosha Bard
largefiles: fix confusion upon removal of added largefile (issue3176)...
r15786 if after:
Martin von Zweigbergk
largefiles: remove 'forget' list that's always empty
r22630 remove = deleted
Mads Kiilerich
largefiles: align rm warnings with warnings used in core
r18066 result = warn(modified + added + clean,
_('not removing %s: file still exists\n'))
various
hgext: add largefiles extension...
r15168 else:
Martin von Zweigbergk
largefiles: remove 'forget' list that's always empty
r22630 remove = deleted + clean
Mads Kiilerich
largefiles: align rm warnings with warnings used in core
r18066 result = warn(modified, _('not removing %s: file is modified (use -f'
' to force removal)\n'))
result = warn(added, _('not removing %s: file has been marked for add'
' (use forget to undo)\n')) or result
various
hgext: add largefiles extension...
r15168
# Need to lock because standin files are deleted then removed from the
Mads Kiilerich
fix trivial spelling errors
r17424 # repository and we could race in-between.
various
hgext: add largefiles extension...
r15168 wlock = repo.wlock()
try:
lfdirstate = lfutil.openlfdirstate(ui, repo)
Matt Harbison
largefiles: eliminate a duplicate message when removing files in verbose mode...
r23658 for f in sorted(remove):
Matt Harbison
largefiles: align the output messages for a removed file with core methods...
r23766 if ui.verbose or not m.exact(f):
# addremove in core gets fancy with the name, remove doesn't
if isaddremove:
name = m.uipath(f)
else:
name = m.rel(f)
ui.status(_('removing %s\n') % name)
Matt Harbison
largefiles: don't actually remove largefiles in an addremove dry run...
r23592
if not opts.get('dry_run'):
if not after:
util.unlinkpath(repo.wjoin(f), ignoremissing=True)
if opts.get('dry_run'):
return result
various
hgext: add largefiles extension...
r15168 remove = [lfutil.standin(f) for f in remove]
Na'Tosha Bard
largefiles: implement addremove (issue3064)...
r15792 # If this is being called by addremove, let the original addremove
# function handle this.
Mads Kiilerich
largefiles: replace repo._isaddremove hack with a simple function parameter
r23038 if not isaddremove:
Mads Kiilerich
largefiles: remove reporemove portability wrapper
r18153 for f in remove:
util.unlinkpath(repo.wjoin(f), ignoremissing=True)
repo[None].forget(remove)
Matt Harbison
largefiles: properly sync lfdirstate after removing largefiles...
r23721
for f in remove:
lfutil.synclfdirstate(repo, lfdirstate, lfutil.splitstandin(f),
False)
lfdirstate.write()
various
hgext: add largefiles extension...
r15168 finally:
wlock.release()
Matt Harbison
largefiles: exit from remove with 1 on warnings...
r17576 return result
Martin Geisler
largefiles: hide .hglf/ prefix for largefiles in hgweb...
r16449 # For overriding mercurial.hgweb.webcommands so that largefiles will
# appear at their right place in the manifests.
def decodepath(orig, path):
return lfutil.splitstandin(path) or path
Na'Tosha Bard
largefiles: implement addremove (issue3064)...
r15792 # -- Wrappers: modify existing commands --------------------------------
Na'Tosha Bard
largefiles: remove use of underscores that breaks coding convention
r16247 def overrideadd(orig, ui, repo, *pats, **opts):
Matt Harbison
largefiles: cleanup overrideadd()...
r23887 if opts.get('normal') and opts.get('large'):
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_('--normal cannot be used with --large'))
Matt Harbison
largefiles: enable subrepo support for add...
r23886 return orig(ui, repo, *pats, **opts)
def cmdutiladd(orig, ui, repo, matcher, prefix, explicitonly, **opts):
# The --normal flag short circuits this override
if opts.get('normal'):
return orig(ui, repo, matcher, prefix, explicitonly, **opts)
Na'Tosha Bard
largefiles: implement addremove (issue3064)...
r15792
Matt Harbison
largefiles: enable subrepo support for add...
r23886 ladded, lbad = addlargefiles(ui, repo, False, matcher, **opts)
normalmatcher = composenormalfilematcher(matcher, repo[None].manifest(),
ladded)
bad = orig(ui, repo, normalmatcher, prefix, explicitonly, **opts)
bad.extend(f for f in lbad)
return bad
Na'Tosha Bard
largefiles: implement addremove (issue3064)...
r15792
Matt Harbison
largefiles: enable subrepo support for remove...
r23782 def cmdutilremove(orig, ui, repo, matcher, prefix, after, force, subrepos):
normalmatcher = composenormalfilematcher(matcher, repo[None].manifest())
result = orig(ui, repo, normalmatcher, prefix, after, force, subrepos)
return removelargefiles(ui, repo, False, matcher, after=after,
force=force) or result
Na'Tosha Bard
largefiles: implement addremove (issue3064)...
r15792
Matt Harbison
largefiles: fix status -S reporting of subrepos (issue3231)...
r16515 def overridestatusfn(orig, repo, rev2, **opts):
try:
repo._repo.lfstatus = True
return orig(repo, rev2, **opts)
finally:
repo._repo.lfstatus = False
Na'Tosha Bard
largefiles: remove use of underscores that breaks coding convention
r16247 def overridestatus(orig, ui, repo, *pats, **opts):
various
hgext: add largefiles extension...
r15168 try:
repo.lfstatus = True
return orig(ui, repo, *pats, **opts)
finally:
repo.lfstatus = False
Matt Harbison
largefiles: notice dirty large files in a subrepo...
r16516 def overridedirty(orig, repo, ignoreupdate=False):
try:
repo._repo.lfstatus = True
return orig(repo, ignoreupdate)
finally:
repo._repo.lfstatus = False
Na'Tosha Bard
largefiles: remove use of underscores that breaks coding convention
r16247 def overridelog(orig, ui, repo, *pats, **opts):
Pierre-Yves David
largefiles: remove a mutable default argument...
r26339 def overridematchandpats(ctx, pats=(), opts=None, globbed=False,
Matt Harbison
scmutil: add an optional parameter to matcher factories for a bad() override...
r25467 default='relpath', badfn=None):
Mads Kiilerich
largefiles: make log match largefiles in the non-standin location too...
r18341 """Matcher that merges root directory with .hglf, suitable for log.
It is still possible to match .hglf directly.
For any listed files run log on the standin too.
matchfn tries both the given filename and with .hglf stripped.
"""
Pierre-Yves David
largefiles: remove a mutable default argument...
r26339 if opts is None:
opts = {}
Matt Harbison
scmutil: add an optional parameter to matcher factories for a bad() override...
r25467 matchandpats = oldmatchandpats(ctx, pats, opts, globbed, default,
badfn=badfn)
Lucas Moscovicz
largefiles: changed overridelog to work with graphlog...
r21110 m, p = copy.copy(matchandpats)
Siddharth Agarwal
largefiles: don't override matchandpats for always matchers (issue4334)...
r22170 if m.always():
# We want to match everything anyway, so there's no benefit trying
# to add standins.
return matchandpats
Lucas Moscovicz
largefiles: changed overridelog to work with graphlog...
r21110 pats = set(p)
Matt Harbison
largefiles: teach log to handle patterns...
r24206
def fixpats(pat, tostandin=lfutil.standin):
Matt Harbison
largefiles: don't mangle filesets when fixing up the log matcher...
r24813 if pat.startswith('set:'):
return pat
Matt Harbison
largefiles: teach log to handle patterns...
r24206 kindpat = match_._patsplit(pat, None)
if kindpat[0] is not None:
return kindpat[0] + ':' + tostandin(kindpat[1])
return tostandin(kindpat[1])
Lucas Moscovicz
largefiles: changed overridelog to work with graphlog...
r21110 if m._cwd:
Matt Harbison
largefiles: handle logging from outside the repo...
r24208 hglf = lfutil.shortname
back = util.pconvert(m.rel(hglf)[:-len(hglf)])
Matt Harbison
largefiles: teach log to handle patterns...
r24206
def tostandin(f):
Mads Kiilerich
spelling: trivial spell checking
r26781 # The file may already be a standin, so truncate the back
Matt Harbison
largefiles: handle logging from outside the repo...
r24208 # prefix and test before mangling it. This avoids turning
Matt Harbison
largefiles: don't prefix standin patterns with '.hglf' when logging...
r24207 # 'glob:../.hglf/foo*' into 'glob:../.hglf/../.hglf/foo*'.
if f.startswith(back) and lfutil.splitstandin(f[len(back):]):
return f
Matt Harbison
largefiles: handle logging from outside the repo...
r24208 # An absolute path is from outside the repo, so truncate the
# path to the root before building the standin. Otherwise cwd
# is somewhere in the repo, relative to root, and needs to be
# prepended before building the standin.
if os.path.isabs(m._cwd):
f = f[len(back):]
else:
f = m._cwd + '/' + f
return back + lfutil.standin(f)
Matt Harbison
largefiles: teach log to handle patterns...
r24206
pats.update(fixpats(f, tostandin) for f in p)
Lucas Moscovicz
largefiles: changed overridelog to work with graphlog...
r21110 else:
Matt Harbison
largefiles: don't prefix standin patterns with '.hglf' when logging...
r24207 def tostandin(f):
if lfutil.splitstandin(f):
return f
return lfutil.standin(f)
pats.update(fixpats(f, tostandin) for f in p)
Lucas Moscovicz
largefiles: changed overridelog to work with graphlog...
r21110
Wei, Elson
largefiles: overridematch() should replace the file path instead of extending (issue3934)
r19472 for i in range(0, len(m._files)):
Matt Harbison
largefiles: teach log to handle patterns...
r24206 # Don't add '.hglf' to m.files, since that is already covered by '.'
if m._files[i] == '.':
continue
Wei, Elson
largefiles: overridematch() should replace the file path instead of extending (issue3934)
r19472 standin = lfutil.standin(m._files[i])
Matt Harbison
largefiles: don't interfere with logging normal files...
r23976 # If the "standin" is a directory, append instead of replace to
# support naming a directory on the command line with only
# largefiles. The original directory is kept to support normal
# files.
Wei, Elson
largefiles: overridematch() should replace the file path instead of extending (issue3934)
r19472 if standin in repo[ctx.node()]:
m._files[i] = standin
Matt Harbison
largefiles: don't interfere with logging normal files...
r23976 elif m._files[i] not in repo[ctx.node()] \
and repo.wvfs.isdir(standin):
Mads Kiilerich
largefiles: include largefiles when doing log on a directory (issue4241)...
r21275 m._files.append(standin)
Lucas Moscovicz
largefiles: changed overridelog to work with graphlog...
r21110
Drew Gottlieb
match: rename _fmap to _fileroots for clarity...
r25189 m._fileroots = set(m._files)
Siddharth Agarwal
largefiles: fix _always for match overrides...
r18813 m._always = False
Mads Kiilerich
largefiles: make log match largefiles in the non-standin location too...
r18341 origmatchfn = m.matchfn
def lfmatchfn(f):
lf = lfutil.splitstandin(f)
if lf is not None and origmatchfn(lf):
return True
r = origmatchfn(f)
return r
m.matchfn = lfmatchfn
Lucas Moscovicz
largefiles: changed overridelog to work with graphlog...
r21110
Matt Harbison
largefiles: don't prefix standin patterns with '.hglf' when logging...
r24207 ui.debug('updated patterns: %s\n' % sorted(pats))
Lucas Moscovicz
largefiles: changed overridelog to work with graphlog...
r21110 return m, pats
Siddharth Agarwal
largefiles: in overridelog, use non-lf matcher for patch generation (issue4334)...
r22169 # For hg log --patch, the match object is used in two different senses:
# (1) to determine what revisions should be printed out, and
# (2) to determine what files to print out diffs for.
# The magic matchandpats override should be used for case (1) but not for
# case (2).
Matt Harbison
scmutil: add an optional parameter to matcher factories for a bad() override...
r25467 def overridemakelogfilematcher(repo, pats, opts, badfn=None):
Martin von Zweigbergk
log: prefer 'wctx' over 'pctx' for working context
r24534 wctx = repo[None]
Matt Harbison
scmutil: add an optional parameter to matcher factories for a bad() override...
r25467 match, pats = oldmatchandpats(wctx, pats, opts, badfn=badfn)
Siddharth Agarwal
largefiles: in overridelog, use non-lf matcher for patch generation (issue4334)...
r22169 return lambda rev: match
Lucas Moscovicz
largefiles: changed overridelog to work with graphlog...
r21110 oldmatchandpats = installmatchandpatsfn(overridematchandpats)
Siddharth Agarwal
largefiles: in overridelog, use non-lf matcher for patch generation (issue4334)...
r22169 oldmakelogfilematcher = cmdutil._makenofollowlogfilematcher
setattr(cmdutil, '_makenofollowlogfilematcher', overridemakelogfilematcher)
various
hgext: add largefiles extension...
r15168 try:
Matt Harbison
largefiles: preserve the exit status of the log command
r17577 return orig(ui, repo, *pats, **opts)
various
hgext: add largefiles extension...
r15168 finally:
Lucas Moscovicz
largefiles: changed overridelog to work with graphlog...
r21110 restorematchandpatsfn()
Siddharth Agarwal
largefiles: in overridelog, use non-lf matcher for patch generation (issue4334)...
r22169 setattr(cmdutil, '_makenofollowlogfilematcher', oldmakelogfilematcher)
various
hgext: add largefiles extension...
r15168
Na'Tosha Bard
largefiles: remove use of underscores that breaks coding convention
r16247 def overrideverify(orig, ui, repo, *pats, **opts):
various
hgext: add largefiles extension...
r15168 large = opts.pop('large', False)
all = opts.pop('lfa', False)
contents = opts.pop('lfc', False)
result = orig(ui, repo, *pats, **opts)
Mads Kiilerich
largefiles: make verify --lfa and --lfc work without --large...
r18547 if large or all or contents:
various
hgext: add largefiles extension...
r15168 result = result or lfcommands.verifylfiles(ui, repo, all, contents)
return result
Mads Kiilerich
largefiles: introduce basic debugstate --large functionality...
r18144 def overridedebugstate(orig, ui, repo, *pats, **opts):
large = opts.pop('large', False)
if large:
Mads Kiilerich
largefiles: full debugdirstate functionality for largefiles...
r21088 class fakerepo(object):
dirstate = lfutil.openlfdirstate(ui, repo)
orig(ui, fakerepo, *pats, **opts)
Mads Kiilerich
largefiles: introduce basic debugstate --large functionality...
r18144 else:
orig(ui, repo, *pats, **opts)
Martin Geisler
largefiles: handle merges between normal files and largefiles (issue3084)...
r15663 # Before starting the manifest merge, merge.updates will call
Mads Kiilerich
spelling: fixes from proofreading of spell checker issues
r23543 # _checkunknownfile to check if there are any files in the merged-in
Martin Geisler
largefiles: handle merges between normal files and largefiles (issue3084)...
r15663 # changeset that collide with unknown files in the working copy.
#
# The largefiles are seen as unknown, so this prevents us from merging
# in a file 'foo' if we already have a largefile with the same name.
#
# The overridden function filters the unknown files by removing any
# largefiles. This makes the merge proceed and we can then handle this
Martin von Zweigbergk
largefiles: update comments to refer to the right overridden method...
r23307 # case further in the overridden calculateupdates function below.
Martin von Zweigbergk
merge: don't overwrite untracked file at directory rename target...
r23653 def overridecheckunknownfile(origfn, repo, wctx, mctx, f, f2=None):
FUJIWARA Katsunori
largefiles: check unknown files with case awareness of the filesystem...
r19161 if lfutil.standin(repo.dirstate.normalize(f)) in wctx:
Matt Mackall
merge: refactor unknown file conflict checking...
r16093 return False
Martin von Zweigbergk
merge: don't overwrite untracked file at directory rename target...
r23653 return origfn(repo, wctx, mctx, f, f2)
Martin Geisler
largefiles: handle merges between normal files and largefiles (issue3084)...
r15663
# The manifest merge handles conflicts on the manifest level. We want
# to handle changes in largefile-ness of files at this level too.
#
Martin von Zweigbergk
largefiles: update comments to refer to the right overridden method...
r23307 # The strategy is to run the original calculateupdates and then process
Martin Geisler
largefiles: handle merges between normal files and largefiles (issue3084)...
r15663 # the action list it outputs. There are two cases we need to deal with:
#
# 1. Normal file in p1, largefile in p2. Here the largefile is
# detected via its standin file, which will enter the working copy
# with a "get" action. It is not "merge" since the standin is all
# Mercurial is concerned with at this level -- the link to the
# existing normal file is not relevant here.
#
# 2. Largefile in p1, normal file in p2. Here we get a "merge" action
# since the largefile will be present in the working copy and
# different from the normal file in p2. Mercurial therefore
# triggers a merge action.
#
# In both cases, we prompt the user and emit new actions to either
# remove the standin (if the normal file was kept) or to remove the
# normal file and get the standin (if the largefile was kept). The
# default prompt answer is to use the largefile version since it was
# presumably changed on purpose.
#
# Finally, the merge.applyupdates function will then take care of
# writing the files into the working copy and lfcommands.updatelfiles
# will update the largefiles.
Mads Kiilerich
merge: pass merge ancestor to calculateupdates as a list...
r21081 def overridecalculateupdates(origfn, repo, p1, p2, pas, branchmerge, force,
Augie Fackler
merge: restate calculateupdates in terms of a matcher...
r27345 acceptremote, followcopies, matcher=None):
Siddharth Agarwal
manifestmerge: pass in branchmerge and force separately...
r18605 overwrite = force and not branchmerge
Martin von Zweigbergk
merge: don't treat 'diverge' and 'renamedelete' like actions...
r23526 actions, diverge, renamedelete = origfn(
Augie Fackler
merge: restate calculateupdates in terms of a matcher...
r27345 repo, p1, p2, pas, branchmerge, force, acceptremote,
followcopies, matcher=matcher)
Mads Kiilerich
largefiles: don't process merge actions at all when overwriting
r19952
if overwrite:
Martin von Zweigbergk
merge: don't treat 'diverge' and 'renamedelete' like actions...
r23526 return actions, diverge, renamedelete
Martin Geisler
largefiles: handle merges between normal files and largefiles (issue3084)...
r15663
Martin von Zweigbergk
largefiles: rewrite merge code using dictionary with entry per file...
r23529 # Convert to dictionary with filename as key and action as value.
Martin von Zweigbergk
largefiles: start by finding files of interest...
r23530 lfiles = set()
Martin von Zweigbergk
largefiles: don't duplicate 'actions' into 'actionbyfile'
r23642 for f in actions:
Mads Kiilerich
largefiles: don't crash on 'local renamed directory' actions...
r20148 splitstandin = f and lfutil.splitstandin(f)
Martin von Zweigbergk
merge: make calculateupdates() return file->action dict...
r23641 if splitstandin in p1:
lfiles.add(splitstandin)
elif lfutil.standin(f) in p1:
lfiles.add(f)
Martin Geisler
largefiles: handle merges between normal files and largefiles (issue3084)...
r15663
Martin von Zweigbergk
largefiles: start by finding files of interest...
r23530 for lfile in lfiles:
standin = lfutil.standin(lfile)
Martin von Zweigbergk
largefiles: don't duplicate 'actions' into 'actionbyfile'
r23642 (lm, largs, lmsg) = actions.get(lfile, (None, None, None))
(sm, sargs, smsg) = actions.get(standin, (None, None, None))
Martin von Zweigbergk
merge: move cd/dc prompts after largefiles prompts...
r23541 if sm in ('g', 'dc') and lm != 'r':
Siddharth Agarwal
merge: make 'cd' and 'dc' actions store the same arguments as 'm'...
r26962 if sm == 'dc':
f1, f2, fa, move, anc = sargs
sargs = (p2[f2].flags(),)
Martin Geisler
largefiles: handle merges between normal files and largefiles (issue3084)...
r15663 # Case 1: normal file in the working copy, largefile in
# the second parent
Martin von Zweigbergk
largefiles: don't clobber merge action message with user message...
r23470 usermsg = _('remote turned local normal file %s into a largefile\n'
'use (l)argefile or keep (n)ormal file?'
'$$ &Largefile $$ &Normal file') % lfile
Martin von Zweigbergk
largefiles: remove redundant checks for false modify/delete conflicts...
r23483 if repo.ui.promptchoice(usermsg, 0) == 0: # pick remote largefile
Martin von Zweigbergk
largefiles: don't duplicate 'actions' into 'actionbyfile'
r23642 actions[lfile] = ('r', None, 'replaced by standin')
actions[standin] = ('g', sargs, 'replaces standin')
Mads Kiilerich
largefiles: don't show largefile/normal prompts if one side is unchanged
r23419 else: # keep local normal file
Martin von Zweigbergk
largefiles: don't duplicate 'actions' into 'actionbyfile'
r23642 actions[lfile] = ('k', None, 'replaces standin')
Martin von Zweigbergk
largefiles: don't use 'r' action for standin that doesn't exist...
r23493 if branchmerge:
Martin von Zweigbergk
largefiles: don't duplicate 'actions' into 'actionbyfile'
r23642 actions[standin] = ('k', None, 'replaced by non-standin')
Martin von Zweigbergk
largefiles: don't use 'r' action for standin that doesn't exist...
r23493 else:
Martin von Zweigbergk
largefiles: don't duplicate 'actions' into 'actionbyfile'
r23642 actions[standin] = ('r', None, 'replaced by non-standin')
Martin von Zweigbergk
merge: move cd/dc prompts after largefiles prompts...
r23541 elif lm in ('g', 'dc') and sm != 'r':
Siddharth Agarwal
merge: make 'cd' and 'dc' actions store the same arguments as 'm'...
r26962 if lm == 'dc':
f1, f2, fa, move, anc = largs
largs = (p2[f2].flags(),)
Martin Geisler
largefiles: handle merges between normal files and largefiles (issue3084)...
r15663 # Case 2: largefile in the working copy, normal file in
# the second parent
Martin von Zweigbergk
largefiles: don't clobber merge action message with user message...
r23470 usermsg = _('remote turned local largefile %s into a normal file\n'
Mads Kiilerich
largefiles: use 'remote'/'local' in merge prompts like in other merge prompts...
r19967 'keep (l)argefile or use (n)ormal file?'
Matt Mackall
ui: merge prompt text components into a singe string...
r19226 '$$ &Largefile $$ &Normal file') % lfile
Martin von Zweigbergk
largefiles: remove redundant checks for false modify/delete conflicts...
r23483 if repo.ui.promptchoice(usermsg, 0) == 0: # keep local largefile
FUJIWARA Katsunori
largefiles: keep largefiles from colliding with normal one during linear merge...
r22196 if branchmerge:
# largefile can be restored from standin safely
Martin von Zweigbergk
largefiles: don't duplicate 'actions' into 'actionbyfile'
r23642 actions[lfile] = ('k', None, 'replaced by standin')
actions[standin] = ('k', None, 'replaces standin')
FUJIWARA Katsunori
largefiles: keep largefiles from colliding with normal one during linear merge...
r22196 else:
# "lfile" should be marked as "removed" without
# removal of itself
Martin von Zweigbergk
largefiles: don't duplicate 'actions' into 'actionbyfile'
r23642 actions[lfile] = ('lfmr', None,
'forget non-standin largefile')
FUJIWARA Katsunori
largefiles: keep largefiles from colliding with normal one during linear merge...
r22196
# linear-merge should treat this largefile as 're-added'
Martin von Zweigbergk
largefiles: don't duplicate 'actions' into 'actionbyfile'
r23642 actions[standin] = ('a', None, 'keep standin')
Mads Kiilerich
largefiles: don't show largefile/normal prompts if one side is unchanged
r23419 else: # pick remote normal file
Martin von Zweigbergk
largefiles: don't duplicate 'actions' into 'actionbyfile'
r23642 actions[lfile] = ('g', largs, 'replaces standin')
actions[standin] = ('r', None, 'replaced by non-standin')
Martin Geisler
largefiles: handle merges between normal files and largefiles (issue3084)...
r15663
Martin von Zweigbergk
largefiles: don't duplicate 'actions' into 'actionbyfile'
r23642 return actions, diverge, renamedelete
Martin Geisler
largefiles: handle merges between normal files and largefiles (issue3084)...
r15663
FUJIWARA Katsunori
largefiles: keep largefiles from colliding with normal one during linear merge...
r22196 def mergerecordupdates(orig, repo, actions, branchmerge):
if 'lfmr' in actions:
Mads Kiilerich
largefiles: mark lfile as added in lfdirstate when the standin is added...
r23695 lfdirstate = lfutil.openlfdirstate(repo.ui, repo)
FUJIWARA Katsunori
largefiles: keep largefiles from colliding with normal one during linear merge...
r22196 for lfile, args, msg in actions['lfmr']:
Mads Kiilerich
largefiles: mark lfile as added in lfdirstate when the standin is added...
r23695 # this should be executed before 'orig', to execute 'remove'
# before all other actions
FUJIWARA Katsunori
largefiles: keep largefiles from colliding with normal one during linear merge...
r22196 repo.dirstate.remove(lfile)
Mads Kiilerich
largefiles: mark lfile as added in lfdirstate when the standin is added...
r23695 # make sure lfile doesn't get synclfdirstate'd as normal
lfdirstate.add(lfile)
lfdirstate.write()
FUJIWARA Katsunori
largefiles: keep largefiles from colliding with normal one during linear merge...
r22196
return orig(repo, actions, branchmerge)
Greg Ward
largefiles: improve comments, internal docstrings...
r15252 # Override filemerge to prompt the user about how they wish to merge
Mads Kiilerich
largefiles: drop redundant special handling of merges of renames...
r20295 # largefiles. This will handle identical edits without prompting the user.
Siddharth Agarwal
filemerge: introduce a premerge flag and function...
r26607 def overridefilemerge(origfn, premerge, repo, mynode, orig, fcd, fco, fca,
labels=None):
Siddharth Agarwal
largefiles: fall back to the original for change/delete conflicts...
r27050 if not lfutil.isstandin(orig) or fcd.isabsent() or fco.isabsent():
Siddharth Agarwal
filemerge: introduce a premerge flag and function...
r26607 return origfn(premerge, repo, mynode, orig, fcd, fco, fca,
labels=labels)
Mads Kiilerich
largefiles: stylistic cleanup of filemerge
r20298
Mads Kiilerich
largefiles: don't prompt when one side of merge was changed but didn't change...
r20994 ahash = fca.data().strip().lower()
dhash = fcd.data().strip().lower()
ohash = fco.data().strip().lower()
if (ohash != ahash and
ohash != dhash and
(dhash == ahash or
repo.ui.promptchoice(
_('largefile %s has a merge conflict\nancestor was %s\n'
'keep (l)ocal %s or\ntake (o)ther %s?'
'$$ &Local $$ &Other') %
(lfutil.splitstandin(orig), ahash, dhash, ohash),
0) == 1)):
Mads Kiilerich
largefiles: stylistic cleanup of filemerge
r20298 repo.wwrite(fcd.path(), fco.data(), fco.flags())
Siddharth Agarwal
filemerge: return whether the file was deleted...
r27034 return True, 0, False
various
hgext: add largefiles extension...
r15168
Durham Goode
copies: add matcher parameter to copy logic...
r24782 def copiespathcopies(orig, ctx1, ctx2, match=None):
copies = orig(ctx1, ctx2, match=match)
Matt Harbison
largefiles: report the source of copied/moved largefiles in status -C...
r24230 updated = {}
for k, v in copies.iteritems():
updated[lfutil.splitstandin(k) or k] = lfutil.splitstandin(v) or v
return updated
Greg Ward
largefiles: improve comments, internal docstrings...
r15252 # Copy first changes the matchers to match standins instead of
# largefiles. Then it overrides util.copyfile in that function it
# checks if the destination largefile already exists. It also keeps a
# list of copied files so that the largefiles can be copied and the
# dirstate updated.
Na'Tosha Bard
largefiles: remove use of underscores that breaks coding convention
r16247 def overridecopy(orig, ui, repo, pats, opts, rename=False):
Greg Ward
largefiles: improve comments, internal docstrings...
r15252 # doesn't remove largefile on rename
various
hgext: add largefiles extension...
r15168 if len(pats) < 2:
# this isn't legal, let the original function deal with it
return orig(ui, repo, pats, opts, rename)
Greg Ward
largefiles: more work on cleaning up comments...
r15254 # This could copy both lfiles and normal files in one command,
# but we don't want to do that. First replace their matcher to
# only match normal files and run it, then replace it to just
# match largefiles and run it again.
various
hgext: add largefiles extension...
r15168 nonormalfiles = False
nolfiles = False
Mads Kiilerich
largefiles: copy override, install matchfn outside the try/except restoring it
r21091 installnormalfilesmatchfn(repo[None].manifest())
various
hgext: add largefiles extension...
r15168 try:
Matt Mackall
largefiles: use try/except/finally
r25079 result = orig(ui, repo, pats, opts, rename)
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 except error.Abort as e:
Matt Mackall
largefiles: use try/except/finally
r25079 if str(e) != _('no files to copy'):
raise e
else:
nonormalfiles = True
result = 0
various
hgext: add largefiles extension...
r15168 finally:
restorematchfn()
# The first rename can cause our current working directory to be removed.
# In that case there is nothing left to copy/rename so just quit.
try:
repo.getcwd()
except OSError:
return result
Matt Harbison
largefiles: use the core file copy logic to validate the destination path...
r24006 def makestandin(relpath):
path = pathutil.canonpath(repo.root, repo.getcwd(), relpath)
return os.path.join(repo.wjoin(lfutil.standin(path)))
fullpats = scmutil.expandpats(pats)
dest = fullpats[-1]
if os.path.isdir(dest):
if not os.path.isdir(makestandin(dest)):
os.makedirs(makestandin(dest))
various
hgext: add largefiles extension...
r15168 try:
Matt Mackall
largefiles: use try/except/finally
r25079 # When we call orig below it creates the standins but we don't add
# them to the dir state until later so lock during that time.
wlock = repo.wlock()
various
hgext: add largefiles extension...
r15168
Matt Mackall
largefiles: use try/except/finally
r25079 manifest = repo[None].manifest()
Pierre-Yves David
largefiles: remove a mutable default argument...
r26341 def overridematch(ctx, pats=(), opts=None, globbed=False,
Matt Harbison
scmutil: add an optional parameter to matcher factories for a bad() override...
r25467 default='relpath', badfn=None):
Pierre-Yves David
largefiles: remove a mutable default argument...
r26341 if opts is None:
opts = {}
Matt Mackall
largefiles: use try/except/finally
r25079 newpats = []
# The patterns were previously mangled to add the standin
# directory; we need to remove that now
various
hgext: add largefiles extension...
r15168 for pat in pats:
Matt Mackall
largefiles: use try/except/finally
r25079 if match_.patkind(pat) is None and lfutil.shortname in pat:
newpats.append(pat.replace(lfutil.shortname, ''))
various
hgext: add largefiles extension...
r15168 else:
Matt Mackall
largefiles: use try/except/finally
r25079 newpats.append(pat)
Matt Harbison
scmutil: add an optional parameter to matcher factories for a bad() override...
r25467 match = oldmatch(ctx, newpats, opts, globbed, default, badfn=badfn)
Matt Mackall
largefiles: use try/except/finally
r25079 m = copy.copy(match)
lfile = lambda f: lfutil.standin(f) in manifest
m._files = [lfutil.standin(f) for f in m._files if lfile(f)]
Drew Gottlieb
match: rename _fmap to _fileroots for clarity...
r25189 m._fileroots = set(m._files)
Matt Mackall
largefiles: use try/except/finally
r25079 origmatchfn = m.matchfn
m.matchfn = lambda f: (lfutil.isstandin(f) and
(f in manifest) and
origmatchfn(lfutil.splitstandin(f)) or
None)
return m
oldmatch = installmatchfn(overridematch)
listpats = []
for pat in pats:
if match_.patkind(pat) is not None:
listpats.append(pat)
else:
listpats.append(makestandin(pat))
various
hgext: add largefiles extension...
r15168
Matt Mackall
largefiles: use try/except/finally
r25079 try:
origcopyfile = util.copyfile
copiedfiles = []
def overridecopyfile(src, dest):
Na'Tosha Bard
largefiles: fix rename (issue3093)
r15598 if (lfutil.shortname in src and
dest.startswith(repo.wjoin(lfutil.shortname))):
Matt Mackall
largefiles: use try/except/finally
r25079 destlfile = dest.replace(lfutil.shortname, '')
if not opts['force'] and os.path.exists(destlfile):
raise IOError('',
_('destination largefile already exists'))
copiedfiles.append((src, dest))
origcopyfile(src, dest)
util.copyfile = overridecopyfile
result += orig(ui, repo, listpats, opts, rename)
finally:
util.copyfile = origcopyfile
Matt Harbison
largefiles: remove directories emptied after their files are moved (issue3515)
r21196
Matt Mackall
largefiles: use try/except/finally
r25079 lfdirstate = lfutil.openlfdirstate(ui, repo)
for (src, dest) in copiedfiles:
if (lfutil.shortname in src and
dest.startswith(repo.wjoin(lfutil.shortname))):
srclfile = src.replace(repo.wjoin(lfutil.standin('')), '')
destlfile = dest.replace(repo.wjoin(lfutil.standin('')), '')
destlfiledir = os.path.dirname(repo.wjoin(destlfile)) or '.'
if not os.path.isdir(destlfiledir):
os.makedirs(destlfiledir)
if rename:
os.rename(repo.wjoin(srclfile), repo.wjoin(destlfile))
Matt Harbison
largefiles: fix path handling for cp/mv (issue3516)...
r17245
Matt Mackall
largefiles: use try/except/finally
r25079 # The file is gone, but this deletes any empty parent
# directories as a side-effect.
util.unlinkpath(repo.wjoin(srclfile), True)
lfdirstate.remove(srclfile)
else:
util.copyfile(repo.wjoin(srclfile),
repo.wjoin(destlfile))
lfdirstate.add(destlfile)
lfdirstate.write()
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 except error.Abort as e:
Matt Mackall
largefiles: use try/except/finally
r25079 if str(e) != _('no files to copy'):
raise e
else:
nolfiles = True
various
hgext: add largefiles extension...
r15168 finally:
restorematchfn()
wlock.release()
if nolfiles and nonormalfiles:
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_('no files to copy'))
various
hgext: add largefiles extension...
r15168
return result
Greg Ward
largefiles: more work on cleaning up comments...
r15254 # When the user calls revert, we have to be careful to not revert any
# changes to other largefiles accidentally. This means we have to keep
# track of the largefiles that are being reverted so we only pull down
# the necessary largefiles.
various
hgext: add largefiles extension...
r15168 #
Greg Ward
largefiles: more work on cleaning up comments...
r15254 # Standins are only updated (to match the hash of largefiles) before
# commits. Update the standins then run the original revert, changing
# the matcher to hit standins instead of largefiles. Based on the
Mads Kiilerich
largefiles: simplify revert - use getstandinsstate like other commands do
r21094 # resulting standins update the largefiles.
Martin von Zweigbergk
largefiles: override cmdutil.revert() instead of comands.revert()...
r24436 def overriderevert(orig, ui, repo, ctx, parents, *pats, **opts):
Greg Ward
largefiles: more work on cleaning up comments...
r15254 # Because we put the standins in a bad state (by updating them)
# and then return them to a correct state we need to lock to
# prevent others from changing them in their incorrect state.
various
hgext: add largefiles extension...
r15168 wlock = repo.wlock()
try:
lfdirstate = lfutil.openlfdirstate(ui, repo)
Mads Kiilerich
largefiles: remove confusing rev parameter for lfdirstatestatus...
r23039 s = lfutil.lfdirstatestatus(lfdirstate, repo)
Mads Kiilerich
largefiles revert: update lfdirstate with result from first cleanliness check...
r18140 lfdirstate.write()
Martin von Zweigbergk
largefiles: access status fields by name rather than index
r22919 for lfile in s.modified:
various
hgext: add largefiles extension...
r15168 lfutil.updatestandin(repo, lfutil.standin(lfile))
Martin von Zweigbergk
largefiles: access status fields by name rather than index
r22919 for lfile in s.deleted:
Na'Tosha Bard
largefiles: fix deletion of multiple missing largefiles (issue3329)
r16638 if (os.path.exists(repo.wjoin(lfutil.standin(lfile)))):
os.unlink(repo.wjoin(lfutil.standin(lfile)))
various
hgext: add largefiles extension...
r15168
Mads Kiilerich
largefiles: simplify revert - use getstandinsstate like other commands do
r21094 oldstandins = lfutil.getstandinsstate(repo)
Pierre-Yves David
largefiles: remove a mutable default argument...
r26343 def overridematch(mctx, pats=(), opts=None, globbed=False,
Matt Harbison
scmutil: add an optional parameter to matcher factories for a bad() override...
r25467 default='relpath', badfn=None):
Pierre-Yves David
largefiles: remove a mutable default argument...
r26343 if opts is None:
opts = {}
Matt Harbison
scmutil: add an optional parameter to matcher factories for a bad() override...
r25467 match = oldmatch(mctx, pats, opts, globbed, default, badfn=badfn)
Mads Kiilerich
largefiles: revert override, install matchfn outside the try/except restoring it
r21095 m = copy.copy(match)
Matt Harbison
largefiles: don't warn when reverting a forgotten largefile...
r24133
# revert supports recursing into subrepos, and though largefiles
# currently doesn't work correctly in that case, this match is
# called, so the lfdirstate above may not be the correct one for
# this invocation of match.
Martin von Zweigbergk
largefiles: override cmdutil.revert() instead of comands.revert()...
r24436 lfdirstate = lfutil.openlfdirstate(mctx.repo().ui, mctx.repo(),
False)
Matt Harbison
largefiles: don't warn when reverting a forgotten largefile...
r24133
Mads Kiilerich
largefiles: revert override, install matchfn outside the try/except restoring it
r21095 def tostandin(f):
Martin von Zweigbergk
largefiles: extract and reuse 'standin' variable in overriderevert()
r24437 standin = lfutil.standin(f)
Martin von Zweigbergk
revert: evaluate filesets against working directory (issue4497)...
r24438 if standin in ctx or standin in mctx:
Martin von Zweigbergk
largefiles: extract and reuse 'standin' variable in overriderevert()
r24437 return standin
elif standin in repo[None] or lfdirstate[f] == 'r':
Mads Kiilerich
largefiles: revert override, install matchfn outside the try/except restoring it
r21095 return None
return f
m._files = [tostandin(f) for f in m._files]
m._files = [f for f in m._files if f is not None]
Drew Gottlieb
match: rename _fmap to _fileroots for clarity...
r25189 m._fileroots = set(m._files)
Mads Kiilerich
largefiles: revert override, install matchfn outside the try/except restoring it
r21095 origmatchfn = m.matchfn
def matchfn(f):
if lfutil.isstandin(f):
return (origmatchfn(lfutil.splitstandin(f)) and
Martin von Zweigbergk
revert: evaluate filesets against working directory (issue4497)...
r24438 (f in ctx or f in mctx))
Mads Kiilerich
largefiles: revert override, install matchfn outside the try/except restoring it
r21095 return origmatchfn(f)
m.matchfn = matchfn
return m
oldmatch = installmatchfn(overridematch)
various
hgext: add largefiles extension...
r15168 try:
Martin von Zweigbergk
largefiles: override cmdutil.revert() instead of comands.revert()...
r24436 orig(ui, repo, ctx, parents, *pats, **opts)
various
hgext: add largefiles extension...
r15168 finally:
restorematchfn()
Greg Ward
largefiles: more work on cleaning up comments...
r15254
Mads Kiilerich
largefiles: simplify revert - use getstandinsstate like other commands do
r21094 newstandins = lfutil.getstandinsstate(repo)
filelist = lfutil.getlfilestoupdate(oldstandins, newstandins)
FUJIWARA Katsunori
largefiles: use "normallookup" on "lfdirstate" while reverting...
r21934 # lfdirstate should be 'normallookup'-ed for updated files,
# because reverting doesn't touch dirstate for 'normal' files
# when target revision is explicitly specified: in such case,
# 'n' and valid timestamp in dirstate doesn't ensure 'clean'
# of target (standin) file.
lfcommands.updatelfiles(ui, repo, filelist, printmessage=False,
normallookup=True)
Mads Kiilerich
largefiles: simplify revert - use getstandinsstate like other commands do
r21094
various
hgext: add largefiles extension...
r15168 finally:
wlock.release()
FUJIWARA Katsunori
largefiles: remove meaningless code path for "hg pull --rebase"...
r23183 # after pulling changesets, we need to take some extra care to get
# largefiles updated remotely
Na'Tosha Bard
largefiles: remove use of underscores that breaks coding convention
r16247 def overridepull(orig, ui, repo, source=None, **opts):
Na'Tosha Bard
largefiles: add --all-largefiles flag to pull
r16692 revsprepull = len(repo)
Mads Kiilerich
largefiles: refactor overridepull internals
r18977 if not source:
source = 'default'
repo.lfpullsource = source
FUJIWARA Katsunori
largefiles: remove meaningless code path for "hg pull --rebase"...
r23183 result = orig(ui, repo, source, **opts)
Mads Kiilerich
largefiles: refactor overridepull internals
r18977 revspostpull = len(repo)
Mads Kiilerich
largefiles: implement pull --all-largefiles as a special case of --lfrev
r18981 lfrevs = opts.get('lfrev', [])
Na'Tosha Bard
largefiles: add --all-largefiles flag to pull
r16692 if opts.get('all_largefiles'):
Mads Kiilerich
largefiles: implement pull --all-largefiles as a special case of --lfrev
r18981 lfrevs.append('pulled()')
Mads Kiilerich
largefiles: introduce pull --lfrev option...
r18978 if lfrevs and revspostpull > revsprepull:
numcached = 0
Mads Kiilerich
largefiles: introduce pulled() revset expression for use in --lfrev...
r18979 repo.firstpulled = revsprepull # for pulled() revset expression
try:
for rev in scmutil.revrange(repo, lfrevs):
ui.note(_('pulling largefiles for revision %s\n') % rev)
(cached, missing) = lfcommands.cachelfiles(ui, repo, rev)
numcached += len(cached)
finally:
del repo.firstpulled
Mads Kiilerich
largefiles: introduce pull --lfrev option...
r18978 ui.status(_("%d largefiles cached\n") % numcached)
various
hgext: add largefiles extension...
r15168 return result
FUJIWARA Katsunori
revset: use delayregistrar to register predicate in extension easily...
r27586 revsetpredicate = revset.extpredicate()
@revsetpredicate('pulled()')
Mads Kiilerich
largefiles: introduce pulled() revset expression for use in --lfrev...
r18979 def pulledrevsetsymbol(repo, subset, x):
FUJIWARA Katsunori
revset: use delayregistrar to register predicate in extension easily...
r27586 """Changesets that just has been pulled.
Mads Kiilerich
largefiles: introduce pulled() revset expression for use in --lfrev...
r18979
Only available with largefiles from pull --lfrev expressions.
.. container:: verbose
Some examples:
- pull largefiles for all new changesets::
hg pull -lfrev "pulled()"
- pull largefiles for all new branch heads::
hg pull -lfrev "head(pulled()) and not closed()"
"""
try:
firstpulled = repo.firstpulled
except AttributeError:
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_("pulled() only available in --lfrev"))
Lucas Moscovicz
hgext: updated extensions to return a baseset when adding symbols
r20442 return revset.baseset([r for r in subset if r >= firstpulled])
Mads Kiilerich
largefiles: introduce pulled() revset expression for use in --lfrev...
r18979
Na'Tosha Bard
largefiles: add --all-largefiles flag to clone (issue3188)
r16644 def overrideclone(orig, ui, source, dest=None, **opts):
Matt Harbison
largefiles: don't convert dest=None to dest=hg.defaultdest() in clone command...
r17600 d = dest
if d is None:
d = hg.defaultdest(source)
if opts.get('all_largefiles') and not hg.islocal(d):
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_(
FUJIWARA Katsunori
i18n: fix "% inside _()" problem
r21096 '--all-largefiles is incompatible with non-local destination %s') %
d)
Matt Harbison
largefiles: delegate to the wrapped clone command...
r17601
return orig(ui, source, dest, **opts)
def hgclone(orig, ui, opts, *args, **kwargs):
result = orig(ui, opts, *args, **kwargs)
Matt Harbison
largefiles: always create the cache and standin directories when cloning...
r17824 if result is not None:
Na'Tosha Bard
largefiles: add --all-largefiles flag to clone (issue3188)
r16644 sourcerepo, destrepo = result
Matt Harbison
largefiles: restore caching of largefiles with 'clone -U --all-largefiles'...
r17599 repo = destrepo.local()
Matt Harbison
largefiles: don't crash when cloning to a remote repo...
r24812 # When cloning to a remote repo (like through SSH), no repo is available
# from the peer. Therefore the largefiles can't be downloaded and the
# hgrc can't be updated.
if not repo:
return result
Matt Harbison
largefiles: set the extension as enabled locally after a clone requiring it...
r24029 # If largefiles is required for this repo, permanently enable it locally
if 'largefiles' in repo.requirements:
fp = repo.vfs('hgrc', 'a', text=True)
try:
fp.write('\n[extensions]\nlargefiles=\n')
finally:
fp.close()
Matt Harbison
largefiles: restore caching of largefiles with 'clone -U --all-largefiles'...
r17599 # Caching is implicitly limited to 'rev' option, since the dest repo was
Matt Harbison
largefiles: always create the cache and standin directories when cloning...
r17824 # truncated at that point. The user may expect a download count with
# this option, so attempt whether or not this is a largefile repo.
if opts.get('all_largefiles'):
success, missing = lfcommands.downloadlfiles(ui, repo, None)
Matt Harbison
largefiles: delegate to the wrapped clone command...
r17601
Matt Harbison
largefiles: always create the cache and standin directories when cloning...
r17824 if missing != 0:
return None
Matt Harbison
largefiles: delegate to the wrapped clone command...
r17601
return result
Na'Tosha Bard
largefiles: add --all-largefiles flag to clone (issue3188)
r16644
Na'Tosha Bard
largefiles: remove use of underscores that breaks coding convention
r16247 def overriderebase(orig, ui, repo, **opts):
FUJIWARA Katsunori
largefiles: access to specific fields only if largefiles enabled (issue4547)...
r24158 if not util.safehasattr(repo, '_largefilesenabled'):
return orig(ui, repo, **opts)
FUJIWARA Katsunori
largefiles: update standins only at the 1st commit of "hg rebase --continue"...
r23187 resuming = opts.get('continue')
repo._lfcommithooks.append(lfutil.automatedcommithook(resuming))
FUJIWARA Katsunori
largefiles: avoid printing messages while rebasing by "_lfstatuswriters"...
r23190 repo._lfstatuswriters.append(lambda *msg, **opts: None)
various
hgext: add largefiles extension...
r15168 try:
Matt Harbison
largefiles: preserve the exit status of the rebase command
r17578 return orig(ui, repo, **opts)
various
hgext: add largefiles extension...
r15168 finally:
FUJIWARA Katsunori
largefiles: avoid printing messages while rebasing by "_lfstatuswriters"...
r23190 repo._lfstatuswriters.pop()
FUJIWARA Katsunori
largefiles: update standins only at the 1st commit of "hg rebase --continue"...
r23187 repo._lfcommithooks.pop()
various
hgext: add largefiles extension...
r15168
Matt Harbison
largefiles: allow the archiving of largefiles to be disabled...
r25811 def overridearchivecmd(orig, ui, repo, dest, **opts):
repo.unfiltered().lfstatus = True
try:
return orig(ui, repo.unfiltered(), dest, **opts)
finally:
repo.unfiltered().lfstatus = False
Matt Harbison
largefiles: restore archiving largefiles with hgweb (issue4859)...
r26417 def hgwebarchive(orig, web, req, tmpl):
web.repo.lfstatus = True
try:
return orig(web, req, tmpl)
finally:
web.repo.lfstatus = False
Na'Tosha Bard
largefiles: remove use of underscores that breaks coding convention
r16247 def overridearchive(orig, repo, dest, node, kind, decode=True, matchfn=None,
Matt Harbison
archive: change the default prefix to '' from None...
r24172 prefix='', mtime=None, subrepos=None):
Matt Harbison
largefiles: restore archiving largefiles with hgweb (issue4859)...
r26417 # For some reason setting repo.lfstatus in hgwebarchive only changes the
# unfiltered repo's attr, so check that as well.
if not repo.lfstatus and not repo.unfiltered().lfstatus:
Matt Harbison
largefiles: allow the archiving of largefiles to be disabled...
r25811 return orig(repo, dest, node, kind, decode, matchfn, prefix, mtime,
subrepos)
Greg Ward
largefiles: more work on cleaning up comments...
r15254 # No need to lock because we are only reading history and
# largefile caches, neither of which are modified.
Matt Harbison
archive: support 'wdir()'...
r25601 if node is not None:
lfcommands.cachelfiles(repo.ui, repo, node)
various
hgext: add largefiles extension...
r15168
if kind not in archival.archivers:
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_("unknown archive type '%s'") % kind)
various
hgext: add largefiles extension...
r15168
ctx = repo[node]
Na'Tosha Bard
largefiles: remove pre-1.9 code from extension first bundled with 1.9
r15224 if kind == 'files':
if prefix:
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(
Na'Tosha Bard
largefiles: remove pre-1.9 code from extension first bundled with 1.9
r15224 _('cannot give prefix when archiving to files'))
else:
prefix = archival.tidyprefix(dest, kind, prefix)
various
hgext: add largefiles extension...
r15168
Na'Tosha Bard
largefiles: remove pre-1.9 code from extension first bundled with 1.9
r15224 def write(name, mode, islink, getdata):
if matchfn and not matchfn(name):
return
data = getdata()
if decode:
data = repo.wwritedata(name, data)
archiver.addfile(prefix + name, mode, islink, data)
various
hgext: add largefiles extension...
r15168
Na'Tosha Bard
largefiles: remove pre-1.9 code from extension first bundled with 1.9
r15224 archiver = archival.archivers[kind](dest, mtime or ctx.date()[0])
various
hgext: add largefiles extension...
r15168
if repo.ui.configbool("ui", "archivemeta", True):
Gregory Szorc
global: mass rewrite to use modern octal syntax...
r25658 write('.hg_archival.txt', 0o644, False,
Yuya Nishihara
largefiles: use common function to build content of .hg_archival.txt...
r24680 lambda: archival.buildmetadata(ctx))
various
hgext: add largefiles extension...
r15168
for f in ctx:
ff = ctx.flags(f)
getdata = ctx[f].data
if lfutil.isstandin(f):
Matt Harbison
archive: support 'wdir()'...
r25601 if node is not None:
path = lfutil.findfile(repo, getdata().strip())
if path is None:
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(
Matt Harbison
archive: support 'wdir()'...
r25601 _('largefile %s not found in repo store or system cache')
% lfutil.splitstandin(f))
else:
path = lfutil.splitstandin(f)
various
hgext: add largefiles extension...
r15168 f = lfutil.splitstandin(f)
def getdatafn():
Mads Kiilerich
largefiles: avoid use of uinitialized variable in case of errors
r15576 fd = None
various
hgext: add largefiles extension...
r15168 try:
fd = open(path, 'rb')
return fd.read()
finally:
Mads Kiilerich
largefiles: avoid use of uinitialized variable in case of errors
r15576 if fd:
fd.close()
various
hgext: add largefiles extension...
r15168
getdata = getdatafn
Gregory Szorc
global: mass rewrite to use modern octal syntax...
r25658 write(f, 'x' in ff and 0o755 or 0o644, 'l' in ff, getdata)
various
hgext: add largefiles extension...
r15168
if subrepos:
Mads Kiilerich
subrepos: process subrepos in sorted order...
r18364 for subpath in sorted(ctx.substate):
Matt Harbison
archive: support 'wdir()'...
r25601 sub = ctx.workingsub(subpath)
Matt Harbison
subrepo: propagate matcher to subrepos when archiving...
r17108 submatch = match_.narrowmatcher(subpath, matchfn)
Matt Harbison
largefiles: allow the archiving of largefiles to be disabled...
r25811 sub._repo.lfstatus = True
Matt Harbison
subrepo: drop the 'ui' parameter to archive()...
r23575 sub.archive(archiver, prefix, submatch)
various
hgext: add largefiles extension...
r15168
archiver.done()
Matt Harbison
subrepo: drop the 'ui' parameter to archive()...
r23575 def hgsubrepoarchive(orig, repo, archiver, prefix, match=None):
Matt Harbison
largefiles: allow the archiving of largefiles to be disabled...
r25811 if not repo._repo.lfstatus:
return orig(repo, archiver, prefix, match)
Matt Harbison
largefiles: download missing subrepo revs when archiving...
r17695 repo._get(repo._state + ('hg',))
Matt Harbison
largefiles: make archive -S store largefiles instead of standins...
r16578 rev = repo._state[1]
ctx = repo._repo[rev]
Matt Harbison
archive: support 'wdir()'...
r25601 if ctx.node() is not None:
lfcommands.cachelfiles(repo.ui, repo._repo, ctx.node())
Matt Harbison
largefiles: make archive -S store largefiles instead of standins...
r16578
def write(name, mode, islink, getdata):
Matt Harbison
subrepo: propagate matcher to subrepos when archiving...
r17108 # At this point, the standin has been replaced with the largefile name,
# so the normal matcher works here without the lfutil variants.
if match and not match(f):
return
Matt Harbison
largefiles: make archive -S store largefiles instead of standins...
r16578 data = getdata()
archiver.addfile(prefix + repo._path + '/' + name, mode, islink, data)
for f in ctx:
ff = ctx.flags(f)
getdata = ctx[f].data
if lfutil.isstandin(f):
Matt Harbison
archive: support 'wdir()'...
r25601 if ctx.node() is not None:
path = lfutil.findfile(repo._repo, getdata().strip())
if path is None:
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(
Matt Harbison
archive: support 'wdir()'...
r25601 _('largefile %s not found in repo store or system cache')
% lfutil.splitstandin(f))
else:
path = lfutil.splitstandin(f)
Matt Harbison
largefiles: make archive -S store largefiles instead of standins...
r16578 f = lfutil.splitstandin(f)
def getdatafn():
fd = None
try:
fd = open(os.path.join(prefix, path), 'rb')
return fd.read()
finally:
if fd:
fd.close()
getdata = getdatafn
Gregory Szorc
global: mass rewrite to use modern octal syntax...
r25658 write(f, 'x' in ff and 0o755 or 0o644, 'l' in ff, getdata)
Matt Harbison
largefiles: make archive -S store largefiles instead of standins...
r16578
Mads Kiilerich
subrepos: process subrepos in sorted order...
r18364 for subpath in sorted(ctx.substate):
Matt Harbison
archive: support 'wdir()'...
r25601 sub = ctx.workingsub(subpath)
Matt Harbison
subrepo: propagate matcher to subrepos when archiving...
r17108 submatch = match_.narrowmatcher(subpath, match)
Matt Harbison
largefiles: allow the archiving of largefiles to be disabled...
r25811 sub._repo.lfstatus = True
Matt Harbison
largefiles: drop os.path.join() in subrepo archive override...
r24954 sub.archive(archiver, prefix + repo._path + '/', submatch)
Matt Harbison
largefiles: make archive -S store largefiles instead of standins...
r16578
Greg Ward
largefiles: more work on cleaning up comments...
r15254 # If a largefile is modified, the change is not reflected in its
# standin until a commit. cmdutil.bailifchanged() raises an exception
# if the repo has uncommitted changes. Wrap it to also check if
Matt Harbison
largefiles: drop the override for 'fetch'...
r23441 # largefiles were changed. This is used by bisect, backout and fetch.
FUJIWARA Katsunori
cmdutil: allow bailifchanged to ignore merging in progress...
r24472 def overridebailifchanged(orig, repo, *args, **kwargs):
orig(repo, *args, **kwargs)
various
hgext: add largefiles extension...
r15168 repo.lfstatus = True
Martin von Zweigbergk
largefiles: access status fields by name rather than index
r22919 s = repo.status()
various
hgext: add largefiles extension...
r15168 repo.lfstatus = False
Martin von Zweigbergk
largefiles: access status fields by name rather than index
r22919 if s.modified or s.added or s.removed or s.deleted:
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_('uncommitted changes'))
various
hgext: add largefiles extension...
r15168
Matt Harbison
largefiles: enable subrepo support for forget
r23837 def cmdutilforget(orig, ui, repo, match, prefix, explicitonly):
normalmatcher = composenormalfilematcher(match, repo[None].manifest())
bad, forgot = orig(ui, repo, normalmatcher, prefix, explicitonly)
m = composelargefilematcher(match, repo[None].manifest())
various
hgext: add largefiles extension...
r15168
try:
repo.lfstatus = True
s = repo.status(match=m, clean=True)
finally:
repo.lfstatus = False
Martin von Zweigbergk
largefiles: access status fields by name rather than index
r22919 forget = sorted(s.modified + s.added + s.deleted + s.clean)
various
hgext: add largefiles extension...
r15168 forget = [f for f in forget if lfutil.standin(f) in repo[None].manifest()]
for f in forget:
if lfutil.standin(f) not in repo.dirstate and not \
Matt Harbison
forget: use vfs instead of os.path + match.rel() for filesystem checks
r23673 repo.wvfs.isdir(lfutil.standin(f)):
various
hgext: add largefiles extension...
r15168 ui.warn(_('not removing %s: file is already untracked\n')
% m.rel(f))
Matt Harbison
largefiles: enable subrepo support for forget
r23837 bad.append(f)
various
hgext: add largefiles extension...
r15168
for f in forget:
if ui.verbose or not m.exact(f):
ui.status(_('removing %s\n') % m.rel(f))
# Need to lock because standin files are deleted then removed from the
Mads Kiilerich
fix trivial spelling errors
r17424 # repository and we could race in-between.
various
hgext: add largefiles extension...
r15168 wlock = repo.wlock()
try:
lfdirstate = lfutil.openlfdirstate(ui, repo)
for f in forget:
if lfdirstate[f] == 'a':
lfdirstate.drop(f)
else:
lfdirstate.remove(f)
lfdirstate.write()
Mads Kiilerich
largefiles: remove reporemove portability wrapper
r18153 standins = [lfutil.standin(f) for f in forget]
for f in standins:
util.unlinkpath(repo.wjoin(f), ignoremissing=True)
Matt Harbison
largefiles: enable subrepo support for forget
r23837 rejected = repo[None].forget(standins)
various
hgext: add largefiles extension...
r15168 finally:
wlock.release()
Matt Harbison
largefiles: enable subrepo support for forget
r23837 bad.extend(f for f in rejected if f in m.files())
forgot.extend(f for f in forget if f not in rejected)
return bad, forgot
Matt Harbison
largefiles: preserve the exit status of the forget command...
r17579
FUJIWARA Katsunori
largefiles: confirm existence of outgoing largefile entities in remote store...
r21884 def _getoutgoings(repo, other, missing, addfunc):
FUJIWARA Katsunori
largefiles: show also how many data entities are outgoing at "hg summary"...
r21882 """get pairs of filename and largefile hash in outgoing revisions
in 'missing'.
FUJIWARA Katsunori
largefiles: confirm existence of outgoing largefile entities in remote store...
r21884 largefiles already existing on 'other' repository are ignored.
FUJIWARA Katsunori
largefiles: show also how many data entities are outgoing at "hg summary"...
r21882 'addfunc' is invoked with each unique pairs of filename and
largefile hash value.
"""
knowns = set()
FUJIWARA Katsunori
largefiles: confirm existence of outgoing largefile entities in remote store...
r21884 lfhashes = set()
FUJIWARA Katsunori
largefiles: show also how many data entities are outgoing at "hg summary"...
r21882 def dedup(fn, lfhash):
k = (fn, lfhash)
if k not in knowns:
knowns.add(k)
FUJIWARA Katsunori
largefiles: confirm existence of outgoing largefile entities in remote store...
r21884 lfhashes.add(lfhash)
FUJIWARA Katsunori
largefiles: show also how many data entities are outgoing at "hg summary"...
r21882 lfutil.getlfilestoupload(repo, missing, dedup)
FUJIWARA Katsunori
largefiles: confirm existence of outgoing largefile entities in remote store...
r21884 if lfhashes:
lfexists = basestore._openstore(repo, other).exists(lfhashes)
for fn, lfhash in knowns:
if not lfexists[lfhash]: # lfhash doesn't exist on "other"
addfunc(fn, lfhash)
FUJIWARA Katsunori
largefiles: show also how many data entities are outgoing at "hg summary"...
r21882
FUJIWARA Katsunori
largefiles: use "outgoinghooks" to avoid redundant outgoing check...
r21052 def outgoinghook(ui, repo, other, opts, missing):
various
hgext: add largefiles extension...
r15168 if opts.pop('large', None):
FUJIWARA Katsunori
largefiles: show also how many data entities are outgoing at "hg outgoing"...
r21883 lfhashes = set()
if ui.debugflag:
toupload = {}
def addfunc(fn, lfhash):
if fn not in toupload:
toupload[fn] = []
toupload[fn].append(lfhash)
lfhashes.add(lfhash)
def showhashes(fn):
for lfhash in sorted(toupload[fn]):
ui.debug(' %s\n' % (lfhash))
else:
toupload = set()
def addfunc(fn, lfhash):
toupload.add(fn)
lfhashes.add(lfhash)
def showhashes(fn):
pass
FUJIWARA Katsunori
largefiles: confirm existence of outgoing largefile entities in remote store...
r21884 _getoutgoings(repo, other, missing, addfunc)
FUJIWARA Katsunori
largefiles: show also how many data entities are outgoing at "hg outgoing"...
r21883
FUJIWARA Katsunori
largefiles: use "outgoinghooks" to avoid redundant outgoing check...
r21052 if not toupload:
FUJIWARA Katsunori
largefiles: distinguish "no remote repo" from "no files to upload" (issue3651)...
r17835 ui.status(_('largefiles: no files to upload\n'))
various
hgext: add largefiles extension...
r15168 else:
FUJIWARA Katsunori
largefiles: show also how many data entities are outgoing at "hg outgoing"...
r21883 ui.status(_('largefiles to upload (%d entities):\n')
% (len(lfhashes)))
FUJIWARA Katsunori
largefiles: use "outgoinghooks" to avoid redundant outgoing check...
r21052 for file in sorted(toupload):
various
hgext: add largefiles extension...
r15168 ui.status(lfutil.splitstandin(file) + '\n')
FUJIWARA Katsunori
largefiles: show also how many data entities are outgoing at "hg outgoing"...
r21883 showhashes(file)
various
hgext: add largefiles extension...
r15168 ui.status('\n')
FUJIWARA Katsunori
largefiles: use "summaryremotehooks" to avoid redundant outgoing check...
r21048 def summaryremotehook(ui, repo, opts, changes):
largeopt = opts.get('large', False)
if changes is None:
if largeopt:
return (False, True) # only outgoing check is needed
else:
return (False, False)
elif largeopt:
url, branch, peer, outgoing = changes[1]
if peer is None:
# i18n: column positioning for "hg summary"
ui.status(_('largefiles: (no remote repo)\n'))
return
toupload = set()
FUJIWARA Katsunori
largefiles: show also how many data entities are outgoing at "hg summary"...
r21882 lfhashes = set()
def addfunc(fn, lfhash):
toupload.add(fn)
lfhashes.add(lfhash)
FUJIWARA Katsunori
largefiles: confirm existence of outgoing largefile entities in remote store...
r21884 _getoutgoings(repo, peer, outgoing.missing, addfunc)
FUJIWARA Katsunori
largefiles: show also how many data entities are outgoing at "hg summary"...
r21882
FUJIWARA Katsunori
largefiles: use "summaryremotehooks" to avoid redundant outgoing check...
r21048 if not toupload:
# i18n: column positioning for "hg summary"
ui.status(_('largefiles: (no files to upload)\n'))
else:
# i18n: column positioning for "hg summary"
FUJIWARA Katsunori
largefiles: show also how many data entities are outgoing at "hg summary"...
r21882 ui.status(_('largefiles: %d entities for %d files to upload\n')
% (len(lfhashes), len(toupload)))
FUJIWARA Katsunori
largefiles: use "summaryremotehooks" to avoid redundant outgoing check...
r21048
Na'Tosha Bard
largefiles: remove use of underscores that breaks coding convention
r16247 def overridesummary(orig, ui, repo, *pats, **opts):
Na'Tosha Bard
largefiles: fix output of hg summary (issue3060)
r15787 try:
repo.lfstatus = True
orig(ui, repo, *pats, **opts)
finally:
repo.lfstatus = False
various
hgext: add largefiles extension...
r15168
Pierre-Yves David
largefiles: remove a mutable default argument...
r26344 def scmutiladdremove(orig, repo, matcher, prefix, opts=None, dry_run=None,
Matt Harbison
largefiles: handle commit -A properly, after a --large commit (issue3542)...
r17658 similarity=None):
Pierre-Yves David
largefiles: remove a mutable default argument...
r26344 if opts is None:
opts = {}
Na'Tosha Bard
largefiles: follow normal codepath for addremove if non-largefiles repo (issue3249)
r16636 if not lfutil.islfilesrepo(repo):
Matt Harbison
commit: propagate --addremove to subrepos if -S is specified (issue3759)...
r23537 return orig(repo, matcher, prefix, opts, dry_run, similarity)
Na'Tosha Bard
largefiles: implement addremove (issue3064)...
r15792 # Get the list of missing largefiles so we can remove them
Matt Harbison
largefiles: handle commit -A properly, after a --large commit (issue3542)...
r17658 lfdirstate = lfutil.openlfdirstate(repo.ui, repo)
Martin von Zweigbergk
dirstate: separate 'lookup' status field from others...
r22911 unsure, s = lfdirstate.status(match_.always(repo.root, repo.getcwd()), [],
False, False, False)
various
hgext: add largefiles extension...
r15168
Na'Tosha Bard
largefiles: implement addremove (issue3064)...
r15792 # Call into the normal remove code, but the removing of the standin, we want
# to have handled by original addremove. Monkey patching here makes sure
# we don't remove the standin in the largefiles code, preventing a very
# confused state later.
Martin von Zweigbergk
largefiles: access status fields by name rather than index
r22919 if s.deleted:
Matt Harbison
largefiles: pass a matcher instead of a raw file list to removelargefiles()...
r23741 m = copy.copy(matcher)
# The m._files and m._map attributes are not changed to the deleted list
# because that affects the m.exact() test, which in turn governs whether
# or not the file name is printed, and how. Simply limit the original
# matches to those in the deleted status list.
matchfn = m.matchfn
m.matchfn = lambda f: f in s.deleted and matchfn(f)
removelargefiles(repo.ui, repo, True, m, **opts)
Na'Tosha Bard
largefiles: implement addremove (issue3064)...
r15792 # Call into the normal add code, and any files that *should* be added as
# largefiles will be
Matt Harbison
largefiles: don't print files as both large and normal in addremove dryruns
r23769 added, bad = addlargefiles(repo.ui, repo, True, matcher, **opts)
Na'Tosha Bard
largefiles: implement addremove (issue3064)...
r15792 # Now that we've handled largefiles, hand off to the original addremove
# function to take care of the rest. Make sure it doesn't do anything with
Matt Harbison
scmutil: pass a matcher to scmutil.addremove() instead of a list of patterns...
r23533 # largefiles by passing a matcher that will ignore them.
Matt Harbison
largefiles: don't print files as both large and normal in addremove dryruns
r23769 matcher = composenormalfilematcher(matcher, repo[None].manifest(), added)
Matt Harbison
commit: propagate --addremove to subrepos if -S is specified (issue3759)...
r23537 return orig(repo, matcher, prefix, opts, dry_run, similarity)
various
hgext: add largefiles extension...
r15168
Greg Ward
largefiles: more work on cleaning up comments...
r15254 # Calling purge with --all will cause the largefiles to be deleted.
various
hgext: add largefiles extension...
r15168 # Override repo.status to prevent this from happening.
Na'Tosha Bard
largefiles: remove use of underscores that breaks coding convention
r16247 def overridepurge(orig, ui, repo, *dirs, **opts):
Pierre-Yves David
largefile: explain why no monkey patching on a repoview...
r23635 # XXX Monkey patching a repoview will not work. The assigned attribute will
# be set on the unfiltered repo, but we will only lookup attributes in the
# unfiltered repo if the lookup in the repoview object itself fails. As the
# monkey patched method exists on the repoview class the lookup will not
# fail. As a result, the original version will shadow the monkey patched
# one, defeating the monkey patch.
#
# As a work around we use an unfiltered repo here. We should do something
# cleaner instead.
Pierre-Yves David
largefile: status is buggy on repoproxy, so run unfiltered...
r18012 repo = repo.unfiltered()
various
hgext: add largefiles extension...
r15168 oldstatus = repo.status
Na'Tosha Bard
largefiles: remove use of underscores that breaks coding convention
r16247 def overridestatus(node1='.', node2=None, match=None, ignored=False,
various
hgext: add largefiles extension...
r15168 clean=False, unknown=False, listsubrepos=False):
r = oldstatus(node1, node2, match, ignored, clean, unknown,
listsubrepos)
lfdirstate = lfutil.openlfdirstate(ui, repo)
Martin von Zweigbergk
largefiles: access status fields by name rather than index
r22919 unknown = [f for f in r.unknown if lfdirstate[f] == '?']
ignored = [f for f in r.ignored if lfdirstate[f] == '?']
return scmutil.status(r.modified, r.added, r.removed, r.deleted,
unknown, ignored, r.clean)
Na'Tosha Bard
largefiles: remove use of underscores that breaks coding convention
r16247 repo.status = overridestatus
various
hgext: add largefiles extension...
r15168 orig(ui, repo, *dirs, **opts)
repo.status = oldstatus
Na'Tosha Bard
largefiles: remove use of underscores that breaks coding convention
r16247 def overriderollback(orig, ui, repo, **opts):
Levi Bard
largefiles: fix inappropriate locking (issue3182)...
r15794 wlock = repo.wlock()
try:
FUJIWARA Katsunori
largefiles: omit restoring standins if working parent is not rollbacked...
r22283 before = repo.dirstate.parents()
FUJIWARA Katsunori
largefiles: unlink standins not known to the restored dirstate at rollback...
r22286 orphans = set(f for f in repo.dirstate
if lfutil.isstandin(f) and repo.dirstate[f] != 'r')
FUJIWARA Katsunori
largefiles: put whole rollback-ing process into the same "wlock" scope...
r22094 result = orig(ui, repo, **opts)
FUJIWARA Katsunori
largefiles: omit restoring standins if working parent is not rollbacked...
r22283 after = repo.dirstate.parents()
if before == after:
return result # no need to restore standins
FUJIWARA Katsunori
largefiles: restore standins according to restored dirstate...
r22285 pctx = repo['.']
for f in repo.dirstate:
if lfutil.isstandin(f):
FUJIWARA Katsunori
largefiles: unlink standins not known to the restored dirstate at rollback...
r22286 orphans.discard(f)
FUJIWARA Katsunori
largefiles: restore standins according to restored dirstate...
r22285 if repo.dirstate[f] == 'r':
repo.wvfs.unlinkpath(f, ignoremissing=True)
elif f in pctx:
fctx = pctx[f]
repo.wwrite(f, fctx.data(), fctx.flags())
else:
# content of standin is not so important in 'a',
# 'm' or 'n' (coming from the 2nd parent) cases
lfutil.writestandin(repo, f, '', False)
FUJIWARA Katsunori
largefiles: unlink standins not known to the restored dirstate at rollback...
r22286 for standin in orphans:
repo.wvfs.unlinkpath(standin, ignoremissing=True)
FUJIWARA Katsunori
largefiles: put whole rollback-ing process into the same "wlock" scope...
r22094
Levi Bard
largefiles: fix inappropriate locking (issue3182)...
r15794 lfdirstate = lfutil.openlfdirstate(ui, repo)
FUJIWARA Katsunori
largefiles: drop orphan entries from lfdristat at "hg rollback"...
r22097 orphans = set(lfdirstate)
Levi Bard
largefiles: fix inappropriate locking (issue3182)...
r15794 lfiles = lfutil.listlfiles(repo)
for file in lfiles:
FUJIWARA Katsunori
largefiles: restore R status of removed largefiles correctly at "hg rollback"...
r22096 lfutil.synclfdirstate(repo, lfdirstate, file, True)
FUJIWARA Katsunori
largefiles: drop orphan entries from lfdristat at "hg rollback"...
r22097 orphans.discard(file)
for lfile in orphans:
lfdirstate.drop(lfile)
Levi Bard
largefiles: fix inappropriate locking (issue3182)...
r15794 lfdirstate.write()
finally:
wlock.release()
various
hgext: add largefiles extension...
r15168 return result
Na'Tosha Bard
largefiles: fix bad bug where transplanting a changeset with a largefile will result in an old largefile being comitted later on
r15383
Na'Tosha Bard
largefiles: remove use of underscores that breaks coding convention
r16247 def overridetransplant(orig, ui, repo, *revs, **opts):
FUJIWARA Katsunori
largefiles: update standins only at the 1st commit of "transplant --continue"...
r23274 resuming = opts.get('continue')
repo._lfcommithooks.append(lfutil.automatedcommithook(resuming))
FUJIWARA Katsunori
largefiles: avoid printing messages while transplanting by "_lfstatuswriters"...
r23275 repo._lfstatuswriters.append(lambda *msg, **opts: None)
Na'Tosha Bard
largefiles: fix transplant for all cases (issue3192)
r15982 try:
result = orig(ui, repo, *revs, **opts)
finally:
FUJIWARA Katsunori
largefiles: avoid printing messages while transplanting by "_lfstatuswriters"...
r23275 repo._lfstatuswriters.pop()
FUJIWARA Katsunori
largefiles: update standins only at the 1st commit of "transplant --continue"...
r23274 repo._lfcommithooks.pop()
Na'Tosha Bard
largefiles: fix bad bug where transplanting a changeset with a largefile will result in an old largefile being comitted later on
r15383 return result
Na'Tosha Bard
largefiles: fix cat for largefiles (issue3352)...
r16439
def overridecat(orig, ui, repo, file1, *pats, **opts):
Matt Harbison
largefiles: support revsets for cat...
r17269 ctx = scmutil.revsingle(repo, opts.get('rev'))
Mads Kiilerich
largefiles: fix cat when using relative paths from subdirectory
r18491 err = 1
notbad = set()
m = scmutil.match(ctx, (file1,) + pats, opts)
origmatchfn = m.matchfn
def lfmatchfn(f):
Mads Kiilerich
largefiles: make cat on standins do something...
r21087 if origmatchfn(f):
return True
Mads Kiilerich
largefiles: fix cat when using relative paths from subdirectory
r18491 lf = lfutil.splitstandin(f)
if lf is None:
Mads Kiilerich
largefiles: make cat on standins do something...
r21087 return False
Mads Kiilerich
largefiles: fix cat when using relative paths from subdirectory
r18491 notbad.add(lf)
return origmatchfn(lf)
m.matchfn = lfmatchfn
Mads Kiilerich
largefiles: fix cat of non-largefiles from subdirectory...
r18974 origbadfn = m.bad
def lfbadfn(f, msg):
if not f in notbad:
Mads Kiilerich
largefiles: remove confusing handling of .bad return value - it is void
r21086 origbadfn(f, msg)
Mads Kiilerich
largefiles: fix cat of non-largefiles from subdirectory...
r18974 m.bad = lfbadfn
Drew Gottlieb
treemanifest: optimize treemanifest._walk() to skip directories...
r24670
origvisitdirfn = m.visitdir
def lfvisitdirfn(dir):
if dir == lfutil.shortname:
return True
ret = origvisitdirfn(dir)
if ret:
return ret
lf = lfutil.splitstandin(dir)
if lf is None:
return False
return origvisitdirfn(lf)
m.visitdir = lfvisitdirfn
Mads Kiilerich
largefiles: fix cat when using relative paths from subdirectory
r18491 for f in ctx.walk(m):
Mads Kiilerich
largefiles: fix cat of non-largefiles from subdirectory...
r18974 fp = cmdutil.makefileobj(repo, opts.get('output'), ctx.node(),
pathname=f)
Mads Kiilerich
largefiles: fix cat when using relative paths from subdirectory
r18491 lf = lfutil.splitstandin(f)
Mads Kiilerich
largefiles: make cat on standins do something...
r21087 if lf is None or origmatchfn(f):
Mads Kiilerich
largefiles: fix cat of non-largefiles from subdirectory...
r18974 # duplicating unreachable code from commands.cat
data = ctx[f].data()
if opts.get('decode'):
data = repo.wwritedata(f, data)
fp.write(data)
Mads Kiilerich
largefiles: fix cat when using relative paths from subdirectory
r18491 else:
Mads Kiilerich
largefiles: fix cat of non-largefiles from subdirectory...
r18974 hash = lfutil.readstandin(repo, lf, ctx.rev())
if not lfutil.inusercache(repo.ui, hash):
store = basestore._openstore(repo)
success, missing = store.get([(lf, hash)])
if len(success) != 1:
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(
Mads Kiilerich
largefiles: fix cat of non-largefiles from subdirectory...
r18974 _('largefile %s is not in cache and could not be '
'downloaded') % lf)
path = lfutil.usercachepath(repo.ui, hash)
fpin = open(path, "rb")
Mads Kiilerich
largefiles: drop lfutil.blockstream - use filechunkiter like everybody else...
r19001 for chunk in util.filechunkiter(fpin, 128 * 1024):
Mads Kiilerich
largefiles: fix cat of non-largefiles from subdirectory...
r18974 fp.write(chunk)
fpin.close()
fp.close()
err = 0
Mads Kiilerich
largefiles: fix cat when using relative paths from subdirectory
r18491 return err
Matt Harbison
largefiles: don't copy largefiles from working dir to the store while converting...
r17878
Augie Fackler
merge: have merge.update use a matcher instead of partial fn...
r27344 def mergeupdate(orig, repo, node, branchmerge, force,
FUJIWARA Katsunori
largefiles: update largefiles even if rebase is aborted by conflict...
r22288 *args, **kwargs):
Augie Fackler
merge: have merge.update use a matcher instead of partial fn...
r27344 matcher = kwargs.get('matcher', None)
# note if this is a partial update
partial = matcher and not matcher.always()
FUJIWARA Katsunori
largefiles: update largefiles even if rebase is aborted by conflict...
r22288 wlock = repo.wlock()
try:
# branch | | |
# merge | force | partial | action
# -------+-------+---------+--------------
# x | x | x | linear-merge
# o | x | x | branch-merge
# x | o | x | overwrite (as clean update)
# o | o | x | force-branch-merge (*1)
# x | x | o | (*)
# o | x | o | (*)
# x | o | o | overwrite (as revert)
# o | o | o | (*)
#
# (*) don't care
# (*1) deprecated, but used internally (e.g: "rebase --collapse")
Mads Kiilerich
largefiles: for update -C, only update largefiles when necessary...
r24787 lfdirstate = lfutil.openlfdirstate(repo.ui, repo)
unsure, s = lfdirstate.status(match_.always(repo.root,
repo.getcwd()),
[], False, False, False)
pctx = repo['.']
for lfile in unsure + s.modified:
lfileabs = repo.wvfs.join(lfile)
if not os.path.exists(lfileabs):
continue
lfhash = lfutil.hashrepofile(repo, lfile)
standin = lfutil.standin(lfile)
lfutil.writestandin(repo, standin, lfhash,
lfutil.getexecutable(lfileabs))
if (standin in pctx and
lfhash == lfutil.readstandin(repo, lfile, '.')):
lfdirstate.normal(lfile)
for lfile in s.added:
lfutil.updatestandin(repo, lfutil.standin(lfile))
lfdirstate.write()
FUJIWARA Katsunori
largefiles: update largefiles even if rebase is aborted by conflict...
r22288
Mads Kiilerich
largefiles: for update -C, only update largefiles when necessary...
r24787 oldstandins = lfutil.getstandinsstate(repo)
FUJIWARA Katsunori
largefiles: update largefiles even if rebase is aborted by conflict...
r22288
Augie Fackler
merge: have merge.update use a matcher instead of partial fn...
r27344 result = orig(repo, node, branchmerge, force, *args, **kwargs)
FUJIWARA Katsunori
largefiles: update largefiles even if rebase is aborted by conflict...
r22288
Mads Kiilerich
largefiles: for update -C, only update largefiles when necessary...
r24787 newstandins = lfutil.getstandinsstate(repo)
filelist = lfutil.getlfilestoupdate(oldstandins, newstandins)
if branchmerge or force or partial:
filelist.extend(s.deleted + s.removed)
FUJIWARA Katsunori
largefiles: update largefiles even if rebase is aborted by conflict...
r22288
lfcommands.updatelfiles(repo.ui, repo, filelist=filelist,
Mads Kiilerich
largefiles: always consider updatelfiles 'checked' parameter set...
r24788 normallookup=partial)
FUJIWARA Katsunori
largefiles: update largefiles even if rebase is aborted by conflict...
r22288
return result
finally:
wlock.release()
FUJIWARA Katsunori
largefiles: update largefiles even if transplant is aborted by conflict...
r22289
def scmutilmarktouched(orig, repo, files, *args, **kwargs):
result = orig(repo, files, *args, **kwargs)
filelist = [lfutil.splitstandin(f) for f in files if lfutil.isstandin(f)]
if filelist:
lfcommands.updatelfiles(repo.ui, repo, filelist=filelist,
printmessage=False, normallookup=True)
return result