From 4a91e3a4f74dbc352a1bf24cb80b1837cdfa0141 Mon Sep 17 00:00:00 2001 From: "marcel.kocisek" Date: Thu, 26 Feb 2026 13:37:12 +0100 Subject: [PATCH 1/4] Temp log of diffs --- server/mergin/sync/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/mergin/sync/models.py b/server/mergin/sync/models.py index bc01c523..73c500b3 100644 --- a/server/mergin/sync/models.py +++ b/server/mergin/sync/models.py @@ -1041,7 +1041,7 @@ def construct_checkpoint(self) -> bool: project.storage.geodiff.concat_changes(diffs_paths, self.abs_path) except (GeoDiffLibError, GeoDiffLibConflictError): logging.error( - f"Geodiff: Failed to merge diffs for file {self.file_path_id}" + f"Geodiff: Failed to merge diffs for file {self.file_path_id}. Diffs: {diffs_paths}" ) return False From 4ade8b49da3f4915fc0daf1e2b6957c7074cc456 Mon Sep 17 00:00:00 2001 From: "marcel.kocisek" Date: Thu, 26 Feb 2026 16:13:13 +0100 Subject: [PATCH 2/4] Create also subfolders with diffs --- server/mergin/sync/models.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/server/mergin/sync/models.py b/server/mergin/sync/models.py index 73c500b3..2d4fe953 100644 --- a/server/mergin/sync/models.py +++ b/server/mergin/sync/models.py @@ -1030,7 +1030,9 @@ def construct_checkpoint(self) -> bool: return False project: Project = basefile.file.project - os.makedirs(project.storage.diffs_dir, exist_ok=True) + + # create diffs directory if not exists and subfolders in case of diffs/subfolder/diff-file + os.makedirs(os.path.dirname(self.abs_path), exist_ok=True) try: if len(diffs_paths) == 1: From 6d30574d372e49d64a6c0caebe94ed66c3bda415 Mon Sep 17 00:00:00 2001 From: "marcel.kocisek" Date: Fri, 27 Feb 2026 14:26:22 +0100 Subject: [PATCH 3/4] In case when removed rank > 0 deltas, we still had a file diff - unhandled case when filediff exists in DB --- server/mergin/sync/files.py | 2 +- server/mergin/sync/models.py | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/server/mergin/sync/files.py b/server/mergin/sync/files.py index f0ee09a1..a00834b9 100644 --- a/server/mergin/sync/files.py +++ b/server/mergin/sync/files.py @@ -287,7 +287,7 @@ def to_data_delta(self): version=self.version, ) if self.diffs: - result.diff = self.diffs[0].id + result.diff = None return result diff --git a/server/mergin/sync/models.py b/server/mergin/sync/models.py index 2d4fe953..8b5b2b59 100644 --- a/server/mergin/sync/models.py +++ b/server/mergin/sync/models.py @@ -1359,6 +1359,11 @@ def create_checkpoint( # Patch the delta with the path to the new diff checkpoint item.diff = checkpoint_diff.path db.session.add(checkpoint_diff) + else: + # checkpoint already exists, just patch the delta with the path to the existing diff checkpoint + # this could happen when file diff exists but dela was missing + # this allowing us to remove rank > 0 delta checkpoints in case of inconsistencies + item.diff = existing_diff_checkpoint.path checkpoint_delta = ProjectVersionDelta( project_id=project_id, From 7e25d37a94fac6b34f23bf9e42f94b0be7dce1a5 Mon Sep 17 00:00:00 2001 From: "marcel.kocisek" Date: Mon, 2 Mar 2026 12:15:17 +0100 Subject: [PATCH 4/4] add assertion for update_diff and not diff attribute. --- server/mergin/sync/files.py | 5 +++-- server/mergin/sync/models.py | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/server/mergin/sync/files.py b/server/mergin/sync/files.py index a00834b9..d22358d5 100644 --- a/server/mergin/sync/files.py +++ b/server/mergin/sync/files.py @@ -286,8 +286,6 @@ def to_data_delta(self): change=self.change, version=self.version, ) - if self.diffs: - result.diff = None return result @@ -332,6 +330,9 @@ def make_object(self, data, **kwargs): @post_dump def patch_field(self, data, **kwargs): + assert data.get("change") != PushChangeType.UPDATE_DIFF.value or data.get( + "diff" + ), "Diff file must be provided for update_diff change type" # drop 'diff' key entirely if empty or None as database would expect if not data.get("diff"): data.pop("diff", None) diff --git a/server/mergin/sync/models.py b/server/mergin/sync/models.py index 8b5b2b59..e5f5123d 100644 --- a/server/mergin/sync/models.py +++ b/server/mergin/sync/models.py @@ -1043,7 +1043,7 @@ def construct_checkpoint(self) -> bool: project.storage.geodiff.concat_changes(diffs_paths, self.abs_path) except (GeoDiffLibError, GeoDiffLibConflictError): logging.error( - f"Geodiff: Failed to merge diffs for file {self.file_path_id}. Diffs: {diffs_paths}" + f"Geodiff: Failed to merge diffs for file {self.file_path_id}." ) return False