##// END OF EJS Templates
revlog: _addrevision creates full-replace deltas based on censored revisions...
revlog: _addrevision creates full-replace deltas based on censored revisions A delta against a censored revision is either received through exchange and written blindly to a revlog, or it is created by the revlog itself. This change ensures the latter process creates deltas which fully replace all data in a censored base using a single patch operation. Recipients of a delta against a censored base will verify that the delta is in this full-replace format. Other recipients will use the delta as normal. For background and broader design of the censorship feature, see: http://mercurial.selenic.com/wiki/CensorPlan

File last commit:

r24029:e1dbe0b2 default
r24123:eb2d41c6 default
Show More
overrides.py
1355 lines | 51.3 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_, \
FUJIWARA Katsunori
largefiles: restore standins according to restored dirstate...
r22285 archival, pathutil, revset
various
hgext: add largefiles extension...
r15168 from mercurial.i18n import _
from mercurial.node import hex
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)
m._fmap = set(m._files)
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)
m._fmap = set(m._files)
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'''
Na'Tosha Bard
largefiles: remove use of underscores that breaks coding convention
r16247 def overridematch(ctx, pats=[], opts={}, globbed=False,
various
hgext: add largefiles extension...
r15168 default='relpath'):
Greg Ward
largefiles: fix some badly named function parameters...
r15306 match = oldmatch(ctx, pats, opts, globbed, default)
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
scmutil: pass a matcher to scmutil.addremove() instead of a list of patterns...
r23533 m = copy.copy(matcher)
various
hgext: add largefiles extension...
r15168 m.bad = lambda x, y: None
wctx = repo[None]
for f in repo.walk(m):
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'):
raise util.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):
Lucas Moscovicz
largefiles: changed overridelog to work with graphlog...
r21110 def overridematchandpats(ctx, pats=[], opts={}, globbed=False,
Mads Kiilerich
largefiles: make log match largefiles in the non-standin location too...
r18341 default='relpath'):
"""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.
"""
Lucas Moscovicz
largefiles: changed overridelog to work with graphlog...
r21110 matchandpats = oldmatchandpats(ctx, pats, opts, globbed, default)
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)
# TODO: handling of patterns in both cases below
if m._cwd:
Mads Kiilerich
largefiles: better handling of log from other working directory (issue4236)...
r21209 if os.path.isabs(m._cwd):
# TODO: handle largefile magic when invoked from other cwd
return matchandpats
Lucas Moscovicz
largefiles: changed overridelog to work with graphlog...
r21110 back = (m._cwd.count('/') + 1) * '../'
pats.update(back + lfutil.standin(m._cwd + '/' + f) for f in p)
else:
pats.update(lfutil.standin(f) for f in p)
Wei, Elson
largefiles: overridematch() should replace the file path instead of extending (issue3934)
r19472 for i in range(0, len(m._files)):
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 pats.add(standin)
Mads Kiilerich
largefiles: make log match largefiles in the non-standin location too...
r18341 m._fmap = 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
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).
def overridemakelogfilematcher(repo, pats, opts):
pctx = repo[None]
match, pats = oldmatchandpats(pctx, pats, opts)
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)
various
hgext: add largefiles extension...
r15168 # Override needs to refresh standins so that update's normal merge
# will go through properly. Then the other update hook (overriding repo.update)
Mads Kiilerich
fix trivial spelling errors
r17424 # will get the new files. Filemerge is also overridden so that the merge
various
hgext: add largefiles extension...
r15168 # will merge standins correctly.
Na'Tosha Bard
largefiles: remove use of underscores that breaks coding convention
r16247 def overrideupdate(orig, ui, repo, *pats, **opts):
Greg Ward
largefiles: improve comments, internal docstrings...
r15252 # Need to lock between the standins getting updated and their
# largefiles getting updated
various
hgext: add largefiles extension...
r15168 wlock = repo.wlock()
try:
Mads Kiilerich
largefiles: the update override only needs lfdirstate and status for --check
r23040 if opts['check']:
lfdirstate = lfutil.openlfdirstate(ui, repo)
unsure, s = lfdirstate.status(
match_.always(repo.root, repo.getcwd()),
[], False, False, False)
Mads Kiilerich
largefiles: use more reasonable locking for update
r21089
Martin von Zweigbergk
largefiles: access status fields by name rather than index
r22919 mod = len(s.modified) > 0
various
hgext: add largefiles extension...
r15168 for lfile in unsure:
standin = lfutil.standin(lfile)
if repo['.'][standin].data().strip() != \
lfutil.hashfile(repo.wjoin(lfile)):
mod = True
else:
lfdirstate.normal(lfile)
lfdirstate.write()
if mod:
Siddharth Agarwal
largefiles: standardize error message for dirty working dir
r19805 raise util.Abort(_('uncommitted changes'))
Mads Kiilerich
largefiles: use more reasonable locking for update
r21089 return orig(ui, repo, *pats, **opts)
various
hgext: add largefiles extension...
r15168 finally:
wlock.release()
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,
Mads Kiilerich
merge: move ancestor selection tweaking from manifestmerge to update function...
r21080 partial, acceptremote, followcopies):
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(
repo, p1, p2, pas, branchmerge, force, partial, acceptremote,
followcopies)
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':
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':
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.
Durham Goode
merge: add labels parameter from merge.update to filemerge...
r21524 def overridefilemerge(origfn, repo, mynode, orig, fcd, fco, fca, labels=None):
various
hgext: add largefiles extension...
r15168 if not lfutil.isstandin(orig):
Durham Goode
merge: add labels parameter from merge.update to filemerge...
r21524 return origfn(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())
return 0
various
hgext: add largefiles extension...
r15168
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:
Thomas Arendsen Hein
largefiles: use separate try/except and try/finally as needed for python2.4...
r15279 try:
result = orig(ui, repo, pats, opts, rename)
except util.Abort, e:
Matt Mackall
largefiles: fix exception hack for i18n (issue3197)...
r17263 if str(e) != _('no files to copy'):
Thomas Arendsen Hein
largefiles: use separate try/except and try/finally as needed for python2.4...
r15279 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:
Thomas Arendsen Hein
largefiles: use separate try/except and try/finally as needed for python2.4...
r15279 try:
Na'Tosha Bard
largefiles: fix check-code errors.
r16248 # 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.
Thomas Arendsen Hein
largefiles: use separate try/except and try/finally as needed for python2.4...
r15279 wlock = repo.wlock()
various
hgext: add largefiles extension...
r15168
Thomas Arendsen Hein
largefiles: use separate try/except and try/finally as needed for python2.4...
r15279 manifest = repo[None].manifest()
Na'Tosha Bard
largefiles: remove use of underscores that breaks coding convention
r16247 def overridematch(ctx, pats=[], opts={}, globbed=False,
Thomas Arendsen Hein
largefiles: use separate try/except and try/finally as needed for python2.4...
r15279 default='relpath'):
newpats = []
# The patterns were previously mangled to add the standin
# directory; we need to remove that now
for pat in pats:
if match_.patkind(pat) is None and lfutil.shortname in pat:
newpats.append(pat.replace(lfutil.shortname, ''))
else:
newpats.append(pat)
Greg Ward
largefiles: fix some badly named function parameters...
r15306 match = oldmatch(ctx, newpats, opts, globbed, default)
Thomas Arendsen Hein
largefiles: use separate try/except and try/finally as needed for python2.4...
r15279 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)]
m._fmap = set(m._files)
Na'Tosha Bard
largefiles: remove use of underscores that breaks coding convention
r16247 origmatchfn = m.matchfn
Thomas Arendsen Hein
largefiles: use separate try/except and try/finally as needed for python2.4...
r15279 m.matchfn = lambda f: (lfutil.isstandin(f) and
FUJIWARA Katsunori
largefiles: reduce redundant splitstandin/standin combination...
r16075 (f in manifest) and
Na'Tosha Bard
largefiles: remove use of underscores that breaks coding convention
r16247 origmatchfn(lfutil.splitstandin(f)) or
Thomas Arendsen Hein
largefiles: use separate try/except and try/finally as needed for python2.4...
r15279 None)
return m
Na'Tosha Bard
largefiles: remove use of underscores that breaks coding convention
r16247 oldmatch = installmatchfn(overridematch)
Thomas Arendsen Hein
largefiles: use separate try/except and try/finally as needed for python2.4...
r15279 listpats = []
various
hgext: add largefiles extension...
r15168 for pat in pats:
Thomas Arendsen Hein
largefiles: use separate try/except and try/finally as needed for python2.4...
r15279 if match_.patkind(pat) is not None:
listpats.append(pat)
various
hgext: add largefiles extension...
r15168 else:
Thomas Arendsen Hein
largefiles: use separate try/except and try/finally as needed for python2.4...
r15279 listpats.append(makestandin(pat))
various
hgext: add largefiles extension...
r15168
Thomas Arendsen Hein
largefiles: use separate try/except and try/finally as needed for python2.4...
r15279 try:
origcopyfile = util.copyfile
copiedfiles = []
Na'Tosha Bard
largefiles: remove use of underscores that breaks coding convention
r16247 def overridecopyfile(src, dest):
Na'Tosha Bard
largefiles: fix rename (issue3093)
r15598 if (lfutil.shortname in src and
dest.startswith(repo.wjoin(lfutil.shortname))):
Thomas Arendsen Hein
largefiles: use separate try/except and try/finally as needed for python2.4...
r15279 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)
various
hgext: add largefiles extension...
r15168
Na'Tosha Bard
largefiles: remove use of underscores that breaks coding convention
r16247 util.copyfile = overridecopyfile
Thomas Arendsen Hein
largefiles: use separate try/except and try/finally as needed for python2.4...
r15279 result += orig(ui, repo, listpats, opts, rename)
finally:
util.copyfile = origcopyfile
various
hgext: add largefiles extension...
r15168
Thomas Arendsen Hein
largefiles: use separate try/except and try/finally as needed for python2.4...
r15279 lfdirstate = lfutil.openlfdirstate(ui, repo)
for (src, dest) in copiedfiles:
Na'Tosha Bard
largefiles: fix rename (issue3093)
r15598 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('')), '')
Matt Harbison
largefiles: fix path handling for cp/mv (issue3516)...
r17245 destlfiledir = os.path.dirname(repo.wjoin(destlfile)) or '.'
Thomas Arendsen Hein
largefiles: use separate try/except and try/finally as needed for python2.4...
r15279 if not os.path.isdir(destlfiledir):
os.makedirs(destlfiledir)
if rename:
Na'Tosha Bard
largefiles: fix rename (issue3093)
r15598 os.rename(repo.wjoin(srclfile), repo.wjoin(destlfile))
Matt Harbison
largefiles: remove directories emptied after their files are moved (issue3515)
r21196
# The file is gone, but this deletes any empty parent
# directories as a side-effect.
util.unlinkpath(repo.wjoin(srclfile), True)
Na'Tosha Bard
largefiles: fix rename (issue3093)
r15598 lfdirstate.remove(srclfile)
Thomas Arendsen Hein
largefiles: use separate try/except and try/finally as needed for python2.4...
r15279 else:
Matt Harbison
largefiles: fix path handling for cp/mv (issue3516)...
r17245 util.copyfile(repo.wjoin(srclfile),
repo.wjoin(destlfile))
Na'Tosha Bard
largefiles: fix rename (issue3093)
r15598 lfdirstate.add(destlfile)
Thomas Arendsen Hein
largefiles: use separate try/except and try/finally as needed for python2.4...
r15279 lfdirstate.write()
except util.Abort, e:
Matt Mackall
largefiles: fix exception hack for i18n (issue3197)...
r17263 if str(e) != _('no files to copy'):
Thomas Arendsen Hein
largefiles: use separate try/except and try/finally as needed for python2.4...
r15279 raise e
else:
nolfiles = True
various
hgext: add largefiles extension...
r15168 finally:
restorematchfn()
wlock.release()
if nolfiles and nonormalfiles:
raise util.Abort(_('no files to copy'))
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.
Na'Tosha Bard
largefiles: remove use of underscores that breaks coding convention
r16247 def overriderevert(orig, ui, repo, *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)
Mads Kiilerich
largefiles: revert override, install matchfn outside the try/except restoring it
r21095 def overridematch(ctx, pats=[], opts={}, globbed=False,
default='relpath'):
match = oldmatch(ctx, pats, opts, globbed, default)
m = copy.copy(match)
def tostandin(f):
if lfutil.standin(f) in ctx:
return lfutil.standin(f)
elif lfutil.standin(f) in repo[None]:
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]
m._fmap = set(m._files)
origmatchfn = m.matchfn
def matchfn(f):
if lfutil.isstandin(f):
return (origmatchfn(lfutil.splitstandin(f)) and
(f in repo[None] or f in ctx))
return origmatchfn(f)
m.matchfn = matchfn
return m
oldmatch = installmatchfn(overridematch)
various
hgext: add largefiles extension...
r15168 try:
orig(ui, repo, *pats, **opts)
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
Mads Kiilerich
largefiles: introduce pulled() revset expression for use in --lfrev...
r18979 def pulledrevsetsymbol(repo, subset, x):
"""``pulled()``
Changesets that just has been pulled.
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:
raise util.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):
Levi Bard
largefiles: don't attempt to clone all largefiles to non-local destinations
r16723 raise util.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: 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: 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
Na'Tosha Bard
largefiles: remove use of underscores that breaks coding convention
r16247 def overridearchive(orig, repo, dest, node, kind, decode=True, matchfn=None,
various
hgext: add largefiles extension...
r15168 prefix=None, mtime=None, subrepos=None):
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.
various
hgext: add largefiles extension...
r15168 lfcommands.cachelfiles(repo.ui, repo, node)
if kind not in archival.archivers:
raise util.Abort(_("unknown archive type '%s'") % kind)
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:
raise util.Abort(
_('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):
def metadata():
base = 'repo: %s\nnode: %s\nbranch: %s\n' % (
hex(repo.changelog.node(0)), hex(node), ctx.branch())
tags = ''.join('tag: %s\n' % t for t in ctx.tags()
if repo.tagtype(t) == 'global')
if not tags:
repo.ui.pushbuffer()
opts = {'template': '{latesttag}\n{latesttagdistance}',
'style': '', 'patch': None, 'git': None}
cmdutil.show_changeset(repo.ui, repo, opts).show(ctx)
ltags, dist = repo.ui.popbuffer().split('\n')
tags = ''.join('latesttag: %s\n' % t for t in ltags.split(':'))
tags += 'latesttagdistance: %s\n' % dist
return base + tags
write('.hg_archival.txt', 0644, False, metadata)
for f in ctx:
ff = ctx.flags(f)
getdata = ctx[f].data
if lfutil.isstandin(f):
path = lfutil.findfile(repo, getdata().strip())
Na'Tosha Bard
largefiles: check if largefile could be found when archiving (issue3193)
r15914 if path is None:
raise util.Abort(
_('largefile %s not found in repo store or system cache')
% 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
write(f, 'x' in ff and 0755 or 0644, 'l' in ff, getdata)
if subrepos:
Mads Kiilerich
subrepos: process subrepos in sorted order...
r18364 for subpath in sorted(ctx.substate):
various
hgext: add largefiles extension...
r15168 sub = ctx.sub(subpath)
Matt Harbison
subrepo: propagate matcher to subrepos when archiving...
r17108 submatch = match_.narrowmatcher(subpath, matchfn)
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: 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
subrepo: drop the 'ui' parameter to archive()...
r23575 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):
path = lfutil.findfile(repo._repo, getdata().strip())
if path is None:
raise util.Abort(
_('largefile %s not found in repo store or system cache')
% lfutil.splitstandin(f))
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
write(f, 'x' in ff and 0755 or 0644, 'l' in ff, getdata)
Mads Kiilerich
subrepos: process subrepos in sorted order...
r18364 for subpath in sorted(ctx.substate):
Matt Harbison
largefiles: make archive -S store largefiles instead of standins...
r16578 sub = ctx.sub(subpath)
Matt Harbison
subrepo: propagate matcher to subrepos when archiving...
r17108 submatch = match_.narrowmatcher(subpath, match)
Matt Harbison
subrepo: drop the 'ui' parameter to archive()...
r23575 sub.archive(archiver, os.path.join(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.
Na'Tosha Bard
largefiles: remove use of underscores that breaks coding convention
r16247 def overridebailifchanged(orig, repo):
various
hgext: add largefiles extension...
r15168 orig(repo)
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:
Siddharth Agarwal
largefiles: standardize error message for dirty working dir
r19805 raise util.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
Matt Harbison
commit: propagate --addremove to subrepos if -S is specified (issue3759)...
r23537 def scmutiladdremove(orig, repo, matcher, prefix, opts={}, dry_run=None,
Matt Harbison
largefiles: handle commit -A properly, after a --large commit (issue3542)...
r17658 similarity=None):
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
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:
raise util.Abort(
_('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
FUJIWARA Katsunori
largefiles: update largefiles even if rebase is aborted by conflict...
r22288 def mergeupdate(orig, repo, node, branchmerge, force, partial,
*args, **kwargs):
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")
linearmerge = not branchmerge and not force and not partial
if linearmerge or (branchmerge and force and not partial):
# update standins for linear-merge or force-branch-merge,
# because largefiles in the working directory may be modified
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)
Mads Kiilerich
largefiles: make linear update set unsure largefiles normal if unchanged...
r23841 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:
FUJIWARA Katsunori
largefiles: update largefiles even if rebase is aborted by conflict...
r22288 lfutil.updatestandin(repo, lfutil.standin(lfile))
Mads Kiilerich
largefiles: make linear update set unsure largefiles normal if unchanged...
r23841 lfdirstate.write()
FUJIWARA Katsunori
largefiles: update largefiles even if rebase is aborted by conflict...
r22288
if linearmerge:
# Only call updatelfiles on the standins that have changed
# to save time
oldstandins = lfutil.getstandinsstate(repo)
result = orig(repo, node, branchmerge, force, partial, *args, **kwargs)
filelist = None
if linearmerge:
newstandins = lfutil.getstandinsstate(repo)
filelist = lfutil.getlfilestoupdate(oldstandins, newstandins)
lfcommands.updatelfiles(repo.ui, repo, filelist=filelist,
Mads Kiilerich
largefiles: don't rehash largefiles in updatelfiles if standin hash changed...
r23893 normallookup=partial, checked=linearmerge)
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