exportEvents function

Future<String?> exportEvents(
  1. String repo,
  2. List<Event> events, {
  3. String branch = eventLogBranch,
})

Export events onto the branch: one commit per event, in sequence order, skipping sequence numbers the branch already has. Returns the new head sha (or the existing one when nothing was appended). The ref update is a compare-and-swap: a concurrent exporter fails loudly instead of forking the log; retrying is safe.

Implementation

Future<String?> exportEvents(String repo, List<Event> events,
    {String branch = eventLogBranch}) async {
  await initEventLogRepo(repo);
  final existing = <int>{};
  for (final e in await importEvents(repo, branch: branch)) {
    existing.add(e.seq);
  }
  final ordered = List<Event>.from(events)
    ..sort((a, b) => a.seq.compareTo(b.seq));
  var head = await branchHead(repo, branch);
  final before = head;
  for (final event in ordered) {
    if (existing.contains(event.seq)) continue;
    final blob = await gitText(repo, ['hash-object', '-w', '--stdin'],
        inputBytes: event.marshalDc());
    final tree = await gitText(repo, ['mktree'],
        inputBytes:
            utf8.encode('100644 blob $blob\t$gitBlobPath\n'));
    final args = ['commit-tree', tree, '-m', commitMessage(event)];
    if (head != null) {
      args.add('-p');
      args.add(head);
    }
    head = await gitText(repo, args, envExtra: commitEnv(event));
    existing.add(event.seq);
  }
  if (head != null && head != before) {
    await gitText(
        repo, ['update-ref', 'refs/heads/$branch', head, before ?? zeroSha]);
  }
  return head;
}