merge with i18n stable
authorKevin Bullock <kbullock+mercurial@ringworld.org>
Tue, 18 Oct 2016 14:13:06 -0500
branchstable
changeset 30214 fc11bb10425f
parent 30191 328545c7d8a1 (diff)
parent 30213 a76e04b674c4 (current diff)
child 30215 438173c41587
merge with i18n
--- 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