mirror of
https://github.com/SkinnyMind/libgit2dart.git
synced 2025-05-05 04:39:07 -04:00
feat(diff): add ability to apply diff
This commit is contained in:
parent
344dba60e9
commit
cd9f38c2bd
4 changed files with 89 additions and 0 deletions
|
@ -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.
|
/// Free a previously allocated diff stats.
|
||||||
void statsFree(Pointer<git_diff_stats> stats) =>
|
void statsFree(Pointer<git_diff_stats> stats) =>
|
||||||
libgit2.git_diff_stats_free(stats);
|
libgit2.git_diff_stats_free(stats);
|
||||||
|
|
|
@ -1046,3 +1046,29 @@ class GitDiffLine {
|
||||||
@override
|
@override
|
||||||
String toString() => 'GitDiffLine.$_name';
|
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';
|
||||||
|
}
|
||||||
|
|
|
@ -798,4 +798,25 @@ class Repository {
|
||||||
}) {
|
}) {
|
||||||
return a.diff(newBlob: b, oldAsPath: aPath, newAsPath: bPath);
|
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,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -194,6 +194,22 @@ index e69de29..c217c63 100644
|
||||||
diff.free();
|
diff.free();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test(
|
||||||
|
'checks if diff can be applied to repository and successfully applies it',
|
||||||
|
() {
|
||||||
|
final diff = Diff.parse(patchText);
|
||||||
|
final file = File('${tmpDir}subdir/modified_file');
|
||||||
|
|
||||||
|
repo.reset('a763aa560953e7cfb87ccbc2f536d665aa4dff22', GitReset.hard);
|
||||||
|
expect(file.readAsStringSync(), '');
|
||||||
|
|
||||||
|
expect(repo.applies(diff), true);
|
||||||
|
repo.apply(diff);
|
||||||
|
expect(file.readAsStringSync(), 'Modified content\n');
|
||||||
|
|
||||||
|
diff.free();
|
||||||
|
});
|
||||||
|
|
||||||
test('successfully creates patch from entry index in diff', () {
|
test('successfully creates patch from entry index in diff', () {
|
||||||
final diff = Diff.parse(patchText);
|
final diff = Diff.parse(patchText);
|
||||||
final patch = Patch.fromDiff(diff, 0);
|
final patch = Patch.fromDiff(diff, 0);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue