diff cutils/treesum.py @ 155:bf74ce3c968d

When computing digests use the order imposed by names alone. No different loops for dirs and nondirs.
author Franz Glasner <fzglas.hg@dom66.de>
date Mon, 06 Jan 2025 13:39:12 +0100
parents 3505406ef9f3
children 481cc9b26861
line wrap: on
line diff
--- a/cutils/treesum.py	Mon Jan 06 13:38:09 2025 +0100
+++ b/cutils/treesum.py	Mon Jan 06 13:39:12 2025 +0100
@@ -307,47 +307,49 @@
         outfp.flush()
         return
 
-    for top, dirs, nondirs in walk.walk(
+    for top, fsobjects in walk.walk(
             root,
             follow_symlinks=follow_directory_symlinks):
         dir_dgst = algorithm[0]()
-        for dn in dirs:
-            if dn.is_symlink and not follow_directory_symlinks:
-                linktgt = util.fsencode(os.readlink(dn.path))
-                linkdgst = algorithm[0]()
-                linkdgst.update(b"%d:%s," % (len(linktgt), linktgt))
-                dir_dgst.update(b"1:S,%d:%s," % (len(dn.fsname), dn.fsname))
-                dir_dgst.update(linkdgst.digest())
-                opath = "/".join(top) + "/" + dn.name if top else dn.name
+        for fso in fsobjects:
+            if fso.is_dir:
+                if fso.is_symlink and not follow_directory_symlinks:
+                    linktgt = util.fsencode(os.readlink(fso.path))
+                    linkdgst = algorithm[0]()
+                    linkdgst.update(b"%d:%s," % (len(linktgt), linktgt))
+                    dir_dgst.update(b"1:S,%d:%s,"
+                                    % (len(fso.fsname), fso.fsname))
+                    dir_dgst.update(linkdgst.digest())
+                    opath = "/".join(top) + "/" + fso.name if top else fso.name
+                    outfp.write(
+                        format_bsd_line(
+                            algorithm[1],
+                            linkdgst.digest(),
+                            "%s/./@" % (opath,),
+                            use_base64))
+                    outfp.flush()
+                    continue
+                # fetch from dir_digests
+                dgst = dir_digests[top + (fso.name,)]
+                dir_dgst.update(b"1:d,%d:%s," % (len(fso.fsname), fso.fsname))
+                dir_dgst.update(dgst)
+            else:
+                dir_dgst.update(b"1:f,%d:%s," % (len(fso.fsname), fso.fsname))
+                if with_metadata_mtime:
+                    mtime = datetime.datetime.utcfromtimestamp(
+                        int(fso.stat.st_mtime))
+                    mtime = mtime.isoformat("T") + "Z"
+                    if not isinstance(mtime, bytes):
+                        mtime = mtime.encode("ascii")
+                    dir_dgst.update(b"5:mtime,%d:%s," % (len(mtime), mtime))
+                dgst = digest.compute_digest_file(
+                    algorithm[0], fso.path, use_mmap=use_mmap)
+                dir_dgst.update(dgst)
+                opath = "/".join(top) + "/" + fso.name if top else fso.name
                 outfp.write(
                     format_bsd_line(
-                        algorithm[1],
-                        linkdgst.digest(),
-                        "%s/./@" % (opath,),
-                        use_base64))
+                        algorithm[1], dgst, opath, use_base64))
                 outfp.flush()
-                continue
-            # fetch from dir_digests
-            dgst = dir_digests[top + (dn.name,)]
-            dir_dgst.update(b"1:d,%d:%s," % (len(dn.fsname), dn.fsname))
-            dir_dgst.update(dgst)
-        for fn in nondirs:
-            dir_dgst.update(b"1:f,%d:%s," % (len(fn.fsname), fn.fsname))
-            if with_metadata_mtime:
-                mtime = datetime.datetime.utcfromtimestamp(
-                    int(fn.stat.st_mtime))
-                mtime = mtime.isoformat("T") + "Z"
-                if not isinstance(mtime, bytes):
-                    mtime = mtime.encode("ascii")
-                dir_dgst.update(b"5:mtime,%d:%s," % (len(mtime), mtime))
-            dgst = digest.compute_digest_file(
-                algorithm[0], fn.path, use_mmap=use_mmap)
-            dir_dgst.update(dgst)
-            opath = "/".join(top) + "/" + fn.name if top else fn.name
-            outfp.write(
-                format_bsd_line(
-                    algorithm[1], dgst, opath, use_base64))
-            outfp.flush()
         opath = "/".join(top) + "/" if top else ""
         outfp.write(format_bsd_line(
             algorithm[1], dir_dgst.digest(), opath, use_base64))