@@ -272,6 +272,30 @@ def root():
272272
273273 has_comparator = Config .comparator is not None
274274
275+ def collect_one_sided (existing : Path , root : Path , message : str ) -> list [dict ]:
276+ """Walk a directory present on only one side.
277+
278+ Emits one row per comparable file inside it so each file stays viewable
279+ (on the present side) and copyable to the reference, just like a missing
280+ file. Recurses into nested directories.
281+ """
282+ entries = []
283+
284+ for child in sorted (existing .iterdir (), key = lambda p : p .name ):
285+ if child .is_dir ():
286+ entries .extend (collect_one_sided (child , root , message ))
287+ elif child .is_file () and comparable_file (child ):
288+ entries .append (
289+ {
290+ "path" : str (child .relative_to (root )),
291+ "comparable" : True ,
292+ "message" : message ,
293+ "result" : "different" ,
294+ }
295+ )
296+
297+ return entries
298+
275299 def collect (a : Path , b : Path ) -> list [dict ]:
276300 """Single O(n) walk producing flat leaf rows.
277301
@@ -327,16 +351,18 @@ def collect(a: Path, b: Path) -> list[dict]:
327351 )
328352
329353 for name in sorted (left_dirs ^ right_dirs ):
330- rel = common_path / name
331- where = "reference (A)" if name in right_dirs else "monitored (B)"
332- entries .append (
333- {
334- "path" : str (rel ) + "/" ,
335- "comparable" : False ,
336- "message" : f"directory missing in { where } " ,
337- "result" : "different" ,
338- }
339- )
354+ if name in left_dirs :
355+ entries .extend (
356+ collect_one_sided (
357+ a / name , Config .path_a , "missing in monitored (B)"
358+ )
359+ )
360+ else :
361+ entries .extend (
362+ collect_one_sided (
363+ b / name , Config .path_b , "missing in reference (A)"
364+ )
365+ )
340366
341367 for name in sorted (left_dirs & right_dirs ):
342368 entries .extend (collect (a / name , b / name ))
0 commit comments