This is an automated email from the ASF dual-hosted git repository.

sbp pushed a commit to branch sbp
in repository https://gitbox.apache.org/repos/asf/tooling-trusted-releases.git


The following commit(s) were added to refs/heads/sbp by this push:
     new 499e88d  Detect only content changes in tree comparisons
499e88d is described below

commit 499e88d1fc05611bd1ba3549fbda885b5b9ba4c2
Author: Sean B. Palmer <[email protected]>
AuthorDate: Thu Feb 5 17:13:02 2026 +0000

    Detect only content changes in tree comparisons
---
 atr/tasks/checks/compare.py       | 18 +++++++++++-------
 tests/unit/test_checks_compare.py | 22 ++++++++++++++++++++++
 2 files changed, 33 insertions(+), 7 deletions(-)

diff --git a/atr/tasks/checks/compare.py b/atr/tasks/checks/compare.py
index 7cb41a6..f209287 100644
--- a/atr/tasks/checks/compare.py
+++ b/atr/tasks/checks/compare.py
@@ -261,17 +261,21 @@ def _compare_trees_rsync(repo_dir: pathlib.Path, 
archive_dir: pathlib.Path) -> T
             continue
         rel_path: str | None = None
         is_repo_only = False
-        if line.startswith("*deleting "):
-            rel_path = line.removeprefix("*deleting ").strip().rstrip("/")
-        elif line.startswith("deleting "):
-            rel_path = line.removeprefix("deleting ").strip().rstrip("/")
+        is_content_diff = False
+        if line.startswith("*deleting ") or line.startswith("deleting "):
+            prefix = "*deleting " if line.startswith("*deleting ") else 
"deleting "
+            rel_path = line.removeprefix(prefix).strip().rstrip("/")
+            is_content_diff = True
         else:
             parts = line.split(" ", 1)
             if len(parts) == 2:
                 flags = parts[0]
                 rel_path = parts[1].rstrip("/")
-                if flags.startswith(">f") and (len(flags) >= 3) and (flags[2] 
== "+"):
-                    is_repo_only = True
+                if (len(flags) >= 3) and (flags[1] == "f"):
+                    if (flags[0] == ">") and (flags[2] == "+"):
+                        is_repo_only = True
+                    elif (flags[0] in (">", "<", "c")) and (flags[2] in ("c", 
"s", "+")):
+                        is_content_diff = True
         if not rel_path:
             continue
         full_repo = repo_dir / rel_path
@@ -279,7 +283,7 @@ def _compare_trees_rsync(repo_dir: pathlib.Path, 
archive_dir: pathlib.Path) -> T
         if full_repo.is_file() or full_archive.is_file():
             if is_repo_only:
                 repo_only.add(rel_path)
-            else:
+            elif is_content_diff:
                 invalid.add(rel_path)
     return TreeComparisonResult(invalid, repo_only)
 
diff --git a/tests/unit/test_checks_compare.py 
b/tests/unit/test_checks_compare.py
index f87248c..22126de 100644
--- a/tests/unit/test_checks_compare.py
+++ b/tests/unit/test_checks_compare.py
@@ -439,6 +439,28 @@ def test_compare_trees_rsync_content_differs(monkeypatch: 
pytest.MonkeyPatch, tm
     assert result.repo_only == set()
 
 
+def test_compare_trees_rsync_ignores_timestamp_only(monkeypatch: 
pytest.MonkeyPatch, tmp_path: pathlib.Path) -> None:
+    repo_dir = tmp_path / "repo"
+    archive_dir = tmp_path / "archive"
+    _make_tree(repo_dir, ["a.txt"])
+    _make_tree(archive_dir, ["a.txt"])
+    completed = subprocess.CompletedProcess(
+        args=["rsync"],
+        returncode=0,
+        stdout=".f..t...... a.txt\n",
+        stderr="",
+    )
+    run_recorder = RunRecorder(completed)
+
+    monkeypatch.setattr(shutil, "which", lambda _name: "/usr/bin/rsync")
+    monkeypatch.setattr(subprocess, "run", run_recorder)
+
+    result = atr.tasks.checks.compare._compare_trees_rsync(repo_dir, 
archive_dir)
+
+    assert result.invalid == set()
+    assert result.repo_only == set()
+
+
 def test_compare_trees_rsync_distinct_files(monkeypatch: pytest.MonkeyPatch, 
tmp_path: pathlib.Path) -> None:
     repo_dir = tmp_path / "repo"
     archive_dir = tmp_path / "archive"


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to