feat(diff): add ability to apply diff

This commit is contained in:
Aleksey Kulikov 2021-09-16 18:56:53 +03:00
parent 344dba60e9
commit cd9f38c2bd
4 changed files with 89 additions and 0 deletions

View file

@ -267,6 +267,32 @@ Pointer<git_buf> addToBuf(Pointer<git_patch> patch, Pointer<git_buf> buffer) {
}
}
/// Apply a diff to the given repository, making changes directly in the working directory,
/// the index, or both.
///
/// Throws a [LibGit2Error] if error occured.
bool apply(
Pointer<git_repository> repo,
Pointer<git_diff> diff,
int location, [
bool check = false,
]) {
final opts = calloc<git_apply_options>();
libgit2.git_apply_options_init(opts, GIT_APPLY_OPTIONS_VERSION);
if (check) {
opts.ref.flags = git_apply_flags_t.GIT_APPLY_CHECK;
}
final error = libgit2.git_apply(repo, diff, location, opts);
calloc.free(opts);
if (error < 0) {
return check ? false : throw LibGit2Error(libgit2.git_error_last());
} else {
return true;
}
}
/// Free a previously allocated diff stats.
void statsFree(Pointer<git_diff_stats> stats) =>
libgit2.git_diff_stats_free(stats);

View file

@ -1046,3 +1046,29 @@ class GitDiffLine {
@override
String toString() => 'GitDiffLine.$_name';
}
/// Possible application locations for `apply()`
class GitApplyLocation {
const GitApplyLocation._(this._value, this._name);
final int _value;
final String _name;
/// Apply the patch to the workdir, leaving the index untouched.
/// This is the equivalent of `git apply` with no location argument.
static const workdir = GitApplyLocation._(0, 'workdir');
/// Apply the patch to the index, leaving the working directory
/// untouched. This is the equivalent of `git apply --cached`.
static const index = GitApplyLocation._(1, 'index');
/// Apply the patch to both the working directory and the index.
/// This is the equivalent of `git apply --index`.
static const both = GitApplyLocation._(2, 'both');
static const List<GitApplyLocation> values = [workdir, index, both];
int get value => _value;
@override
String toString() => 'GitApplyLocation.$_name';
}

View file

@ -798,4 +798,25 @@ class Repository {
}) {
return a.diff(newBlob: b, oldAsPath: aPath, newAsPath: bPath);
}
/// Applies the [diff] to the given repository, making changes directly in the working directory.
///
/// Throws a [LibGit2Error] if error occured.
void apply(Diff diff) {
diff_bindings.apply(
_repoPointer,
diff.pointer,
GitApplyLocation.workdir.value,
);
}
/// Checks if the [diff] will apply to HEAD.
bool applies(Diff diff) {
return diff_bindings.apply(
_repoPointer,
diff.pointer,
GitApplyLocation.index.value,
true,
);
}
}