mirror of
https://github.com/SkinnyMind/libgit2dart.git
synced 2025-05-04 20:29:08 -04:00
feat(worktree): add base bindings and api
This commit is contained in:
parent
11dbb8195d
commit
a00078ba76
5 changed files with 224 additions and 2 deletions
|
@ -13,5 +13,6 @@ export 'src/blob.dart';
|
||||||
export 'src/tag.dart';
|
export 'src/tag.dart';
|
||||||
export 'src/treebuilder.dart';
|
export 'src/treebuilder.dart';
|
||||||
export 'src/branch.dart';
|
export 'src/branch.dart';
|
||||||
|
export 'src/worktree.dart';
|
||||||
export 'src/error.dart';
|
export 'src/error.dart';
|
||||||
export 'src/git_types.dart';
|
export 'src/git_types.dart';
|
||||||
|
|
94
lib/src/bindings/worktree.dart
Normal file
94
lib/src/bindings/worktree.dart
Normal file
|
@ -0,0 +1,94 @@
|
||||||
|
import 'dart:ffi';
|
||||||
|
import 'package:ffi/ffi.dart';
|
||||||
|
import 'package:libgit2dart/libgit2dart.dart';
|
||||||
|
import 'libgit2_bindings.dart';
|
||||||
|
import '../error.dart';
|
||||||
|
import '../util.dart';
|
||||||
|
|
||||||
|
/// Add a new working tree.
|
||||||
|
///
|
||||||
|
/// Add a new working tree for the repository, that is create the required
|
||||||
|
/// data structures inside the repository and check out the current HEAD at path.
|
||||||
|
///
|
||||||
|
/// Throws a [LibGit2Error] if error occured.
|
||||||
|
Pointer<git_worktree> create(
|
||||||
|
Pointer<git_repository> repo,
|
||||||
|
String name,
|
||||||
|
String path,
|
||||||
|
) {
|
||||||
|
final out = calloc<Pointer<git_worktree>>();
|
||||||
|
final nameC = name.toNativeUtf8().cast<Int8>();
|
||||||
|
final pathC = path.toNativeUtf8().cast<Int8>();
|
||||||
|
final error = libgit2.git_worktree_add(out, repo, nameC, pathC, nullptr);
|
||||||
|
|
||||||
|
calloc.free(nameC);
|
||||||
|
calloc.free(pathC);
|
||||||
|
|
||||||
|
if (error < 0) {
|
||||||
|
throw LibGit2Error(libgit2.git_error_last());
|
||||||
|
} else {
|
||||||
|
return out.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Lookup a working tree by its name for a given repository.
|
||||||
|
///
|
||||||
|
/// Throws a [LibGit2Error] if error occured.
|
||||||
|
Pointer<git_worktree> lookup(Pointer<git_repository> repo, String name) {
|
||||||
|
final out = calloc<Pointer<git_worktree>>();
|
||||||
|
final nameC = name.toNativeUtf8().cast<Int8>();
|
||||||
|
final error = libgit2.git_worktree_lookup(out, repo, nameC);
|
||||||
|
|
||||||
|
calloc.free(nameC);
|
||||||
|
|
||||||
|
if (error < 0) {
|
||||||
|
throw LibGit2Error(libgit2.git_error_last());
|
||||||
|
} else {
|
||||||
|
return out.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Prune working tree.
|
||||||
|
///
|
||||||
|
/// Prune the working tree, that is remove the git data structures on disk.
|
||||||
|
///
|
||||||
|
/// Throws a [LibGit2Error] if error occured.
|
||||||
|
void prune(Pointer<git_worktree> wt) {
|
||||||
|
final error = libgit2.git_worktree_prune(wt, nullptr);
|
||||||
|
|
||||||
|
if (error < 0) {
|
||||||
|
throw LibGit2Error(libgit2.git_error_last());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// List names of linked working trees.
|
||||||
|
///
|
||||||
|
/// Throws a [LibGit2Error] if error occured.
|
||||||
|
List<String> list(Pointer<git_repository> repo) {
|
||||||
|
final out = calloc<git_strarray>();
|
||||||
|
final error = libgit2.git_worktree_list(out, repo);
|
||||||
|
final result = <String>[];
|
||||||
|
|
||||||
|
if (error < 0) {
|
||||||
|
throw LibGit2Error(libgit2.git_error_last());
|
||||||
|
} else {
|
||||||
|
for (var i = 0; i < out.ref.count; i++) {
|
||||||
|
result.add(out.ref.strings[i].cast<Utf8>().toDartString());
|
||||||
|
}
|
||||||
|
calloc.free(out);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Retrieve the name of the worktree.
|
||||||
|
String name(Pointer<git_worktree> wt) {
|
||||||
|
return libgit2.git_worktree_name(wt).cast<Utf8>().toDartString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Retrieve the filesystem path for the worktree.
|
||||||
|
String path(Pointer<git_worktree> wt) {
|
||||||
|
return libgit2.git_worktree_path(wt).cast<Utf8>().toDartString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Free a previously allocated worktree.
|
||||||
|
void free(Pointer<git_worktree> wt) => libgit2.git_worktree_free(wt);
|
|
@ -1,10 +1,9 @@
|
||||||
import 'dart:ffi';
|
import 'dart:ffi';
|
||||||
import 'package:libgit2dart/libgit2dart.dart';
|
|
||||||
|
|
||||||
import 'bindings/libgit2_bindings.dart';
|
import 'bindings/libgit2_bindings.dart';
|
||||||
import 'bindings/repository.dart' as bindings;
|
import 'bindings/repository.dart' as bindings;
|
||||||
import 'bindings/merge.dart' as merge_bindings;
|
import 'bindings/merge.dart' as merge_bindings;
|
||||||
import 'bindings/object.dart' as object_bindings;
|
import 'bindings/object.dart' as object_bindings;
|
||||||
|
import 'branch.dart';
|
||||||
import 'commit.dart';
|
import 'commit.dart';
|
||||||
import 'config.dart';
|
import 'config.dart';
|
||||||
import 'index.dart';
|
import 'index.dart';
|
||||||
|
@ -17,6 +16,7 @@ import 'blob.dart';
|
||||||
import 'git_types.dart';
|
import 'git_types.dart';
|
||||||
import 'signature.dart';
|
import 'signature.dart';
|
||||||
import 'tag.dart';
|
import 'tag.dart';
|
||||||
|
import 'tree.dart';
|
||||||
import 'util.dart';
|
import 'util.dart';
|
||||||
|
|
||||||
class Repository {
|
class Repository {
|
||||||
|
|
54
lib/src/worktree.dart
Normal file
54
lib/src/worktree.dart
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
import 'dart:ffi';
|
||||||
|
import 'bindings/libgit2_bindings.dart';
|
||||||
|
import 'bindings/worktree.dart' as bindings;
|
||||||
|
import 'repository.dart';
|
||||||
|
|
||||||
|
class Worktree {
|
||||||
|
/// Initializes a new instance of [Worktree] class by creating new worktree
|
||||||
|
/// with provided [Repository] object worktree [name] and [path].
|
||||||
|
///
|
||||||
|
/// Should be freed with `free()` to release allocated memory.
|
||||||
|
///
|
||||||
|
/// Throws a [LibGit2Error] if error occured.
|
||||||
|
Worktree.create({
|
||||||
|
required Repository repo,
|
||||||
|
required String name,
|
||||||
|
required String path,
|
||||||
|
}) {
|
||||||
|
_worktreePointer = bindings.create(repo.pointer, name, path);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Initializes a new instance of [Worktree] class by looking up existing worktree
|
||||||
|
/// with provided [Repository] object and worktree [name].
|
||||||
|
///
|
||||||
|
/// Should be freed with `free()` to release allocated memory.
|
||||||
|
///
|
||||||
|
/// Throws a [LibGit2Error] if error occured.
|
||||||
|
Worktree.lookup(Repository repo, String name) {
|
||||||
|
_worktreePointer = bindings.lookup(repo.pointer, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Pointer to memory address for allocated branch object.
|
||||||
|
late final Pointer<git_worktree> _worktreePointer;
|
||||||
|
|
||||||
|
/// Returns list of names of linked working trees.
|
||||||
|
///
|
||||||
|
/// Throws a [LibGit2Error] if error occured.
|
||||||
|
static List<String> list(Repository repo) => bindings.list(repo.pointer);
|
||||||
|
|
||||||
|
/// Returns the name of the worktree.
|
||||||
|
String get name => bindings.name(_worktreePointer);
|
||||||
|
|
||||||
|
/// Returns the filesystem path for the worktree.
|
||||||
|
String get path => bindings.path(_worktreePointer);
|
||||||
|
|
||||||
|
/// Prunes working tree.
|
||||||
|
///
|
||||||
|
/// Prune the working tree, that is remove the git data structures on disk.
|
||||||
|
///
|
||||||
|
/// Throws a [LibGit2Error] if error occured.
|
||||||
|
void prune() => bindings.prune(_worktreePointer);
|
||||||
|
|
||||||
|
/// Releases memory allocated for worktree object.
|
||||||
|
void free() => bindings.free(_worktreePointer);
|
||||||
|
}
|
73
test/worktree_test.dart
Normal file
73
test/worktree_test.dart
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
import 'dart:io';
|
||||||
|
import 'package:test/test.dart';
|
||||||
|
import 'package:libgit2dart/libgit2dart.dart';
|
||||||
|
import 'helpers/util.dart';
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
late Repository repo;
|
||||||
|
final tmpDir = '${Directory.systemTemp.path}/worktree_testrepo/';
|
||||||
|
final worktreeDir = '${Directory.systemTemp.path}/worktree';
|
||||||
|
|
||||||
|
setUp(() async {
|
||||||
|
if (await Directory(tmpDir).exists()) {
|
||||||
|
await Directory(tmpDir).delete(recursive: true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (await Directory(worktreeDir).exists()) {
|
||||||
|
await Directory(worktreeDir).delete(recursive: true);
|
||||||
|
}
|
||||||
|
|
||||||
|
await copyRepo(
|
||||||
|
from: Directory('test/assets/testrepo/'),
|
||||||
|
to: await Directory(tmpDir).create(),
|
||||||
|
);
|
||||||
|
repo = Repository.open(tmpDir);
|
||||||
|
});
|
||||||
|
|
||||||
|
tearDown(() async {
|
||||||
|
repo.free();
|
||||||
|
await Directory(tmpDir).delete(recursive: true);
|
||||||
|
if (await Directory(worktreeDir).exists()) {
|
||||||
|
await Directory(worktreeDir).delete(recursive: true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
group('Worktree', () {
|
||||||
|
test('successfully creates worktree at provided path', () {
|
||||||
|
const worktreeName = 'worktree';
|
||||||
|
expect(Worktree.list(repo), []);
|
||||||
|
|
||||||
|
final worktree = Worktree.create(
|
||||||
|
repo: repo,
|
||||||
|
name: worktreeName,
|
||||||
|
path: worktreeDir,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(Worktree.list(repo), [worktreeName]);
|
||||||
|
expect(repo.branches.list(), contains(worktreeName));
|
||||||
|
expect(worktree.name, worktreeName);
|
||||||
|
expect(worktree.path, worktreeDir);
|
||||||
|
expect(File('$worktreeDir/.git').existsSync(), true);
|
||||||
|
|
||||||
|
worktree.free();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('successfully prunes worktree', () {
|
||||||
|
const worktreeName = 'worktree';
|
||||||
|
expect(Worktree.list(repo), []);
|
||||||
|
|
||||||
|
final worktree = Worktree.create(
|
||||||
|
repo: repo,
|
||||||
|
name: worktreeName,
|
||||||
|
path: worktreeDir,
|
||||||
|
);
|
||||||
|
expect(Worktree.list(repo), [worktreeName]);
|
||||||
|
|
||||||
|
Directory(worktreeDir).deleteSync(recursive: true);
|
||||||
|
worktree.prune();
|
||||||
|
expect(Worktree.list(repo), []);
|
||||||
|
|
||||||
|
worktree.free();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue