mirror of
https://github.com/SkinnyMind/libgit2dart.git
synced 2025-05-05 04:39:07 -04:00
feat(index): add base bindings and api
This commit is contained in:
parent
9a737f8d3e
commit
5b8f089723
5 changed files with 523 additions and 2 deletions
227
lib/src/bindings/index.dart
Normal file
227
lib/src/bindings/index.dart
Normal file
|
@ -0,0 +1,227 @@
|
||||||
|
import 'dart:ffi';
|
||||||
|
import 'package:ffi/ffi.dart';
|
||||||
|
import '../error.dart';
|
||||||
|
import 'libgit2_bindings.dart';
|
||||||
|
import '../util.dart';
|
||||||
|
|
||||||
|
/// Update the contents of an existing index object in memory by reading from the hard disk.
|
||||||
|
///
|
||||||
|
/// If force is true, this performs a "hard" read that discards in-memory changes and
|
||||||
|
/// always reloads the on-disk index data. If there is no on-disk version,
|
||||||
|
/// the index will be cleared.
|
||||||
|
///
|
||||||
|
/// If force is false, this does a "soft" read that reloads the index data from disk only
|
||||||
|
/// if it has changed since the last time it was loaded. Purely in-memory index data
|
||||||
|
/// will be untouched. Be aware: if there are changes on disk, unwritten in-memory changes
|
||||||
|
/// are discarded.
|
||||||
|
///
|
||||||
|
/// Throws a [LibGit2Error] if error occured.
|
||||||
|
void read(Pointer<git_index> index, bool force) {
|
||||||
|
final forceC = force == true ? 1 : 0;
|
||||||
|
final error = libgit2.git_index_read(index, forceC);
|
||||||
|
|
||||||
|
if (error < 0) {
|
||||||
|
throw LibGit2Error(libgit2.git_error_last());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Find the first position of any entries which point to given path in the Git index.
|
||||||
|
bool find(Pointer<git_index> index, String path) {
|
||||||
|
final pathC = path.toNativeUtf8().cast<Int8>();
|
||||||
|
final result = libgit2.git_index_find(nullptr, index, pathC);
|
||||||
|
calloc.free(pathC);
|
||||||
|
|
||||||
|
return result == git_error_code.GIT_ENOTFOUND ? false : true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the count of entries currently in the index.
|
||||||
|
int entryCount(Pointer<git_index> index) => libgit2.git_index_entrycount(index);
|
||||||
|
|
||||||
|
/// Get a pointer to one of the entries in the index based on position.
|
||||||
|
///
|
||||||
|
/// The entry is not modifiable and should not be freed.
|
||||||
|
///
|
||||||
|
/// Throws error if position is out of bounds.
|
||||||
|
Pointer<git_index_entry> getByIndex(Pointer<git_index> index, int n) {
|
||||||
|
final result = libgit2.git_index_get_byindex(index, n);
|
||||||
|
|
||||||
|
if (result == nullptr) {
|
||||||
|
throw RangeError('Out of bounds');
|
||||||
|
} else {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get a pointer to one of the entries in the index based on path.
|
||||||
|
///
|
||||||
|
///The entry is not modifiable and should not be freed.
|
||||||
|
///
|
||||||
|
/// Throws error if entry isn't found.
|
||||||
|
Pointer<git_index_entry> getByPath(
|
||||||
|
Pointer<git_index> index,
|
||||||
|
String path,
|
||||||
|
int stage,
|
||||||
|
) {
|
||||||
|
final pathC = path.toNativeUtf8().cast<Int8>();
|
||||||
|
final result = libgit2.git_index_get_bypath(index, pathC, stage);
|
||||||
|
calloc.free(pathC);
|
||||||
|
|
||||||
|
if (result == nullptr) {
|
||||||
|
throw ArgumentError.value('$path was not found');
|
||||||
|
} else {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Clear the contents (all the entries) of an index object.
|
||||||
|
///
|
||||||
|
/// This clears the index object in memory; changes must be explicitly written to
|
||||||
|
/// disk for them to take effect persistently.
|
||||||
|
///
|
||||||
|
/// Throws a [LibGit2Error] if error occured.
|
||||||
|
void clear(Pointer<git_index> index) {
|
||||||
|
final error = libgit2.git_index_clear(index);
|
||||||
|
|
||||||
|
if (error < 0) {
|
||||||
|
throw LibGit2Error(libgit2.git_error_last());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Add or update an index entry from an in-memory struct.
|
||||||
|
///
|
||||||
|
/// If a previous index entry exists that has the same path and stage as the given `sourceEntry`,
|
||||||
|
/// it will be replaced. Otherwise, the `sourceEntry` will be added.
|
||||||
|
///
|
||||||
|
/// Throws a [LibGit2Error] if error occured.
|
||||||
|
void add(Pointer<git_index> index, Pointer<git_index_entry> sourceEntry) {
|
||||||
|
final error = libgit2.git_index_add(index, sourceEntry);
|
||||||
|
|
||||||
|
if (error < 0) {
|
||||||
|
throw LibGit2Error(libgit2.git_error_last());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Add or update an index entry from a file on disk.
|
||||||
|
///
|
||||||
|
/// The file path must be relative to the repository's working folder and must be readable.
|
||||||
|
///
|
||||||
|
/// This method will fail in bare index instances.
|
||||||
|
///
|
||||||
|
/// This forces the file to be added to the index, not looking at gitignore rules.
|
||||||
|
///
|
||||||
|
/// If this file currently is the result of a merge conflict, this file will no longer be
|
||||||
|
/// marked as conflicting. The data about the conflict will be moved to the "resolve undo"
|
||||||
|
/// (REUC) section.
|
||||||
|
///
|
||||||
|
/// Throws a [LibGit2Error] if error occured.
|
||||||
|
void addByPath(Pointer<git_index> index, String path) {
|
||||||
|
final pathC = path.toNativeUtf8().cast<Int8>();
|
||||||
|
final error = libgit2.git_index_add_bypath(index, pathC);
|
||||||
|
calloc.free(pathC);
|
||||||
|
|
||||||
|
if (error < 0) {
|
||||||
|
throw LibGit2Error(libgit2.git_error_last());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Add or update index entries matching files in the working directory.
|
||||||
|
///
|
||||||
|
/// This method will fail in bare index instances.
|
||||||
|
///
|
||||||
|
/// The `pathspec` is a list of file names or shell glob patterns that will be matched
|
||||||
|
/// against files in the repository's working directory. Each file that matches will be
|
||||||
|
/// added to the index (either updating an existing entry or adding a new entry).
|
||||||
|
///
|
||||||
|
/// Throws a [LibGit2Error] if error occured.
|
||||||
|
void addAll(Pointer<git_index> index, List<String> pathspec) {
|
||||||
|
var pathspecC = calloc<git_strarray>();
|
||||||
|
final List<Pointer<Int8>> pathPointers =
|
||||||
|
pathspec.map((e) => e.toNativeUtf8().cast<Int8>()).toList();
|
||||||
|
final Pointer<Pointer<Int8>> strArray = calloc(pathspec.length);
|
||||||
|
|
||||||
|
for (var i = 0; i < pathspec.length; i++) {
|
||||||
|
strArray[i] = pathPointers[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
pathspecC.ref.strings = strArray;
|
||||||
|
pathspecC.ref.count = pathspec.length;
|
||||||
|
|
||||||
|
final error = libgit2.git_index_add_all(
|
||||||
|
index,
|
||||||
|
pathspecC,
|
||||||
|
0,
|
||||||
|
nullptr,
|
||||||
|
nullptr,
|
||||||
|
);
|
||||||
|
|
||||||
|
calloc.free(pathspecC);
|
||||||
|
calloc.free(strArray);
|
||||||
|
for (var p in pathPointers) {
|
||||||
|
calloc.free(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error < 0) {
|
||||||
|
throw LibGit2Error(libgit2.git_error_last());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Write an existing index object from memory back to disk using an atomic file lock.
|
||||||
|
///
|
||||||
|
/// Throws a [LibGit2Error] if error occured.
|
||||||
|
void write(Pointer<git_index> index) {
|
||||||
|
final error = libgit2.git_index_write(index);
|
||||||
|
|
||||||
|
if (error < 0) {
|
||||||
|
throw LibGit2Error(libgit2.git_error_last());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Remove an entry from the index.
|
||||||
|
///
|
||||||
|
/// Throws a [LibGit2Error] if error occured.
|
||||||
|
void remove(Pointer<git_index> index, String path, int stage) {
|
||||||
|
final pathC = path.toNativeUtf8().cast<Int8>();
|
||||||
|
final error = libgit2.git_index_remove(index, pathC, stage);
|
||||||
|
calloc.free(pathC);
|
||||||
|
|
||||||
|
if (error < 0) {
|
||||||
|
throw LibGit2Error(libgit2.git_error_last());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Remove all matching index entries.
|
||||||
|
///
|
||||||
|
/// Throws a [LibGit2Error] if error occured.
|
||||||
|
void removeAll(Pointer<git_index> index, List<String> pathspec) {
|
||||||
|
final pathspecC = calloc<git_strarray>();
|
||||||
|
final List<Pointer<Int8>> pathPointers =
|
||||||
|
pathspec.map((e) => e.toNativeUtf8().cast<Int8>()).toList();
|
||||||
|
final Pointer<Pointer<Int8>> strArray = calloc(pathspec.length);
|
||||||
|
|
||||||
|
for (var i = 0; i < pathspec.length; i++) {
|
||||||
|
strArray[i] = pathPointers[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
pathspecC.ref.strings = strArray;
|
||||||
|
pathspecC.ref.count = pathspec.length;
|
||||||
|
|
||||||
|
final error = libgit2.git_index_remove_all(
|
||||||
|
index,
|
||||||
|
pathspecC,
|
||||||
|
nullptr,
|
||||||
|
nullptr,
|
||||||
|
);
|
||||||
|
|
||||||
|
calloc.free(pathspecC);
|
||||||
|
calloc.free(strArray);
|
||||||
|
for (var p in pathPointers) {
|
||||||
|
calloc.free(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error < 0) {
|
||||||
|
throw LibGit2Error(libgit2.git_error_last());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Free an existing index object.
|
||||||
|
void free(Pointer<git_index> index) => libgit2.git_index_free(index);
|
133
lib/src/index.dart
Normal file
133
lib/src/index.dart
Normal file
|
@ -0,0 +1,133 @@
|
||||||
|
import 'dart:ffi';
|
||||||
|
import 'package:ffi/ffi.dart';
|
||||||
|
import 'bindings/libgit2_bindings.dart';
|
||||||
|
import 'bindings/index.dart' as bindings;
|
||||||
|
import 'util.dart';
|
||||||
|
|
||||||
|
class Index {
|
||||||
|
/// Initializes a new instance of [Index] class from provided
|
||||||
|
/// pointer to index object in memory.
|
||||||
|
///
|
||||||
|
/// Should be freed with `free()` to release allocated memory.
|
||||||
|
Index(this._indexPointer) {
|
||||||
|
libgit2.git_libgit2_init();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Pointer to memory address for allocated index object.
|
||||||
|
late final Pointer<git_index> _indexPointer;
|
||||||
|
|
||||||
|
/// Returns index entry located at provided 0-based position or string path.
|
||||||
|
///
|
||||||
|
/// Throws error if position is out of bounds or entry isn't found at path.
|
||||||
|
IndexEntry operator [](Object value) {
|
||||||
|
if (value is int) {
|
||||||
|
return IndexEntry(bindings.getByIndex(_indexPointer, value));
|
||||||
|
} else {
|
||||||
|
return IndexEntry(bindings.getByPath(_indexPointer, value as String, 0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Checks whether entry at provided [path] is in the git index or not.
|
||||||
|
bool contains(String path) => bindings.find(_indexPointer, path);
|
||||||
|
|
||||||
|
/// Returns the count of entries currently in the index.
|
||||||
|
int get count => bindings.entryCount(_indexPointer);
|
||||||
|
|
||||||
|
/// Clears the contents (all the entries) of an index object.
|
||||||
|
///
|
||||||
|
/// This clears the index object in memory; changes must be explicitly written to
|
||||||
|
/// disk for them to take effect persistently.
|
||||||
|
///
|
||||||
|
/// Throws a [LibGit2Error] if error occured.
|
||||||
|
void clear() => bindings.clear(_indexPointer);
|
||||||
|
|
||||||
|
/// Adds or updates an index entry from an [IndexEntry] or from a file on disk.
|
||||||
|
///
|
||||||
|
/// If a previous index entry exists that has the same path and stage as the given `entry`,
|
||||||
|
/// it will be replaced. Otherwise, the `entry` will be added.
|
||||||
|
///
|
||||||
|
/// The file path must be relative to the repository's working folder and must be readable.
|
||||||
|
///
|
||||||
|
/// This method will fail in bare index instances.
|
||||||
|
///
|
||||||
|
/// Throws a [LibGit2Error] if error occured.
|
||||||
|
void add(Object entry) {
|
||||||
|
if (entry is IndexEntry) {
|
||||||
|
bindings.add(_indexPointer, entry._indexEntryPointer);
|
||||||
|
} else {
|
||||||
|
bindings.addByPath(_indexPointer, entry as String);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Adds or updates index entries matching files in the working directory.
|
||||||
|
///
|
||||||
|
/// This method will fail in bare index instances.
|
||||||
|
///
|
||||||
|
/// The `pathspec` is a list of file names or shell glob patterns that will be matched
|
||||||
|
/// against files in the repository's working directory. Each file that matches will be
|
||||||
|
/// added to the index (either updating an existing entry or adding a new entry).
|
||||||
|
///
|
||||||
|
/// Throws a [LibGit2Error] if error occured.
|
||||||
|
void addAll(List<String> pathspec) {
|
||||||
|
bindings.addAll(_indexPointer, pathspec);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Updates the contents of an existing index object in memory by reading from the hard disk.
|
||||||
|
///
|
||||||
|
/// If force is true (default), this performs a "hard" read that discards in-memory changes and
|
||||||
|
/// always reloads the on-disk index data. If there is no on-disk version,
|
||||||
|
/// the index will be cleared.
|
||||||
|
///
|
||||||
|
/// If force is false, this does a "soft" read that reloads the index data from disk only
|
||||||
|
/// if it has changed since the last time it was loaded. Purely in-memory index data
|
||||||
|
/// will be untouched. Be aware: if there are changes on disk, unwritten in-memory changes
|
||||||
|
/// are discarded.
|
||||||
|
///
|
||||||
|
/// Throws a [LibGit2Error] if error occured.
|
||||||
|
void read({bool force = true}) => bindings.read(_indexPointer, force);
|
||||||
|
|
||||||
|
/// Writes an existing index object from memory back to disk using an atomic file lock.
|
||||||
|
///
|
||||||
|
/// Throws a [LibGit2Error] if error occured.
|
||||||
|
void write() => bindings.write(_indexPointer);
|
||||||
|
|
||||||
|
/// Removes an entry from the index.
|
||||||
|
///
|
||||||
|
/// Throws a [LibGit2Error] if error occured.
|
||||||
|
void remove(String path, [int stage = 0]) =>
|
||||||
|
bindings.remove(_indexPointer, path, stage);
|
||||||
|
|
||||||
|
/// Remove all matching index entries.
|
||||||
|
///
|
||||||
|
/// Throws a [LibGit2Error] if error occured.
|
||||||
|
void removeAll(List<String> path) => bindings.removeAll(_indexPointer, path);
|
||||||
|
|
||||||
|
/// Releases memory allocated for index object.
|
||||||
|
void free() {
|
||||||
|
bindings.free(_indexPointer);
|
||||||
|
libgit2.git_libgit2_shutdown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class IndexEntry {
|
||||||
|
/// Initializes a new instance of [IndexEntry] class.
|
||||||
|
IndexEntry(this._indexEntryPointer);
|
||||||
|
|
||||||
|
/// Pointer to memory address for allocated index entry object.
|
||||||
|
late final Pointer<git_index_entry> _indexEntryPointer;
|
||||||
|
|
||||||
|
/// Returns path to file.
|
||||||
|
String get path => _indexEntryPointer.ref.path.cast<Utf8>().toDartString();
|
||||||
|
|
||||||
|
/// Returns sha-1 of file.
|
||||||
|
String get sha {
|
||||||
|
var hex = StringBuffer();
|
||||||
|
for (var i = 0; i < 20; i++) {
|
||||||
|
hex.write(_indexEntryPointer.ref.id.id[i].toRadixString(16));
|
||||||
|
}
|
||||||
|
return hex.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns mode of file.
|
||||||
|
int get mode => _indexEntryPointer.ref.mode;
|
||||||
|
}
|
|
@ -44,8 +44,8 @@ class Reference {
|
||||||
late final Oid oid;
|
late final Oid oid;
|
||||||
late final bool isDirect;
|
late final bool isDirect;
|
||||||
|
|
||||||
if (target.runtimeType == Oid) {
|
if (target is Oid) {
|
||||||
oid = target as Oid;
|
oid = target;
|
||||||
isDirect = true;
|
isDirect = true;
|
||||||
} else if (isValidShaHex(target as String)) {
|
} else if (isValidShaHex(target as String)) {
|
||||||
if (target.length == 40) {
|
if (target.length == 40) {
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import 'dart:ffi';
|
import 'dart:ffi';
|
||||||
|
import 'index.dart';
|
||||||
import 'odb.dart';
|
import 'odb.dart';
|
||||||
import 'oid.dart';
|
import 'oid.dart';
|
||||||
import 'reference.dart';
|
import 'reference.dart';
|
||||||
|
@ -188,8 +189,15 @@ class Repository {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns [Reference] object pointing to repository head.
|
/// Returns [Reference] object pointing to repository head.
|
||||||
|
///
|
||||||
|
/// Must be freed once it's no longer being used.
|
||||||
Reference get head => Reference(bindings.head(_repoPointer));
|
Reference get head => Reference(bindings.head(_repoPointer));
|
||||||
|
|
||||||
|
/// Returns [Index] file for this repository.
|
||||||
|
///
|
||||||
|
/// Must be freed once it's no longer being used.
|
||||||
|
Index get index => Index(bindings.index(_repoPointer));
|
||||||
|
|
||||||
/// Returns [Odb] for this repository.
|
/// Returns [Odb] for this repository.
|
||||||
///
|
///
|
||||||
/// ODB Object must be freed once it's no longer being used.
|
/// ODB Object must be freed once it's no longer being used.
|
||||||
|
|
153
test/index_test.dart
Normal file
153
test/index_test.dart
Normal file
|
@ -0,0 +1,153 @@
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
|
import 'package:test/test.dart';
|
||||||
|
import 'package:libgit2dart/src/index.dart';
|
||||||
|
import 'package:libgit2dart/src/repository.dart';
|
||||||
|
import 'package:libgit2dart/src/error.dart';
|
||||||
|
|
||||||
|
import 'helpers/util.dart';
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
late Repository repo;
|
||||||
|
late Index index;
|
||||||
|
final tmpDir = '${Directory.systemTemp.path}/index_testrepo/';
|
||||||
|
|
||||||
|
setUp(() async {
|
||||||
|
if (await Directory(tmpDir).exists()) {
|
||||||
|
await Directory(tmpDir).delete(recursive: true);
|
||||||
|
}
|
||||||
|
await copyRepo(
|
||||||
|
from: Directory('test/assets/testrepo/'),
|
||||||
|
to: await Directory(tmpDir).create(),
|
||||||
|
);
|
||||||
|
repo = Repository.open(tmpDir);
|
||||||
|
index = repo.index;
|
||||||
|
});
|
||||||
|
|
||||||
|
tearDown(() async {
|
||||||
|
index.free();
|
||||||
|
repo.free();
|
||||||
|
await Directory(tmpDir).delete(recursive: true);
|
||||||
|
});
|
||||||
|
|
||||||
|
group('Index', () {
|
||||||
|
const fileSha = 'e69de29bb2d1d6434b8b29ae775ad8c2e48c5391';
|
||||||
|
const featureFileSha = '9c78c21d6680a7ffebc76f7ac68cacc11d8f48bc';
|
||||||
|
|
||||||
|
test('returns number of entries', () {
|
||||||
|
expect(index.count, 3);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('returns mode of index entry', () {
|
||||||
|
expect(index['file'].mode, 33188);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('returns index entry at provided position', () {
|
||||||
|
expect(index[2].path, 'file');
|
||||||
|
expect(index['file'].sha, fileSha);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('returns index entry at provided path', () {
|
||||||
|
expect(index['file'].path, 'file');
|
||||||
|
expect(index['file'].sha, fileSha);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('throws if provided entry position is out of bounds', () {
|
||||||
|
expect(() => index[10], throwsA(isA<RangeError>()));
|
||||||
|
});
|
||||||
|
|
||||||
|
test('throws if provided entry path is not found', () {
|
||||||
|
expect(() => index[10], throwsA(isA<ArgumentError>()));
|
||||||
|
});
|
||||||
|
|
||||||
|
test('clears the contents', () {
|
||||||
|
expect(index.count, 3);
|
||||||
|
index.clear();
|
||||||
|
expect(index.count, 0);
|
||||||
|
});
|
||||||
|
|
||||||
|
group('add()', () {
|
||||||
|
test('successfully adds with provided IndexEntry', () {
|
||||||
|
final entry = index['file'];
|
||||||
|
|
||||||
|
index.add(entry);
|
||||||
|
expect(index['file'].sha, fileSha);
|
||||||
|
expect(index.count, 3);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('successfully adds with provided path string', () {
|
||||||
|
index.add('file');
|
||||||
|
expect(index['file'].sha, fileSha);
|
||||||
|
expect(index.count, 3);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('throws if file not found at provided path', () {
|
||||||
|
expect(() => index.add('not_there'), throwsA(isA<LibGit2Error>()));
|
||||||
|
});
|
||||||
|
|
||||||
|
test('throws if index of bare repository', () {
|
||||||
|
final bare = Repository.open('test/assets/empty_bare.git');
|
||||||
|
final bareIndex = bare.index;
|
||||||
|
|
||||||
|
expect(() => bareIndex.add('config'), throwsA(isA<LibGit2Error>()));
|
||||||
|
|
||||||
|
bareIndex.free();
|
||||||
|
bare.free();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
group('addAll()', () {
|
||||||
|
test('successfully adds with provided pathspec', () {
|
||||||
|
index.clear();
|
||||||
|
index.addAll(['file', 'feature_file']);
|
||||||
|
|
||||||
|
expect(index.count, 2);
|
||||||
|
expect(index['file'].sha, fileSha);
|
||||||
|
expect(index['feature_file'].sha, featureFileSha);
|
||||||
|
|
||||||
|
index.clear();
|
||||||
|
index.addAll(['[f]*']);
|
||||||
|
|
||||||
|
expect(index.count, 2);
|
||||||
|
expect(index['file'].sha, fileSha);
|
||||||
|
expect(index['feature_file'].sha, featureFileSha);
|
||||||
|
|
||||||
|
index.clear();
|
||||||
|
index.addAll(['feature_f???']);
|
||||||
|
|
||||||
|
expect(index.count, 1);
|
||||||
|
expect(index['feature_file'].sha, featureFileSha);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('writes to disk', () {
|
||||||
|
expect(index.count, 3);
|
||||||
|
|
||||||
|
File('$tmpDir/new_file').createSync();
|
||||||
|
|
||||||
|
index.add('new_file');
|
||||||
|
index.write();
|
||||||
|
|
||||||
|
index.clear();
|
||||||
|
index.read();
|
||||||
|
expect(index['new_file'].path, 'new_file');
|
||||||
|
expect(index.count, 4);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('removes an entry', () {
|
||||||
|
expect(index.contains('feature_file'), true);
|
||||||
|
index.remove('feature_file');
|
||||||
|
expect(index.contains('feature_file'), false);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('removes all entries with matching pathspec', () {
|
||||||
|
expect(index.contains('file'), true);
|
||||||
|
expect(index.contains('feature_file'), true);
|
||||||
|
|
||||||
|
index.removeAll(['[f]*']);
|
||||||
|
|
||||||
|
expect(index.contains('file'), false);
|
||||||
|
expect(index.contains('feature_file'), false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue