rfp_mergin_list() reports has_conflict per project, straight from the
server. That is the right signal for "does this project need attention" and
the wrong one for "is it safe to read this file", because it cannot
distinguish a conflict over an empty rebuilt form from one holding a season's
records. This resolves it to the file level.
Value
Tibble with one row per conflicted copy: path (the copy),
base_path (the file it is a copy of), base_present (whether the project
still holds that file at this version), author, version (the version
the author diverged from), and size, checksum and mtime passed
through from the listing. Zero rows, with those columns, when there are no
conflicts.
Details
Measured on newgraph/restoration_wedzin_kwa v112: the project reports
has_conflict = TRUE and carries eight conflicted copies, of which the four
current-season ones are empty. A consumer failing closed on the project flag
refuses to read the project over four empty files; one ignoring it silently
drops whatever a populated conflict holds. Knowing which files is the only
thing between those two.
What is and is not derived from the server
The candidate set comes from rfp_mergin_files() - the server's own
listing at a given version - rather than from a walk of somebody's clone,
which is what makes this usable without one.
The parse is a regular expression, because there is no structured field
to read: a conflicted copy is an ordinary file whose name encodes its author
and divergence version. So the claim here is not that a regex is avoided, it
is that the pattern is anchored to Mergin's actual naming and has a tested
negative case - as against matching the substring "conflicted", which a
file legitimately named notes (conflicted requirements).md also satisfies.
Two details that make the difference between a working guard and one that silently never fires:
The extension is on the far side of the parenthetical. Stripping from
" (conflicted copy"onwards turnsform_vri_qa (conflicted copy, u v95).gpkgintoform_vri_qa, which never matches theform_vri_qa.gpkga caller is about to read. It is reattached here.Matching is on the full path, not the basename, so a stale conflict under
data_field/2023/archive/cannot be mistaken for one over a same-named file at the project root.
What this does not tell you
Whether the conflicted copy holds any records. The file listing carries a
size and no row count, and none is derivable - an empty 53-column GeoPackage
is a nonzero and unpredictable size. Deciding that means fetching the file
with rfp_mergin_file_get() and opening it, which is the caller's call to
make: a listing function that quietly starts transferring files is a worse
thing to have than an extra step.
See also
Other mergin:
rfp_mergin_file_get(),
rfp_mergin_files(),
rfp_mergin_list(),
rfp_mergin_workspaces()
