--- a/hgext/largefiles/lfcommands.py Thu Nov 07 01:48:00 2013 +0100
+++ b/hgext/largefiles/lfcommands.py Thu Nov 07 01:49:48 2013 +0100
@@ -444,13 +444,63 @@
cachelfiles(ui, repo, None, lfiles)
updated, removed = 0, 0
- for f in lfiles:
- i = _updatelfile(repo, lfdirstate, f)
- if i:
- if i > 0:
- updated += i
+ for lfile in lfiles:
+ # updates a single largefile and copies the state of its standin from
+ # the repository's dirstate to its state in the lfdirstate.
+ abslfile = repo.wjoin(lfile)
+ absstandin = repo.wjoin(lfutil.standin(lfile))
+ if os.path.exists(absstandin):
+ if (os.path.exists(absstandin + '.orig') and
+ os.path.exists(abslfile)):
+ shutil.copyfile(abslfile, abslfile + '.orig')
+ update1 = 0
+ expecthash = lfutil.readstandin(repo, lfile)
+ if (expecthash != '' and
+ (not os.path.exists(abslfile) or
+ expecthash != lfutil.hashfile(abslfile))):
+ if not lfutil.copyfromcache(repo, expecthash, lfile):
+ # use normallookup() to allocate entry in largefiles
+ # dirstate, because lack of it misleads
+ # lfilesrepo.status() into recognition that such cache
+ # missing files are REMOVED.
+ if lfile not in repo[None]: # not switched to normal
+ util.unlinkpath(abslfile, ignoremissing=True)
+ lfdirstate.normallookup(lfile)
+ continue # don't try to set the mode
+ else:
+ # Synchronize largefile dirstate to the last modified
+ # time of the file
+ lfdirstate.normal(lfile)
+ update1 = 1
+ mode = os.stat(absstandin).st_mode
+ if mode != os.stat(abslfile).st_mode:
+ os.chmod(abslfile, mode)
+ update1 = 1
+ updated += update1
+ else:
+ # Remove lfiles for which the standin is deleted, unless the
+ # lfile is added to the repository again. This happens when a
+ # largefile is converted back to a normal file: the standin
+ # disappears, but a new (normal) file appears as the lfile.
+ if (os.path.exists(abslfile) and
+ repo.dirstate.normalize(lfile) not in repo[None]):
+ util.unlinkpath(abslfile)
+ removed += 1
+ state = repo.dirstate[lfutil.standin(lfile)]
+ if state == 'n':
+ # When rebasing, we need to synchronize the standin and the
+ # largefile, because otherwise the largefile will get reverted.
+ # But for commit's sake, we have to mark the file as unclean.
+ if getattr(repo, "_isrebasing", False):
+ lfdirstate.normallookup(lfile)
else:
- removed -= i
+ lfdirstate.normal(lfile)
+ elif state == 'r':
+ lfdirstate.remove(lfile)
+ elif state == 'a':
+ lfdirstate.add(lfile)
+ elif state == '?':
+ lfdirstate.drop(lfile)
lfdirstate.write()
if printmessage and lfiles:
@@ -459,66 +509,6 @@
finally:
wlock.release()
-def _updatelfile(repo, lfdirstate, lfile):
- '''updates a single largefile and copies the state of its standin from
- the repository's dirstate to its state in the lfdirstate.
-
- returns 1 if the file was modified, -1 if the file was removed, 0 if the
- file was unchanged, and None if the needed largefile was missing from the
- cache.'''
- ret = 0
- abslfile = repo.wjoin(lfile)
- absstandin = repo.wjoin(lfutil.standin(lfile))
- if os.path.exists(absstandin):
- if os.path.exists(absstandin + '.orig') and os.path.exists(abslfile):
- shutil.copyfile(abslfile, abslfile + '.orig')
- expecthash = lfutil.readstandin(repo, lfile)
- if (expecthash != '' and
- (not os.path.exists(abslfile) or
- expecthash != lfutil.hashfile(abslfile))):
- if not lfutil.copyfromcache(repo, expecthash, lfile):
- # use normallookup() to allocate entry in largefiles dirstate,
- # because lack of it misleads lfilesrepo.status() into
- # recognition that such cache missing files are REMOVED.
- if lfile not in repo[None]: # not switched to normal file
- util.unlinkpath(abslfile, ignoremissing=True)
- lfdirstate.normallookup(lfile)
- return None # don't try to set the mode
- else:
- # Synchronize largefile dirstate to the last modified time of
- # the file
- lfdirstate.normal(lfile)
- ret = 1
- mode = os.stat(absstandin).st_mode
- if mode != os.stat(abslfile).st_mode:
- os.chmod(abslfile, mode)
- ret = 1
- else:
- # Remove lfiles for which the standin is deleted, unless the
- # lfile is added to the repository again. This happens when a
- # largefile is converted back to a normal file: the standin
- # disappears, but a new (normal) file appears as the lfile.
- if (os.path.exists(abslfile) and
- repo.dirstate.normalize(lfile) not in repo[None]):
- util.unlinkpath(abslfile)
- ret = -1
- state = repo.dirstate[lfutil.standin(lfile)]
- if state == 'n':
- # When rebasing, we need to synchronize the standin and the largefile,
- # because otherwise the largefile will get reverted. But for commit's
- # sake, we have to mark the file as unclean.
- if getattr(repo, "_isrebasing", False):
- lfdirstate.normallookup(lfile)
- else:
- lfdirstate.normal(lfile)
- elif state == 'r':
- lfdirstate.remove(lfile)
- elif state == 'a':
- lfdirstate.add(lfile)
- elif state == '?':
- lfdirstate.drop(lfile)
- return ret
-
def lfpull(ui, repo, source="default", **opts):
"""pull largefiles for the specified revisions from the specified source