--- a/hgext/largefiles/overrides.py Tue Oct 11 20:39:47 2016 -0300
+++ b/hgext/largefiles/overrides.py Tue Oct 18 14:13:06 2016 -0500
@@ -1390,7 +1390,8 @@
lfdirstate = lfutil.openlfdirstate(repo.ui, repo)
unsure, s = lfdirstate.status(matchmod.always(repo.root,
repo.getcwd()),
- [], False, False, False)
+ [], False, True, False)
+ oldclean = set(s.clean)
pctx = repo['.']
for lfile in unsure + s.modified:
lfileabs = repo.wvfs.join(lfile)
@@ -1402,9 +1403,13 @@
lfutil.getexecutable(lfileabs))
if (standin in pctx and
lfhash == lfutil.readstandin(repo, lfile, '.')):
- lfdirstate.normal(lfile)
+ oldclean.add(lfile)
for lfile in s.added:
lfutil.updatestandin(repo, lfutil.standin(lfile))
+ # mark all clean largefiles as dirty, just in case the update gets
+ # interrupted before largefiles and lfdirstate are synchronized
+ for lfile in oldclean:
+ lfdirstate.normallookup(lfile)
lfdirstate.write()
oldstandins = lfutil.getstandinsstate(repo)
@@ -1413,6 +1418,13 @@
newstandins = lfutil.getstandinsstate(repo)
filelist = lfutil.getlfilestoupdate(oldstandins, newstandins)
+
+ # to avoid leaving all largefiles as dirty and thus rehash them, mark
+ # all the ones that didn't change as clean
+ for lfile in oldclean.difference(filelist):
+ lfdirstate.normal(lfile)
+ lfdirstate.write()
+
if branchmerge or force or partial:
filelist.extend(s.deleted + s.removed)
--- a/hgext/largefiles/reposetup.py Tue Oct 11 20:39:47 2016 -0300
+++ b/hgext/largefiles/reposetup.py Tue Oct 18 14:13:06 2016 -0500
@@ -164,8 +164,8 @@
# files from lfdirstate
unsure, s = lfdirstate.status(match, [], False, listclean,
False)
- (modified, added, removed, clean) = (s.modified, s.added,
- s.removed, s.clean)
+ (modified, added, removed, deleted, clean) = (
+ s.modified, s.added, s.removed, s.deleted, s.clean)
if parentworking:
for lfile in unsure:
standin = lfutil.standin(lfile)
@@ -206,14 +206,18 @@
removed = [lfile for lfile in removed
if lfutil.standin(lfile) in ctx1]
- # Standins no longer found in lfdirstate has been
- # removed
+ # Standins no longer found in lfdirstate have been deleted
for standin in ctx1.walk(lfutil.getstandinmatcher(self)):
lfile = lfutil.splitstandin(standin)
if not match(lfile):
continue
if lfile not in lfdirstate:
- removed.append(lfile)
+ deleted.append(lfile)
+ # Sync "largefile has been removed" back to the
+ # standin. Removing a file as a side effect of
+ # running status is gross, but the alternatives (if
+ # any) are worse.
+ self.wvfs.unlink(standin)
# Filter result lists
result = list(result)
@@ -237,7 +241,7 @@
normals = [[fn for fn in filelist
if not lfutil.isstandin(fn)]
for filelist in result]
- lfstatus = (modified, added, removed, s.deleted, [], [],
+ lfstatus = (modified, added, removed, deleted, [], [],
clean)
result = [sorted(list1 + list2)
for (list1, list2) in zip(normals, lfstatus)]
--- a/tests/test-largefiles-update.t Tue Oct 11 20:39:47 2016 -0300
+++ b/tests/test-largefiles-update.t Tue Oct 18 14:13:06 2016 -0500
@@ -144,6 +144,7 @@
large1 in #1
$ cat .hglf/large1
58e24f733a964da346e2407a2bee99d9001184f5
+ $ rm normal1.orig
(merge non-existing largefiles from "other" via conflict prompt -
make sure the following commit doesn't abort in a confusing way when trying to
@@ -243,6 +244,7 @@
? largeY
$ test -f .hglf/largeY
[1]
+ $ rm largeY
Test that "hg rollback" restores standins correctly
@@ -285,6 +287,7 @@
58e24f733a964da346e2407a2bee99d9001184f5
$ cat .hglf/large2
1deebade43c8c498a3c8daddac0244dc55d1331d
+ $ rm normalX
Test that "hg status" shows status of largefiles correctly just after
automated commit like rebase/transplant
@@ -598,6 +601,7 @@
58e24f733a964da346e2407a2bee99d9001184f5
$ cat large1
large1 in #1
+ $ rm normal1.orig
Test that rebase updates standins for manually modified largefiles at
the 1st commit of resuming.
@@ -728,6 +732,42 @@
#endif
+Test a fatal error interrupting an update. Verify that status report dirty
+files correctly after an interrupted update. Also verify that checking all
+hashes reveals it isn't clean.
+
+Start with clean dirstates:
+ $ hg up -qcr "8^"
+ $ sleep 1
+ $ hg st
+Update standins without updating largefiles - large1 is modified and largeX is
+added:
+ $ cat << EOF > ../crashupdatelfiles.py
+ > import hgext.largefiles.lfutil
+ > def getlfilestoupdate(oldstandins, newstandins):
+ > raise SystemExit(7)
+ > hgext.largefiles.lfutil.getlfilestoupdate = getlfilestoupdate
+ > EOF
+ $ hg up -Cr "8" --config extensions.crashupdatelfiles=../crashupdatelfiles.py
+ [7]
+Check large1 content and status ... and that update will undo modifications:
+ $ cat large1
+ large1 in #3
+ $ hg st
+ M large1
+ ! largeX
+ $ hg up -Cr .
+ getting changed largefiles
+ 2 largefiles updated, 0 removed
+ 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+ $ cat large1
+ manually modified before 'hg transplant --continue'
+ $ hg st
+Force largefiles rehashing and check that all changes have been caught by
+status and update:
+ $ rm .hg/largefiles/dirstate
+ $ hg st
+
$ cd ..
Test that "hg convert" avoids copying largefiles from the working