@@ -363,6 +363,36 @@ def getstandinsstate(repo):
standins.append((lfile, hash))
return standins
+def standintolargefiles(printmessage=True, normallookup=False):
+ def decorate(f):
+ def new(orig, ui, repo, *a, **b):
+ wlock = repo.wlock()
+ try:
+ lfdirstate = openlfdirstate(ui, repo)
+ (modified, added, removed, missing, unknown, ignored, clean) = \
+ lfdirstatestatus(lfdirstate, repo, repo['.'].rev())
+ lfdirstate.write()
+ for lfile in modified:
+ updatestandin(repo, standin(lfile))
+ for lfile in missing:
+ standinfile = repo.wjoin(standin(lfile))
+ if os.path.exists(standinfile):
+ os.unlink(standinfile)
+
+ oldstandins = getstandinsstate(repo)
+ ret = f(orig, ui, repo, *a, **b)
+ newstandins = getstandinsstate(repo)
+ filelist = getlfilestoupdate(oldstandins, newstandins)
+ import lfcommands
+ lfcommands.updatelfiles(ui, repo, filelist,
+ printmessage=printmessage,
+ normallookup=normallookup)
+ return ret
+ finally:
+ wlock.release()
+ return new
+ return decorate
+
def synclfdirstate(repo, lfdirstate, lfile, normallookup):
lfstandin = standin(lfile)
if lfstandin in repo.dirstate:
@@ -655,64 +655,41 @@ def overridecopy(orig, ui, repo, pats, o
# commits. Update the standins then run the original revert, changing
# the matcher to hit standins instead of largefiles. Based on the
# resulting standins update the largefiles.
+#
+# 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.
+@lfutil.standintolargefiles(printmessage=False, normallookup=True)
def overriderevert(orig, ui, repo, *pats, **opts):
- # 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.
- wlock = repo.wlock()
+ 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)
+ m._always = False
+ 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)
try:
- lfdirstate = lfutil.openlfdirstate(ui, repo)
- (modified, added, removed, missing, unknown, ignored, clean) = \
- lfutil.lfdirstatestatus(lfdirstate, repo, repo['.'].rev())
- lfdirstate.write()
- for lfile in modified:
- lfutil.updatestandin(repo, lfutil.standin(lfile))
- for lfile in missing:
- if (os.path.exists(repo.wjoin(lfutil.standin(lfile)))):
- os.unlink(repo.wjoin(lfutil.standin(lfile)))
-
- oldstandins = lfutil.getstandinsstate(repo)
-
- 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)
- m._always = False
- 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)
- try:
- orig(ui, repo, *pats, **opts)
- finally:
- restorematchfn()
-
- newstandins = lfutil.getstandinsstate(repo)
- filelist = lfutil.getlfilestoupdate(oldstandins, newstandins)
- # 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)
-
+ orig(ui, repo, *pats, **opts)
finally:
- wlock.release()
+ restorematchfn()
# When we rebase a repository with remotely changed largefiles, we need to
# take some extra care so that the largefiles are correctly updated in the
@@ -817,6 +794,7 @@ def hgclone(orig, ui, opts, *args, **kwa
return result
+@lfutil.standintolargefiles(printmessage=False)
def overriderebase(orig, ui, repo, **opts):
repo._isrebasing = True
try:
@@ -1196,15 +1174,11 @@ def overriderollback(orig, ui, repo, **o
wlock.release()
return result
+@lfutil.standintolargefiles(printmessage=True)
def overridetransplant(orig, ui, repo, *revs, **opts):
try:
- oldstandins = lfutil.getstandinsstate(repo)
repo._istransplanting = True
result = orig(ui, repo, *revs, **opts)
- newstandins = lfutil.getstandinsstate(repo)
- filelist = lfutil.getlfilestoupdate(oldstandins, newstandins)
- lfcommands.updatelfiles(repo.ui, repo, filelist=filelist,
- printmessage=True)
finally:
repo._istransplanting = False
return result