mirror of
https://github.com/SkinnyMind/libgit2dart.git
synced 2025-05-05 04:39:07 -04:00
feat(worktree): add ability to create worktree from provided reference
This commit is contained in:
parent
a00078ba76
commit
db21f2e890
6 changed files with 80 additions and 5 deletions
|
@ -158,6 +158,22 @@ bool isHead(Pointer<git_reference> branch) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Determine if any HEAD points to the current branch.
|
||||||
|
///
|
||||||
|
/// This will iterate over all known linked repositories (usually in the form of worktrees)
|
||||||
|
/// and report whether any HEAD is pointing at the current branch.
|
||||||
|
///
|
||||||
|
/// Throws a [LibGit2Error] if error occured.
|
||||||
|
bool isCheckedOut(Pointer<git_reference> branch) {
|
||||||
|
final result = libgit2.git_branch_is_checked_out(branch);
|
||||||
|
|
||||||
|
if (result < 0) {
|
||||||
|
throw LibGit2Error(libgit2.git_error_last());
|
||||||
|
} else {
|
||||||
|
return result == 1 ? true : false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Get the branch name.
|
/// Get the branch name.
|
||||||
///
|
///
|
||||||
/// Given a reference object, this will check that it really is a branch
|
/// Given a reference object, this will check that it really is a branch
|
||||||
|
|
|
@ -15,14 +15,23 @@ Pointer<git_worktree> create(
|
||||||
Pointer<git_repository> repo,
|
Pointer<git_repository> repo,
|
||||||
String name,
|
String name,
|
||||||
String path,
|
String path,
|
||||||
|
Pointer<git_reference>? ref,
|
||||||
) {
|
) {
|
||||||
final out = calloc<Pointer<git_worktree>>();
|
final out = calloc<Pointer<git_worktree>>();
|
||||||
final nameC = name.toNativeUtf8().cast<Int8>();
|
final nameC = name.toNativeUtf8().cast<Int8>();
|
||||||
final pathC = path.toNativeUtf8().cast<Int8>();
|
final pathC = path.toNativeUtf8().cast<Int8>();
|
||||||
final error = libgit2.git_worktree_add(out, repo, nameC, pathC, nullptr);
|
final opts =
|
||||||
|
calloc<git_worktree_add_options>(sizeOf<git_worktree_add_options>());
|
||||||
|
opts.ref.version = 1;
|
||||||
|
opts.ref.lock = 0;
|
||||||
|
if (ref != null) {
|
||||||
|
opts.ref.ref = ref;
|
||||||
|
}
|
||||||
|
final error = libgit2.git_worktree_add(out, repo, nameC, pathC, opts);
|
||||||
|
|
||||||
calloc.free(nameC);
|
calloc.free(nameC);
|
||||||
calloc.free(pathC);
|
calloc.free(pathC);
|
||||||
|
calloc.free(opts);
|
||||||
|
|
||||||
if (error < 0) {
|
if (error < 0) {
|
||||||
throw LibGit2Error(libgit2.git_error_last());
|
throw LibGit2Error(libgit2.git_error_last());
|
||||||
|
|
|
@ -115,11 +115,19 @@ class Branch {
|
||||||
return Branch(bindings.rename(_branchPointer, newName, force));
|
return Branch(bindings.rename(_branchPointer, newName, force));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Determines if HEAD points to the given branch.
|
/// Checks if HEAD points to the given branch.
|
||||||
///
|
///
|
||||||
/// Throws a [LibGit2Error] if error occured.
|
/// Throws a [LibGit2Error] if error occured.
|
||||||
bool get isHead => bindings.isHead(_branchPointer);
|
bool get isHead => bindings.isHead(_branchPointer);
|
||||||
|
|
||||||
|
/// Checks if any HEAD points to the current branch.
|
||||||
|
///
|
||||||
|
/// This will iterate over all known linked repositories (usually in the form of worktrees)
|
||||||
|
/// and report whether any HEAD is pointing at the current branch.
|
||||||
|
///
|
||||||
|
/// Throws a [LibGit2Error] if error occured.
|
||||||
|
bool get isCheckedOut => bindings.isCheckedOut(_branchPointer);
|
||||||
|
|
||||||
/// Returns the branch name.
|
/// Returns the branch name.
|
||||||
///
|
///
|
||||||
/// Given a reference object, this will check that it really is a branch
|
/// Given a reference object, this will check that it really is a branch
|
||||||
|
|
|
@ -134,12 +134,14 @@ class Reference {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Pointer to memory address for allocated reference object.
|
|
||||||
late Pointer<git_reference> _refPointer;
|
late Pointer<git_reference> _refPointer;
|
||||||
|
|
||||||
/// Pointer to memory address for allocated repository object.
|
/// Pointer to memory address for allocated repository object.
|
||||||
late final Pointer<git_repository> _repoPointer;
|
late final Pointer<git_repository> _repoPointer;
|
||||||
|
|
||||||
|
/// Pointer to memory address for allocated reference object.
|
||||||
|
Pointer<git_reference> get pointer => _refPointer;
|
||||||
|
|
||||||
/// Returns the type of the reference.
|
/// Returns the type of the reference.
|
||||||
ReferenceType get type {
|
ReferenceType get type {
|
||||||
return bindings.referenceType(_refPointer) == 1
|
return bindings.referenceType(_refPointer) == 1
|
||||||
|
|
|
@ -1,11 +1,16 @@
|
||||||
import 'dart:ffi';
|
import 'dart:ffi';
|
||||||
import 'bindings/libgit2_bindings.dart';
|
import 'bindings/libgit2_bindings.dart';
|
||||||
import 'bindings/worktree.dart' as bindings;
|
import 'bindings/worktree.dart' as bindings;
|
||||||
|
import 'reference.dart';
|
||||||
import 'repository.dart';
|
import 'repository.dart';
|
||||||
|
|
||||||
class Worktree {
|
class Worktree {
|
||||||
/// Initializes a new instance of [Worktree] class by creating new worktree
|
/// Initializes a new instance of [Worktree] class by creating new worktree
|
||||||
/// with provided [Repository] object worktree [name] and [path].
|
/// with provided [Repository] object worktree [name], [path] and optional [ref]
|
||||||
|
/// [Reference] object.
|
||||||
|
///
|
||||||
|
/// If [ref] is provided, no new branch will be created but specified [ref] will
|
||||||
|
/// be used instead.
|
||||||
///
|
///
|
||||||
/// Should be freed with `free()` to release allocated memory.
|
/// Should be freed with `free()` to release allocated memory.
|
||||||
///
|
///
|
||||||
|
@ -14,8 +19,9 @@ class Worktree {
|
||||||
required Repository repo,
|
required Repository repo,
|
||||||
required String name,
|
required String name,
|
||||||
required String path,
|
required String path,
|
||||||
|
Reference? ref,
|
||||||
}) {
|
}) {
|
||||||
_worktreePointer = bindings.create(repo.pointer, name, path);
|
_worktreePointer = bindings.create(repo.pointer, name, path, ref?.pointer);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Initializes a new instance of [Worktree] class by looking up existing worktree
|
/// Initializes a new instance of [Worktree] class by looking up existing worktree
|
||||||
|
|
|
@ -52,6 +52,40 @@ void main() {
|
||||||
worktree.free();
|
worktree.free();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test(
|
||||||
|
'successfully creates worktree at provided path from provided reference',
|
||||||
|
() {
|
||||||
|
const worktreeName = 'worktree';
|
||||||
|
final head = repo.revParseSingle('HEAD');
|
||||||
|
final worktreeRef = repo.branches.create(name: 'v1', target: head);
|
||||||
|
final worktreeBranch = repo.branches['v1'];
|
||||||
|
expect(Worktree.list(repo), []);
|
||||||
|
|
||||||
|
final worktree = Worktree.create(
|
||||||
|
repo: repo,
|
||||||
|
name: worktreeName,
|
||||||
|
path: worktreeDir,
|
||||||
|
ref: worktreeRef,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(Worktree.list(repo), [worktreeName]);
|
||||||
|
expect(repo.branches.list(), contains('v1'));
|
||||||
|
expect(repo.branches.list(), isNot(contains(worktreeName)));
|
||||||
|
expect(worktreeBranch.isCheckedOut, true);
|
||||||
|
|
||||||
|
Directory(worktreeDir).deleteSync(recursive: true);
|
||||||
|
worktree.prune();
|
||||||
|
|
||||||
|
expect(Worktree.list(repo), []);
|
||||||
|
expect(worktreeBranch.isCheckedOut, false);
|
||||||
|
expect(repo.branches.list(), contains('v1'));
|
||||||
|
|
||||||
|
worktreeBranch.free();
|
||||||
|
worktreeRef.free();
|
||||||
|
head.free();
|
||||||
|
worktree.free();
|
||||||
|
});
|
||||||
|
|
||||||
test('successfully prunes worktree', () {
|
test('successfully prunes worktree', () {
|
||||||
const worktreeName = 'worktree';
|
const worktreeName = 'worktree';
|
||||||
expect(Worktree.list(repo), []);
|
expect(Worktree.list(repo), []);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue