checkoutBranch method

Future<Reference?> checkoutBranch(
  1. String branchName
)

Implementation

Future<Reference?> checkoutBranch(String branchName) async {
  var ref = await refStorage.reference(ReferenceName.branch(branchName));
  if (ref == null || ref.isSymbolic) {
    return null;
  }
  assert(ref.isHash);

  var _headCommit = await headCommit();
  if (_headCommit == null) {
    var result = await objStorage.readCommit(ref.hash!);
    var commit = result.get();
    /*
    if (obj == null) {
      return null;
    }
    */
    var treeObjRes = await objStorage.readTree(commit.treeHash);

    var index = GitIndex(versionNo: 2);
    await _checkoutTree('', treeObjRes.get(), index);
    await indexStorage.writeIndex(index);

    // Set HEAD to to it
    var branchRef = ReferenceName.branch(branchName);
    var headRef = Reference.symbolic(ReferenceName('HEAD'), branchRef);
    await refStorage.saveRef(headRef);

    return ref;
  }

  var res = await objStorage.readCommit(ref.hash!);
  var branchCommit = res.get();
  /*
  if (branchCommitObj == null) {
    return null;
  }*/

  var blobChanges = await diffCommits(
    fromCommit: _headCommit,
    toCommit: branchCommit,
    objStore: objStorage,
  );
  var index = await indexStorage.readIndex();

  for (var change in blobChanges.merged()) {
    if (change.added || change.modified) {
      var to = change.to!;
      var blobObjRes = await objStorage.readBlob(to.hash);
      var blobObj = blobObjRes.get();

      // FIXME: Add file mode
      await fs
          .directory(p.join(workTree, p.dirname(to.path)))
          .create(recursive: true);
      await fs.file(p.join(workTree, to.path)).writeAsBytes(blobObj.blobData);

      await index.updatePath(to.path, to.hash);
    } else if (change.deleted) {
      var from = change.from!;
      await fs.file(p.join(workTree, from.path)).delete(recursive: true);

      // FIXME: What if the parent directory also needs to be removed?
      var dir = fs.directory(p.join(workTree, p.dirname(from.path)));
      await index.removePath(from.path);

      var isEmpty = true;
      await for (var _ in dir.list()) {
        isEmpty = false;
        break;
      }
      if (isEmpty) {
        await dir.delete();
      }
    }
  }

  await indexStorage.writeIndex(index);

  // Set HEAD to to it
  var branchRef = ReferenceName.branch(branchName);
  var headRef = Reference.symbolic(ReferenceName('HEAD'), branchRef);
  await refStorage.saveRef(headRef);

  return ref;
}