feat(reset): add ability to pass checkout options to reset(...) API method (#72)

This commit is contained in:
Aleksey Kulikov 2022-06-23 18:37:27 +03:00 committed by GitHub
parent 5f829dd1ca
commit 4a36922129
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 84 additions and 4 deletions

View file

@ -17,13 +17,48 @@ import 'package:libgit2dart/src/util.dart';
/// HARD reset will trigger a MIXED reset and the working directory will be
/// replaced with the content of the index. (Untracked and ignored files will
/// be left alone, however.)
///
/// Throws a [LibGit2Error] if error occured.
void reset({
required Pointer<git_repository> repoPointer,
required Pointer<git_object> targetPointer,
required int resetType,
required Pointer<git_checkout_options> checkoutOptsPointer,
int? strategy,
String? checkoutDirectory,
List<String>? pathspec,
}) {
libgit2.git_reset(repoPointer, targetPointer, resetType, checkoutOptsPointer);
final opts = calloc<git_checkout_options>();
libgit2.git_checkout_options_init(opts, GIT_CHECKOUT_OPTIONS_VERSION);
if (strategy != null) {
opts.ref.checkout_strategy = strategy;
}
if (checkoutDirectory != null) {
opts.ref.target_directory = checkoutDirectory.toChar();
}
var pathPointers = <Pointer<Char>>[];
Pointer<Pointer<Char>> strArray = nullptr;
if (pathspec != null) {
pathPointers = pathspec.map((e) => e.toChar()).toList();
strArray = calloc(pathspec.length);
for (var i = 0; i < pathspec.length; i++) {
strArray[i] = pathPointers[i];
}
opts.ref.paths.strings = strArray;
opts.ref.paths.count = pathspec.length;
}
final error = libgit2.git_reset(repoPointer, targetPointer, resetType, opts);
for (final p in pathPointers) {
calloc.free(p);
}
calloc.free(strArray);
calloc.free(opts);
if (error < 0) {
throw LibGit2Error(libgit2.git_error_last());
}
}
/// Updates some entries in the index from the target commit tree.

View file

@ -557,8 +557,23 @@ class Repository extends Equatable {
///
/// [resetType] is one of the [GitReset] flags.
///
/// [strategy], [checkoutDirectory] and [pathspec] are optional checkout
/// options to be used for a HARD reset.
///
/// [strategy] is optional combination of [GitCheckout] flags.
///
/// [checkoutDirectory] is optional alternative checkout path to workdir.
///
/// [pathspec] is optional list of files to checkout.
///
/// Throws a [LibGit2Error] if error occured.
void reset({required Oid oid, required GitReset resetType}) {
void reset({
required Oid oid,
required GitReset resetType,
Set<GitCheckout>? strategy,
String? checkoutDirectory,
List<String>? pathspec,
}) {
final object = object_bindings.lookup(
repoPointer: _repoPointer,
oidPointer: oid.pointer,
@ -569,7 +584,9 @@ class Repository extends Equatable {
repoPointer: _repoPointer,
targetPointer: object,
resetType: resetType.value,
checkoutOptsPointer: nullptr,
strategy: strategy?.fold(0, (acc, e) => acc! | e.value),
checkoutDirectory: checkoutDirectory,
pathspec: pathspec,
);
object_bindings.free(object);

View file

@ -50,6 +50,34 @@ void main() {
expect(diff.deltas.length, 1);
});
test('resets with provided checkout options', () {
expect(file.readAsStringSync(), 'Feature edit\n');
repo.reset(
oid: repo[sha],
resetType: GitReset.hard,
strategy: {GitCheckout.conflictStyleZdiff3},
pathspec: ['feature_file'],
);
expect(file.readAsStringSync(), isEmpty);
});
test(
'throws when trying to reset and error occurs',
testOn: '!windows',
() {
expect(
() => repo.reset(
oid: repo[sha],
resetType: GitReset.hard,
checkoutDirectory: '',
),
throwsA(isA<LibGit2Error>()),
);
},
);
group('resetDefault', () {
test('updates entry in the index', () {
file.writeAsStringSync('new edit');