comparison 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
comparison
equal deleted inserted replaced
154:c7df81fb84b7 155:bf74ce3c968d
305 "./@", 305 "./@",
306 use_base64)) 306 use_base64))
307 outfp.flush() 307 outfp.flush()
308 return 308 return
309 309
310 for top, dirs, nondirs in walk.walk( 310 for top, fsobjects in walk.walk(
311 root, 311 root,
312 follow_symlinks=follow_directory_symlinks): 312 follow_symlinks=follow_directory_symlinks):
313 dir_dgst = algorithm[0]() 313 dir_dgst = algorithm[0]()
314 for dn in dirs: 314 for fso in fsobjects:
315 if dn.is_symlink and not follow_directory_symlinks: 315 if fso.is_dir:
316 linktgt = util.fsencode(os.readlink(dn.path)) 316 if fso.is_symlink and not follow_directory_symlinks:
317 linkdgst = algorithm[0]() 317 linktgt = util.fsencode(os.readlink(fso.path))
318 linkdgst.update(b"%d:%s," % (len(linktgt), linktgt)) 318 linkdgst = algorithm[0]()
319 dir_dgst.update(b"1:S,%d:%s," % (len(dn.fsname), dn.fsname)) 319 linkdgst.update(b"%d:%s," % (len(linktgt), linktgt))
320 dir_dgst.update(linkdgst.digest()) 320 dir_dgst.update(b"1:S,%d:%s,"
321 opath = "/".join(top) + "/" + dn.name if top else dn.name 321 % (len(fso.fsname), fso.fsname))
322 dir_dgst.update(linkdgst.digest())
323 opath = "/".join(top) + "/" + fso.name if top else fso.name
324 outfp.write(
325 format_bsd_line(
326 algorithm[1],
327 linkdgst.digest(),
328 "%s/./@" % (opath,),
329 use_base64))
330 outfp.flush()
331 continue
332 # fetch from dir_digests
333 dgst = dir_digests[top + (fso.name,)]
334 dir_dgst.update(b"1:d,%d:%s," % (len(fso.fsname), fso.fsname))
335 dir_dgst.update(dgst)
336 else:
337 dir_dgst.update(b"1:f,%d:%s," % (len(fso.fsname), fso.fsname))
338 if with_metadata_mtime:
339 mtime = datetime.datetime.utcfromtimestamp(
340 int(fso.stat.st_mtime))
341 mtime = mtime.isoformat("T") + "Z"
342 if not isinstance(mtime, bytes):
343 mtime = mtime.encode("ascii")
344 dir_dgst.update(b"5:mtime,%d:%s," % (len(mtime), mtime))
345 dgst = digest.compute_digest_file(
346 algorithm[0], fso.path, use_mmap=use_mmap)
347 dir_dgst.update(dgst)
348 opath = "/".join(top) + "/" + fso.name if top else fso.name
322 outfp.write( 349 outfp.write(
323 format_bsd_line( 350 format_bsd_line(
324 algorithm[1], 351 algorithm[1], dgst, opath, use_base64))
325 linkdgst.digest(),
326 "%s/./@" % (opath,),
327 use_base64))
328 outfp.flush() 352 outfp.flush()
329 continue
330 # fetch from dir_digests
331 dgst = dir_digests[top + (dn.name,)]
332 dir_dgst.update(b"1:d,%d:%s," % (len(dn.fsname), dn.fsname))
333 dir_dgst.update(dgst)
334 for fn in nondirs:
335 dir_dgst.update(b"1:f,%d:%s," % (len(fn.fsname), fn.fsname))
336 if with_metadata_mtime:
337 mtime = datetime.datetime.utcfromtimestamp(
338 int(fn.stat.st_mtime))
339 mtime = mtime.isoformat("T") + "Z"
340 if not isinstance(mtime, bytes):
341 mtime = mtime.encode("ascii")
342 dir_dgst.update(b"5:mtime,%d:%s," % (len(mtime), mtime))
343 dgst = digest.compute_digest_file(
344 algorithm[0], fn.path, use_mmap=use_mmap)
345 dir_dgst.update(dgst)
346 opath = "/".join(top) + "/" + fn.name if top else fn.name
347 outfp.write(
348 format_bsd_line(
349 algorithm[1], dgst, opath, use_base64))
350 outfp.flush()
351 opath = "/".join(top) + "/" if top else "" 353 opath = "/".join(top) + "/" if top else ""
352 outfp.write(format_bsd_line( 354 outfp.write(format_bsd_line(
353 algorithm[1], dir_dgst.digest(), opath, use_base64)) 355 algorithm[1], dir_dgst.digest(), opath, use_base64))
354 outfp.flush() 356 outfp.flush()
355 dir_digests[top] = dir_dgst.digest() 357 dir_digests[top] = dir_dgst.digest()