resolveFile method
Future<FileResolveOutcome>
resolveFile(
- String mountId,
- String path, {
- required String strategy,
- DriveProgress? onProgress,
Resolves a single path on a directory mount by copying its bytes one
way: accept-local overwrites the node, accept-origin overwrites the
local copy. When the path is absent on the accepted side the other side
is removed. If the file was the mount's last divergence the mount is
re-anchored clean; otherwise its conflicted state is left untouched.
Implementation
Future<FileResolveOutcome> resolveFile(
String mountId,
String path, {
required String strategy,
DriveProgress? onProgress,
}) async {
final record = require(mountId);
if (record.isGit) {
throw DriveException(
'per-file resolve is only supported for directory mounts',
);
}
if (strategy != 'accept-local' && strategy != 'accept-origin') {
throw DriveException(
'per-file resolve needs --accept-local or --accept-origin',
);
}
final outcome = await _withSession(record, (rpc) async {
final local = _localSource(record);
final localEntry = (await local.manifest()).entries[path];
final originEntry = (await ChannelContentSource(
rpc,
).manifest()).entries[path];
if (localEntry == null && originEntry == null) {
throw DriveException('path not found on either side: $path');
}
if (strategy == 'accept-origin') {
if (originEntry == null) {
await local.delete(path);
} else {
_emit(onProgress, ProgressPhase.transferring, 'pulling $path');
final bytes = await rpc.read(path);
await local.writeBytes(
path,
bytes,
executable: originEntry.executable,
);
}
} else {
if (localEntry == null) {
await rpc.delete(path);
} else {
_emit(onProgress, ProgressPhase.transferring, 'pushing $path');
final bytes = await local.readBytes(path);
await rpc.write(path, bytes, executable: localEntry.executable);
}
}
_emit(onProgress, ProgressPhase.done, 'resolved $path');
// Re-read both sides: if the whole tree now matches, the divergence is
// gone and we can re-anchor the mount clean. Otherwise leave it alone —
// other paths still conflict.
final newLocal = await local.manifest();
final newOriginHash = (await ChannelContentSource(rpc).manifest()).hash();
final converged = newLocal.hash() == newOriginHash;
final updated = converged ? _reanchor(record, newLocal) : record;
return FileResolveOutcome(
record: updated,
path: path,
strategy: strategy,
converged: converged,
);
});
store.mounts[mountId] = outcome.record;
await store.save();
return outcome;
}