Patchwork [4,of,5,STABLE] largefiles: drop orphan entries from lfdristat at "hg rollback"

login
register
mail settings
Submitter Katsunori FUJIWARA
Date Aug. 11, 2014, 1:39 p.m.
Message ID <84bf4aa8363406dc5da2.1407764382@feefifofum>
Download mbox | patch
Permalink /patch/5340/
State Accepted
Headers show

Comments

Katsunori FUJIWARA - Aug. 11, 2014, 1:39 p.m.
# HG changeset patch
# User FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
# Date 1407763783 -32400
#      Mon Aug 11 22:29:43 2014 +0900
# Branch stable
# Node ID 84bf4aa8363406dc5da25d9a7819a66acb1e259c
# Parent  acb2e0c42aad2b1287ecf36b95bed18af26a692b
largefiles: drop orphan entries from lfdristat at "hg rollback"

Before this patch, newly added (but not yet committed) largefiles
aren't treated as unknown ("?") after "hg rollback".

After "hg rollback", lfdirstate still contains "A" status entries for
such largefiles, even though corresponding entries for standins are
already dropped from dirstate.

Such "orphan" entries in lfdirstate prevent unknown (large)files in
the working directory from being listed up in "unknown" list. The code
path in "if working" route of "lfilesrepo.status" below drops
largefiles tracked in lfdirstate from "unknown" list:

    lfiles = set(lfdirstate._map)
    # Unknown files
    result[4] = set(result[4]).difference(lfiles)

This patch drops orphan entries from lfdristate at "hg rollback".

This is a temporary way to fix with less changes. For fundamental
resolution of this kind of problems in the future, lfdirstate should
be rollback-ed as a part of transaction, as same as dirstate.

Patch

diff --git a/hgext/largefiles/overrides.py b/hgext/largefiles/overrides.py
--- a/hgext/largefiles/overrides.py
+++ b/hgext/largefiles/overrides.py
@@ -1147,9 +1147,13 @@ 
                      partial=lfutil.isstandin)
 
         lfdirstate = lfutil.openlfdirstate(ui, repo)
+        orphans = set(lfdirstate)
         lfiles = lfutil.listlfiles(repo)
         for file in lfiles:
             lfutil.synclfdirstate(repo, lfdirstate, file, True)
+            orphans.discard(file)
+        for lfile in orphans:
+            lfdirstate.drop(lfile)
         lfdirstate.write()
     finally:
         wlock.release()
diff --git a/tests/test-largefiles-update.t b/tests/test-largefiles-update.t
--- a/tests/test-largefiles-update.t
+++ b/tests/test-largefiles-update.t
@@ -107,12 +107,16 @@ 
   $ echo largeX > largeX
   $ hg add --large largeX
   $ hg commit -m 'will be rollback-ed soon'
+  $ echo largeY > largeY
+  $ hg add --large largeY
   $ hg status -A large1
   large1: No such file or directory
   $ hg status -A large2
   ? large2
   $ hg status -A largeX
   C largeX
+  $ hg status -A largeY
+  A largeY
   $ hg rollback
   repository tip rolled back to revision 3 (undo commit)
   working directory now based on revision 3
@@ -122,5 +126,7 @@ 
   R large2
   $ hg status -A largeX
   A largeX
+  $ hg status -A largeY
+  ? largeY
 
   $ cd ..