[PATCH bfiles] bfupdate: detect big files where only the execute bit needs updating

Geoff Crossland geoff.crossland at linguamatics.com
Tue Jul 5 08:50:07 CDT 2011


# HG changeset patch
# User Geoff Crossland <gcrossland at linguamatics.com>
# Date 1309861085 -3600
# Node ID b18fb7734d6bf5c01d4733065c7455fd96492193
# Parent  f0512849f1634922b6edccc162e9553b45f56b37
bfupdate: detect big files where only the execute bit needs updating

diff --git a/bfiles/bfcommands.py b/bfiles/bfcommands.py
--- a/bfiles/bfcommands.py
+++ b/bfiles/bfcommands.py
@@ -396,12 +396,17 @@
     store = basestore._open_store(ui, repo)
     updated = removed = 0
 
+    # Build a list of all files that we want to update.  Some are
+    # modified but already have the right contents (i.e. only their x
+    # bit has changed), so avoid going to the central store for them.
     # Use dirstate.walk() rather than repo.walk() for performance: we do
     # not care about unknown files at all, so don't waste time iterating
     # over them.  Should be safe since users should not create files in
     # .hgbfiles; if they do, we'll ignore them here and that's just
     # fine.
-    want_files = []
+    want_files_count = 0
+    success0 = []
+    still_want = []
     for standin in sorted(bfutil.dirstate_walk(repo.dirstate, matcher)):
         want_hash = bfutil._read_standin(repo, standin)
         filename = bfutil._split_standin(standin)
@@ -409,17 +414,25 @@
         if (latest_hash and
               latest_hash == want_hash and
               os.path.isfile(repo.wjoin(filename))):
-            continue
-
-        want_files.append((filename, want_hash))
+            want_mode = os.stat(repo.wjoin(standin)).st_mode & 0100
+            latest_mode = os.stat(repo.wjoin(filename)).st_mode & 0100
+            if latest_mode == want_mode:
+                continue
+            else:
+                want_files_count += 1
+                success0.append((filename, want_hash))
+                continue
+        want_files_count += 1
+        still_want.append((filename, want_hash))
 
     # Some revisions might be stashed in .hg/bfiles/{pending,committed}
     # -- e.g. anything that has been bfadded, bfrefreshed, or committed,
     # but not yet bfput.  Go there first: should be faster than hitting
     # the central store.
     success1 = []
+    t = still_want
     still_want = []
-    for (filename, hash) in want_files:
+    for (filename, hash) in t:
         found = False
         for dir in ('pending', 'committed'):
             pfilename = repo.join(os.path.join(
@@ -436,12 +449,12 @@
 
     # Now go to the central store for whatever we didn't find locally.
     (success2, missing) = store.get(still_want)
-    success = success1 + success2
-    del success1, success2
-    assert len(success) + len(missing) == len(want_files), \
+    success = success0 + success1 + success2
+    del success0, success1, success2
+    assert len(success) + len(missing) == want_files_count, \
            ('some requested files not accounted for: '
             'wanted %d files, got %d, missing %d'
-            % (len(want_files), len(success), len(missing)))
+            % (want_files_count, len(success), len(missing)))
 
     # Fix permissions of successfully downloaded files.
     umask = os.umask(0777)
diff --git a/tests/test-update.t b/tests/test-update.t
--- a/tests/test-update.t
+++ b/tests/test-update.t
@@ -312,3 +312,31 @@
   getting sub/big3
   2 big files updated, 0 removed
   $ hg bfstatus
+
+create a clone with two changesets that differ only in the x-bit on a big file, then update between them
+  $ old=`umask`
+  $ umask 0070
+  $ cd ..
+  $ hg clone -q repo1 repo3 -r3
+  $ cd repo3
+  $ hg bfupdate -q
+  $ chmod a-x sub/big3
+  $ hg bfrefresh -v
+  sub/big3
+  1 big files refreshed
+  $ $PYTHON $TESTDIR/lsmode.py sub/big3
+  100606        204  sub/big3
+  $ hg commit -m"remove x bit from sub/big3"
+  $ hg update -r3
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg bfupdate -v
+  1 big files updated, 0 removed
+  $ $PYTHON $TESTDIR/lsmode.py sub/big3
+  100707        204  sub/big3
+  $ hg update -r4
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg bfupdate -v
+  1 big files updated, 0 removed
+  $ $PYTHON $TESTDIR/lsmode.py sub/big3
+  100606        204  sub/big3
+  $ umask $old


More information about the Mercurial-devel mailing list