feat(repository): add ability to check status of repo and single file

This commit is contained in:
Aleksey Kulikov 2021-09-07 19:08:28 +03:00
parent db21f2e890
commit 1f2d00b177
4 changed files with 171 additions and 7 deletions

View file

@ -0,0 +1,81 @@
import 'dart:ffi';
import 'package:ffi/ffi.dart';
import 'package:libgit2dart/libgit2dart.dart';
import 'libgit2_bindings.dart';
import '../error.dart';
import '../util.dart';
/// Gather file status information and populate the git_status_list.
///
/// Throws a [LibGit2Error] if error occured.
Pointer<git_status_list> listNew(Pointer<git_repository> repo) {
final out = calloc<Pointer<git_status_list>>();
final error = libgit2.git_status_list_new(out, repo, nullptr);
if (error < 0) {
throw LibGit2Error(libgit2.git_error_last());
} else {
return out.value;
}
}
/// Gets the count of status entries in this list.
///
/// If there are no changes in status (at least according the options given when
/// the status list was created), this can return 0.
int listEntryCount(Pointer<git_status_list> statuslist) {
return libgit2.git_status_list_entrycount(statuslist);
}
/// Get a pointer to one of the entries in the status list.
///
/// The entry is not modifiable and should not be freed.
///
/// Throws [RangeError] if position is out of bounds
Pointer<git_status_entry> getByIndex(
Pointer<git_status_list> statuslist,
int idx,
) {
final result = libgit2.git_status_byindex(statuslist, idx);
if (result == nullptr) {
throw RangeError('Out of bounds');
} else {
return result;
}
}
/// Get file status for a single file.
///
/// This tries to get status for the filename that you give. If no files match that name
/// (in either the HEAD, index, or working directory), this returns GIT_ENOTFOUND.
///
/// If the name matches multiple files (for example, if the path names a directory or if
/// running on a case- insensitive filesystem and yet the HEAD has two entries that both
/// match the path), then this returns GIT_EAMBIGUOUS because it cannot give correct results.
///
/// This does not do any sort of rename detection. Renames require a set of targets and because
/// of the path filtering, there is not enough information to check renames correctly. To check
/// file status with rename detection, there is no choice but to do a full listNew
/// and scan through looking for the path that you are interested in.
///
/// Throws a [LibGit2Error] if error occured.
int file(Pointer<git_repository> repo, String path) {
final out = calloc<Uint32>();
final pathC = path.toNativeUtf8().cast<Int8>();
final error = libgit2.git_status_file(out, repo, pathC);
calloc.free(pathC);
if (error < 0) {
throw LibGit2Error(libgit2.git_error_last());
} else {
final result = out.value;
calloc.free(out);
return result;
}
}
/// Free an existing status list.
void listFree(Pointer<git_status_list> statuslist) =>
libgit2.git_status_list_free(statuslist);