preserveGitStateForIssue function

Future<PreservedGitState?> preserveGitStateForIssue({
  1. String? cwd,
})

Preserve git state for issue submission.

Implementation

Future<PreservedGitState?> preserveGitStateForIssue({String? cwd}) async {
  try {
    if (!await getIsGit(cwd: cwd)) return null;

    if (await isShallowClone(cwd: cwd)) {
      final patch = await _runGit(['diff', 'HEAD'], cwd: cwd);
      return PreservedGitState(
        remoteBaseSha: null,
        remoteBase: null,
        patch: patch.stdout,
        untrackedFiles: [],
        formatPatch: null,
        headSha: null,
        branchName: null,
      );
    }

    final remoteBase = await findRemoteBase(cwd: cwd);
    if (remoteBase == null) {
      final patch = await _runGit(['diff', 'HEAD'], cwd: cwd);
      return PreservedGitState(
        remoteBaseSha: null,
        remoteBase: null,
        patch: patch.stdout,
        untrackedFiles: [],
        formatPatch: null,
        headSha: null,
        branchName: null,
      );
    }

    final mergeBase = await _runGit([
      'merge-base',
      'HEAD',
      remoteBase,
    ], cwd: cwd);
    if (mergeBase.code != 0 || mergeBase.stdout.trim().isEmpty) {
      final patch = await _runGit(['diff', 'HEAD'], cwd: cwd);
      return PreservedGitState(
        remoteBaseSha: null,
        remoteBase: null,
        patch: patch.stdout,
        untrackedFiles: [],
        formatPatch: null,
        headSha: null,
        branchName: null,
      );
    }

    final remoteBaseSha = mergeBase.stdout.trim();
    final results = await Future.wait([
      _runGit(['diff', remoteBaseSha], cwd: cwd),
      _runGit(['format-patch', '$remoteBaseSha..HEAD', '--stdout'], cwd: cwd),
      _runGit(['rev-parse', 'HEAD'], cwd: cwd),
      _runGit(['rev-parse', '--abbrev-ref', 'HEAD'], cwd: cwd),
    ]);

    final patchResult = results[0];
    final formatPatchResult = results[1];
    final headShaResult = results[2];
    final branchResult = results[3];

    String? formatPatch;
    if (formatPatchResult.code == 0 &&
        formatPatchResult.stdout.trim().isNotEmpty) {
      formatPatch = formatPatchResult.stdout;
    }

    final trimmedBranch = branchResult.stdout.trim();
    return PreservedGitState(
      remoteBaseSha: remoteBaseSha,
      remoteBase: remoteBase,
      patch: patchResult.stdout,
      untrackedFiles: [],
      formatPatch: formatPatch,
      headSha: headShaResult.stdout.trim().isEmpty
          ? null
          : headShaResult.stdout.trim(),
      branchName: trimmedBranch.isEmpty || trimmedBranch == 'HEAD'
          ? null
          : trimmedBranch,
    );
  } catch (_) {
    return null;
  }
}