calculateDiff static method

Future<CommitDiff> calculateDiff({
  1. required Commit thisCommit,
  2. required Commit otherCommit,
  3. dynamic onNoOtherCommitBranchMetaData(
    1. Branch
    )? = onNoCommitBranchMetaData,
  4. dynamic onNoOtherCommitMetaData(
    1. Commit
    )? = onNoCommitMetaData,
  5. dynamic onNoThisCommitBranchMetaData(
    1. Branch
    )? = onNoCommitBranchMetaData,
  6. dynamic onNoThisCommitMetaData(
    1. Commit
    )? = onNoCommitMetaData,
})

Implementation

static Future<CommitDiff> calculateDiff({
  required Commit thisCommit,
  required Commit otherCommit,
  Function(Branch)? onNoOtherCommitBranchMetaData = onNoCommitBranchMetaData,
  Function(Commit)? onNoOtherCommitMetaData = onNoCommitMetaData,
  Function(Branch)? onNoThisCommitBranchMetaData = onNoCommitBranchMetaData,
  Function(Commit)? onNoThisCommitMetaData = onNoCommitMetaData,
}) async {
  //Get a commit files
  Map<String, RepoObjectsData>? thisFiles = thisCommit.getCommitFiles(
    onNoCommitMetaData: onNoThisCommitMetaData,
    onNoCommitBranchMetaData: onNoThisCommitBranchMetaData,
  );

  //Get b commit files
  Map<String, RepoObjectsData>? otherFiles = otherCommit.getCommitFiles(
    onNoCommitBranchMetaData: onNoOtherCommitBranchMetaData,
    onNoCommitMetaData: onNoOtherCommitMetaData,
  );

  if (thisFiles == null && otherFiles == null) {
    return CommitDiff(
      filesDiff: [],
      thisCommit: thisCommit,
      otherCommit: otherCommit,
      statistic: {},
    );
  }
  thisFiles ??= {};
  otherFiles ??= {};

  //Compare this with other
  debugPrintToConsole(
    message:
        "Comparing files from ${thisCommit.sha.hash} commit (${thisFiles.length} files) to ${otherCommit.sha.hash} commit (${otherFiles.length} files)",
  );

  List<FileDiff> filesDiff = [];
  Map<DiffType, int> statistics = {};
  HashSet<String> thisAndOtherFiles = HashSet();
  thisAndOtherFiles.addAll(thisFiles.keys);
  thisAndOtherFiles.addAll(otherFiles.keys);

  Directory tempDirectory = Directory.systemTemp.createTempSync();

  for (String thisOrOtherFileSha in thisAndOtherFiles) {
    debugPrintToConsole(message: thisOrOtherFileSha);

    RepoObjectsData? thisObject = thisFiles[thisOrOtherFileSha];
    RepoObjectsData? otherObject = otherFiles[thisOrOtherFileSha];

    debugPrintToConsole(message: "Comparing", newLine: true);
    debugPrintToConsole(message: "This: -> ${thisObject?.fileName} & sha -> ${thisObject?.sha}", color: CliColor.cyan);
    debugPrintToConsole(message: "Other: -> ${otherObject?.fileName} & sha -> ${otherObject?.sha}", color: CliColor.cyan);

    late DiffType diffType;
    if (thisObject == null) {
      diffType = DiffType.delete;
    } else if (otherObject == null) {
      diffType = DiffType.insert;
    } else if (thisObject.sha == otherObject.sha) {
      diffType = DiffType.same;
    } else {
      File thisTempFile = File(join(tempDirectory.path, thisObject.sha))
        ..writeAsBytesSync(thisObject.fetchObject(thisCommit.branch.repository)?.blob ?? []);
      File otherTempFile = File(join(tempDirectory.path, otherObject.sha))
        ..writeAsBytesSync(otherObject.fetchObject(otherCommit.branch.repository)?.blob ?? []);

      FileDiff fileDiff = await FileDiff.calculateDiff(
        thisName: thisObject.fileName,
        thisFile: thisTempFile,
        otherName: otherObject.fileName,
        otherFile: otherTempFile,
      );
      filesDiff.add(fileDiff);
      diffType = DiffType.modify;

      thisTempFile.deleteSync(recursive: true);
      otherTempFile.deleteSync(recursive: true);
    }

    debugPrintToConsole(message: "Result: ${diffType.name}", color: CliColor.cyan);

    statistics.update(diffType, (o) => o + 1, ifAbsent: () => 1);
  }

  tempDirectory.deleteSync(recursive: true);

  return CommitDiff(
    filesDiff: filesDiff,
    thisCommit: thisCommit,
    otherCommit: otherCommit,
    statistic: statistics,
  );
}