ProjectMerge.h header

#include <ew/app/ProjectMerge.h>

Namespace ew::app

FileMerge struct

struct ew::app::FileMerge

How one file was reconciled between a local and a remote snapshot of a project directory, both taken against a common ancestor (base). A project is a folder of text files, so reconciliation is per file: most files change on only one side (or not at all) and resolve automatically; only a file both sides edited over the same lines – or an edit/delete race – needs a human choice.

Members

enum class Status { Unchanged, TakenLocal, TakenRemote, AutoMerged, Conflict, AddedLocal, AddedRemote, AddedConflict, RemovedLocal, RemovedRemote, DeleteEditConflict }

The reconciliation outcome for one path.

QString ew::app::FileMerge::path

The project-relative path this outcome is for.

Status ew::app::FileMerge::status =

The reconciliation status.

QString ew::app::FileMerge::content

The resolved content to write for an auto-resolvable status (empty for the removed statuses). For Conflict / AddedConflict / DeleteEditConflict this holds a sensible default (the local side) pending the user's choice.

QString ew::app::FileMerge::mergedText

For Conflict / AddedConflict: the line-merged text with diff3 conflict markers. Empty for non-conflicting statuses.

QString ew::app::FileMerge::localContent

For a conflict (Conflict / AddedConflict / DeleteEditConflict): the file's whole content on the local and remote sides. A resolver picks one of these – each a complete, valid file – rather than the marked mergedText, which for a structured file would not parse. Empty for non-conflict statuses (and one side is empty for a delete/edit race).

QString ew::app::FileMerge::remoteContent

The remote side's whole file content (the other resolver choice; see localContent).

bool ew::app::FileMerge::isConflict() const

Whether this outcome needs a human decision (Conflict / AddedConflict / DeleteEditConflict).

NonConflictWrites struct

struct ew::app::NonConflictWrites

The writes for every changed file that does NOT conflict, when each is safe to persist. This is the conflict-tolerant companion to planReconcileApply: it skips conflicting files (a caller resolves those per-file) but still gathers the clean, auto-merged changes – so a per-file conflict resolver can apply the clean changes alongside the user's conflict choices without losing them. complete is false if any non-conflicting file's merged content would be invalid for its kind (a .json that no longer parses); a caller should then not apply a partial result.

Members

QMap<QString, QString> ew::app::NonConflictWrites::writes

Project-relative path -> content for each changed, non-conflicting, valid file.

std::vector<QString> ew::app::NonConflictWrites::deletes

Project-relative paths of the non-conflicting deletions (a file removed on one side and left untouched on the other). A caller applying the clean changes must delete these too, or a reload from disk would resurrect an in-app deletion.

bool ew::app::NonConflictWrites::complete = true

False if a non-conflicting file's merged content failed validation (so it was left out).

ProjectMerge struct

struct ew::app::ProjectMerge

The reconciliation of a whole project directory: one FileMerge per touched path, plus a tally.

Members

std::vector<FileMerge> ew::app::ProjectMerge::files

The per-file outcomes, ordered by path.

bool ew::app::ProjectMerge::hasConflicts() const

Whether any file needs a human decision.

int ew::app::ProjectMerge::conflictCount() const

The number of files that need a human decision.

ReconcileApplyPlan struct

struct ew::app::ReconcileApplyPlan

A vetted plan to bring a project folder in line with a conflict-free reconcile: the files to (over)write with their resolved content and the files to delete. It is safe to apply only when the merge had no conflicts AND every file it would write is still valid for its kind – in particular a merged .json must parse – so applying the plan can never leave the project in a corrupt, unloadable state. When not safe, nothing should be written and reason says why (a short diagnostic the caller can log or fold into a message).

Members

QMap<QString, QString> ew::app::ReconcileApplyPlan::writes

Project-relative path -> the content to write there.

std::vector<QString> ew::app::ReconcileApplyPlan::deletes

Project-relative paths to delete.

bool ew::app::ReconcileApplyPlan::safe = false

Whether the plan is safe to apply (no conflicts and every write validated).

QString ew::app::ReconcileApplyPlan::reason

When safe is false, a short reason (e.g. "conflicts" or which file failed to validate).

Functions

NonConflictWrites ew::app::autoResolvableWrites(const ProjectMerge &merge)

Gathers the non-conflicting writes and deletions from merge (see NonConflictWrites). Only conflicting files are excluded.

ProjectMerge ew::app::mergeProjectSnapshots(const QMap< QString, QString > &base, const QMap< QString, QString > &local, const QMap< QString, QString > &remote)

Reconciles a local and a remote snapshot of a project directory against their common ancestor base (a per-file diff3). Each snapshot maps a project-relative path to the file's UTF-8 text; the caller excludes binary files (they cannot be line-merged). Files that changed on only one side – including adds and deletes – resolve automatically; files both sides changed over the same lines, and edit/delete races, are flagged as conflicts for the caller to resolve.

ReconcileApplyPlan ew::app::planReconcileApply(const ProjectMerge &merge)

Builds a ReconcileApplyPlan from merge. A merge with conflicts, or one whose merged .json content no longer parses, yields an unsafe plan with empty writes/deletes – so a caller that only applies safe plans can never corrupt the folder-of-text store. Unchanged files are ignored.