mirror of
https://github.com/SkinnyMind/libgit2dart.git
synced 2025-05-05 04:39:07 -04:00
feat(repository)!: add more aliases for api methods
BREAKING CHANGE: Make repository entry point for most operations
This commit is contained in:
parent
9205a3ad82
commit
3a0fa75929
51 changed files with 1380 additions and 1062 deletions
|
@ -2,9 +2,9 @@ import 'dart:io';
|
||||||
import 'package:libgit2dart/libgit2dart.dart';
|
import 'package:libgit2dart/libgit2dart.dart';
|
||||||
import '../test/helpers/util.dart';
|
import '../test/helpers/util.dart';
|
||||||
|
|
||||||
void main() async {
|
void main() {
|
||||||
// Preparing example repository.
|
// Preparing example repository.
|
||||||
final tmpDir = await setupRepo(Directory('test/assets/testrepo/'));
|
final tmpDir = setupRepo(Directory('test/assets/testrepo/'));
|
||||||
|
|
||||||
// Open system + global config file.
|
// Open system + global config file.
|
||||||
final config = Config.open();
|
final config = Config.open();
|
||||||
|
@ -54,5 +54,5 @@ void main() async {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Removing example repository.
|
// Removing example repository.
|
||||||
await tmpDir.delete(recursive: true);
|
tmpDir.deleteSync(recursive: true);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,17 +2,17 @@ import 'dart:io';
|
||||||
import 'package:libgit2dart/libgit2dart.dart';
|
import 'package:libgit2dart/libgit2dart.dart';
|
||||||
import '../test/helpers/util.dart';
|
import '../test/helpers/util.dart';
|
||||||
|
|
||||||
void main() async {
|
void main() {
|
||||||
// Preparing example repository.
|
// Preparing example repository.
|
||||||
final tmpDir = await setupRepo(Directory('test/assets/testrepo/'));
|
final tmpDir = setupRepo(Directory('test/assets/testrepo/'));
|
||||||
|
|
||||||
final repo = Repository.open(tmpDir.path);
|
final repo = Repository.open(tmpDir.path);
|
||||||
|
|
||||||
// Get list of repo's references.
|
// Get list of repo's references.
|
||||||
print('Repository references: ${repo.references.list}');
|
print('Repository references: ${repo.references}');
|
||||||
|
|
||||||
// Get reference by name.
|
// Get reference by name.
|
||||||
final ref = repo.references['refs/heads/master'];
|
final ref = repo.lookupReference('refs/heads/master');
|
||||||
|
|
||||||
print('Reference SHA hex: ${ref.target.sha}');
|
print('Reference SHA hex: ${ref.target.sha}');
|
||||||
print('Is reference a local branch: ${ref.isBranch}');
|
print('Is reference a local branch: ${ref.isBranch}');
|
||||||
|
@ -20,16 +20,16 @@ void main() async {
|
||||||
print('Reference shorthand name: ${ref.shorthand}');
|
print('Reference shorthand name: ${ref.shorthand}');
|
||||||
|
|
||||||
// Create new reference (direct or symbolic).
|
// Create new reference (direct or symbolic).
|
||||||
final newRef = repo.references.create(
|
final newRef = repo.createReference(
|
||||||
name: 'refs/tags/v1',
|
name: 'refs/tags/v1',
|
||||||
target: 'refs/heads/master',
|
target: 'refs/heads/master',
|
||||||
);
|
);
|
||||||
|
|
||||||
// Rename reference.
|
// Rename reference.
|
||||||
newRef.rename(newName: 'refs/tags/v1.1');
|
repo.renameReference(oldName: 'v1', newName: 'refs/tags/v1.1');
|
||||||
|
|
||||||
// Delete reference.
|
// Delete reference.
|
||||||
newRef.delete();
|
repo.deleteReference('v1.1');
|
||||||
|
|
||||||
// free() should be called on object to free memory when done.
|
// free() should be called on object to free memory when done.
|
||||||
ref.free();
|
ref.free();
|
||||||
|
@ -37,5 +37,5 @@ void main() async {
|
||||||
repo.free();
|
repo.free();
|
||||||
|
|
||||||
// Removing example repository.
|
// Removing example repository.
|
||||||
await tmpDir.delete(recursive: true);
|
tmpDir.deleteSync(recursive: true);
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ import '../util.dart';
|
||||||
/// Return a list of branches.
|
/// Return a list of branches.
|
||||||
///
|
///
|
||||||
/// Throws a [LibGit2Error] if error occured.
|
/// Throws a [LibGit2Error] if error occured.
|
||||||
List<String> list({
|
List<Pointer<git_reference>> list({
|
||||||
required Pointer<git_repository> repoPointer,
|
required Pointer<git_repository> repoPointer,
|
||||||
required int flags,
|
required int flags,
|
||||||
}) {
|
}) {
|
||||||
|
@ -24,7 +24,7 @@ List<String> list({
|
||||||
throw LibGit2Error(libgit2.git_error_last());
|
throw LibGit2Error(libgit2.git_error_last());
|
||||||
}
|
}
|
||||||
|
|
||||||
var result = <String>[];
|
var result = <Pointer<git_reference>>[];
|
||||||
var error = 0;
|
var error = 0;
|
||||||
|
|
||||||
while (error == 0) {
|
while (error == 0) {
|
||||||
|
@ -32,10 +32,8 @@ List<String> list({
|
||||||
final refType = calloc<Int32>();
|
final refType = calloc<Int32>();
|
||||||
error = libgit2.git_branch_next(reference, refType, iterator.value);
|
error = libgit2.git_branch_next(reference, refType, iterator.value);
|
||||||
if (error == 0) {
|
if (error == 0) {
|
||||||
final refName = reference_bindings.shorthand(reference.value);
|
result.add(reference.value);
|
||||||
result.add(refName);
|
|
||||||
calloc.free(refType);
|
calloc.free(refType);
|
||||||
calloc.free(reference);
|
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -129,11 +127,8 @@ void delete(Pointer<git_reference> branch) {
|
||||||
///
|
///
|
||||||
/// The new branch name will be checked for validity.
|
/// The new branch name will be checked for validity.
|
||||||
///
|
///
|
||||||
/// Note that if the move succeeds, the old reference object will not be valid anymore,
|
|
||||||
/// and will be freed immediately.
|
|
||||||
///
|
|
||||||
/// Throws a [LibGit2Error] if error occured.
|
/// Throws a [LibGit2Error] if error occured.
|
||||||
Pointer<git_reference> rename({
|
void rename({
|
||||||
required Pointer<git_reference> branchPointer,
|
required Pointer<git_reference> branchPointer,
|
||||||
required String newBranchName,
|
required String newBranchName,
|
||||||
required bool force,
|
required bool force,
|
||||||
|
@ -149,8 +144,7 @@ Pointer<git_reference> rename({
|
||||||
if (error < 0) {
|
if (error < 0) {
|
||||||
throw LibGit2Error(libgit2.git_error_last());
|
throw LibGit2Error(libgit2.git_error_last());
|
||||||
} else {
|
} else {
|
||||||
reference_bindings.free(branchPointer);
|
reference_bindings.free(out.value);
|
||||||
return out.value;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,6 @@ import 'package:ffi/ffi.dart';
|
||||||
import '../error.dart';
|
import '../error.dart';
|
||||||
import 'libgit2_bindings.dart';
|
import 'libgit2_bindings.dart';
|
||||||
import '../util.dart';
|
import '../util.dart';
|
||||||
import 'oid.dart' as oid_bindings;
|
|
||||||
|
|
||||||
/// Lookup a commit object from a repository.
|
/// Lookup a commit object from a repository.
|
||||||
///
|
///
|
||||||
|
@ -92,26 +91,21 @@ Pointer<git_oid> create({
|
||||||
required String message,
|
required String message,
|
||||||
required Pointer<git_tree> treePointer,
|
required Pointer<git_tree> treePointer,
|
||||||
required int parentCount,
|
required int parentCount,
|
||||||
required List<String> parents,
|
required List<Pointer<git_commit>> parents,
|
||||||
}) {
|
}) {
|
||||||
final out = calloc<git_oid>();
|
final out = calloc<git_oid>();
|
||||||
final updateRefC = updateRef?.toNativeUtf8().cast<Int8>() ?? nullptr;
|
final updateRefC = updateRef?.toNativeUtf8().cast<Int8>() ?? nullptr;
|
||||||
final messageEncodingC =
|
final messageEncodingC =
|
||||||
messageEncoding?.toNativeUtf8().cast<Int8>() ?? nullptr;
|
messageEncoding?.toNativeUtf8().cast<Int8>() ?? nullptr;
|
||||||
final messageC = message.toNativeUtf8().cast<Int8>();
|
final messageC = message.toNativeUtf8().cast<Int8>();
|
||||||
Pointer<Pointer<git_commit>> parentsC =
|
final parentsC = calloc<Pointer<git_commit>>(parentCount);
|
||||||
calloc.call<Pointer<git_commit>>(parentCount);
|
|
||||||
|
|
||||||
if (parents.isNotEmpty) {
|
if (parents.isNotEmpty) {
|
||||||
for (var i = 0; i < parentCount; i++) {
|
for (var i = 0; i < parentCount; i++) {
|
||||||
final oid = oid_bindings.fromSHA(parents[i]);
|
parentsC[i] = parents[i];
|
||||||
var commit = calloc<IntPtr>();
|
|
||||||
commit = lookup(repoPointer: repoPointer, oidPointer: oid).cast();
|
|
||||||
parentsC[i] = commit.cast();
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
final commit = calloc<IntPtr>();
|
parentsC[0] = nullptr;
|
||||||
parentsC[0] = commit.cast();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
final error = libgit2.git_commit_create(
|
final error = libgit2.git_commit_create(
|
||||||
|
@ -130,9 +124,6 @@ Pointer<git_oid> create({
|
||||||
calloc.free(updateRefC);
|
calloc.free(updateRefC);
|
||||||
calloc.free(messageEncodingC);
|
calloc.free(messageEncodingC);
|
||||||
calloc.free(messageC);
|
calloc.free(messageC);
|
||||||
for (var i = 0; i < parentCount; i++) {
|
|
||||||
free(parentsC[i]);
|
|
||||||
}
|
|
||||||
calloc.free(parentsC);
|
calloc.free(parentsC);
|
||||||
|
|
||||||
if (error < 0) {
|
if (error < 0) {
|
||||||
|
|
|
@ -107,10 +107,10 @@ Pointer<git_oid> create({
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Remove the note for an object.
|
/// Delete the note for an object.
|
||||||
///
|
///
|
||||||
/// Throws a [LibGit2Error] if error occured.
|
/// Throws a [LibGit2Error] if error occured.
|
||||||
void remove({
|
void delete({
|
||||||
required Pointer<git_repository> repoPointer,
|
required Pointer<git_repository> repoPointer,
|
||||||
String notesRef = 'refs/notes/commits',
|
String notesRef = 'refs/notes/commits',
|
||||||
required Pointer<git_signature> authorPointer,
|
required Pointer<git_signature> authorPointer,
|
||||||
|
|
|
@ -130,5 +130,5 @@ void remove({
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Free a tree builder to release memory.
|
/// Free a tree builder and all the entries to release memory.
|
||||||
void free(Pointer<git_treebuilder> bld) => libgit2.git_treebuilder_free(bld);
|
void free(Pointer<git_treebuilder> bld) => libgit2.git_treebuilder_free(bld);
|
||||||
|
|
|
@ -20,13 +20,22 @@ Pointer<git_worktree> create({
|
||||||
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 opts =
|
|
||||||
calloc<git_worktree_add_options>(sizeOf<git_worktree_add_options>());
|
final opts = calloc<git_worktree_add_options>();
|
||||||
opts.ref.version = 1;
|
final optsError = libgit2.git_worktree_add_options_init(
|
||||||
opts.ref.lock = 0;
|
opts,
|
||||||
|
GIT_WORKTREE_ADD_OPTIONS_VERSION,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (optsError < 0) {
|
||||||
|
throw LibGit2Error(libgit2.git_error_last());
|
||||||
|
}
|
||||||
|
|
||||||
|
opts.ref.ref = nullptr;
|
||||||
if (refPointer != null) {
|
if (refPointer != null) {
|
||||||
opts.ref.ref = refPointer;
|
opts.ref.ref = refPointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
final error = libgit2.git_worktree_add(out, repoPointer, nameC, pathC, opts);
|
final error = libgit2.git_worktree_add(out, repoPointer, nameC, pathC, opts);
|
||||||
|
|
||||||
calloc.free(nameC);
|
calloc.free(nameC);
|
||||||
|
@ -82,6 +91,7 @@ List<String> list(Pointer<git_repository> repo) {
|
||||||
final result = <String>[];
|
final result = <String>[];
|
||||||
|
|
||||||
if (error < 0) {
|
if (error < 0) {
|
||||||
|
calloc.free(out);
|
||||||
throw LibGit2Error(libgit2.git_error_last());
|
throw LibGit2Error(libgit2.git_error_last());
|
||||||
} else {
|
} else {
|
||||||
for (var i = 0; i < out.ref.count; i++) {
|
for (var i = 0; i < out.ref.count; i++) {
|
||||||
|
|
|
@ -8,18 +8,16 @@ class Blob {
|
||||||
/// Initializes a new instance of [Blob] class from provided pointer to
|
/// Initializes a new instance of [Blob] class from provided pointer to
|
||||||
/// blob object in memory.
|
/// blob object in memory.
|
||||||
///
|
///
|
||||||
/// Should be freed with `free()` to release allocated memory.
|
/// Should be freed to release allocated memory.
|
||||||
Blob(this._blobPointer);
|
Blob(this._blobPointer);
|
||||||
|
|
||||||
/// Initializes a new instance of [Blob] class from provided
|
/// Lookups a blob object for provided [id] in a [repo]sitory.
|
||||||
/// [Repository] object and [sha] hex string.
|
|
||||||
///
|
///
|
||||||
/// Should be freed with `free()` to release allocated memory.
|
/// Should be freed to release allocated memory.
|
||||||
Blob.lookup({required Repository repo, required String sha}) {
|
Blob.lookup({required Repository repo, required Oid id}) {
|
||||||
final oid = Oid.fromSHA(repo: repo, sha: sha);
|
|
||||||
_blobPointer = bindings.lookup(
|
_blobPointer = bindings.lookup(
|
||||||
repoPointer: repo.pointer,
|
repoPointer: repo.pointer,
|
||||||
oidPointer: oid.pointer,
|
oidPointer: id.pointer,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,134 +4,131 @@ import 'bindings/libgit2_bindings.dart';
|
||||||
import 'bindings/branch.dart' as bindings;
|
import 'bindings/branch.dart' as bindings;
|
||||||
import 'bindings/reference.dart' as reference_bindings;
|
import 'bindings/reference.dart' as reference_bindings;
|
||||||
|
|
||||||
class Branches {
|
class Branch {
|
||||||
/// Initializes a new instance of the [Branches] class
|
/// Initializes a new instance of [Branch] class from provided pointer to
|
||||||
/// from provided [Repository] object.
|
/// branch object in memory.
|
||||||
Branches(Repository repo) {
|
|
||||||
_repoPointer = repo.pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Pointer to memory address for allocated repository object.
|
|
||||||
late final Pointer<git_repository> _repoPointer;
|
|
||||||
|
|
||||||
/// Returns a list of all branches that can be found in a repository.
|
|
||||||
///
|
///
|
||||||
/// Throws a [LibGit2Error] if error occured.
|
/// Should be freed with [free] to release allocated memory when no longer
|
||||||
List<String> list() {
|
/// needed.
|
||||||
return bindings.list(
|
Branch(this._branchPointer);
|
||||||
repoPointer: _repoPointer,
|
|
||||||
flags: GitBranch.all.value,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns a list of local branches that can be found in a repository.
|
|
||||||
///
|
|
||||||
/// Throws a [LibGit2Error] if error occured.
|
|
||||||
List<String> get local {
|
|
||||||
return bindings.list(
|
|
||||||
repoPointer: _repoPointer,
|
|
||||||
flags: GitBranch.local.value,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns a list of remote branches that can be found in a repository.
|
|
||||||
///
|
|
||||||
/// Throws a [LibGit2Error] if error occured.
|
|
||||||
List<String> get remote {
|
|
||||||
return bindings.list(
|
|
||||||
repoPointer: _repoPointer,
|
|
||||||
flags: GitBranch.remote.value,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Lookups a branch by its name in a repository.
|
|
||||||
///
|
|
||||||
/// The generated reference must be freed. The branch name will be checked for validity.
|
|
||||||
///
|
|
||||||
/// Throws a [LibGit2Error] if error occured.
|
|
||||||
Branch operator [](String branchName) {
|
|
||||||
final ref = Reference(
|
|
||||||
reference_bindings.lookupDWIM(
|
|
||||||
repoPointer: _repoPointer,
|
|
||||||
name: branchName,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
late final GitBranch type;
|
|
||||||
ref.isBranch ? type = GitBranch.local : GitBranch.remote;
|
|
||||||
ref.free();
|
|
||||||
|
|
||||||
return Branch(bindings.lookup(
|
|
||||||
repoPointer: _repoPointer,
|
|
||||||
branchName: branchName,
|
|
||||||
branchType: type.value,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Creates a new branch pointing at a [target] commit.
|
/// Creates a new branch pointing at a [target] commit.
|
||||||
///
|
///
|
||||||
/// A new direct reference will be created pointing to this target commit.
|
/// A new direct reference will be created pointing to this target commit.
|
||||||
/// If [force] is true and a reference already exists with the given name, it'll be replaced.
|
/// If [force] is true and a reference already exists with the given name, it'll be replaced.
|
||||||
///
|
///
|
||||||
/// The returned reference must be freed.
|
/// Should be freed with [free] to release allocated memory when no longer
|
||||||
|
/// needed.
|
||||||
///
|
///
|
||||||
/// The branch name will be checked for validity.
|
/// The branch name will be checked for validity.
|
||||||
///
|
///
|
||||||
/// Throws a [LibGit2Error] if error occured.
|
/// Throws a [LibGit2Error] if error occured.
|
||||||
Reference create({
|
Branch.create({
|
||||||
|
required Repository repo,
|
||||||
required String name,
|
required String name,
|
||||||
required Commit target,
|
required Commit target,
|
||||||
bool force = false,
|
bool force = false,
|
||||||
}) {
|
}) {
|
||||||
return Reference(bindings.create(
|
_branchPointer = bindings.create(
|
||||||
repoPointer: _repoPointer,
|
repoPointer: repo.pointer,
|
||||||
branchName: name,
|
branchName: name,
|
||||||
targetPointer: target.pointer,
|
targetPointer: target.pointer,
|
||||||
force: force,
|
force: force,
|
||||||
));
|
);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class Branch {
|
/// Lookups a branch by its [name] in a [repo]sitory.
|
||||||
/// Initializes a new instance of [Branch] class from provided pointer to
|
|
||||||
/// branch object in memory.
|
|
||||||
///
|
///
|
||||||
/// Should be freed with `free()` to release allocated memory.
|
/// The branch name will be checked for validity.
|
||||||
const Branch(this._branchPointer);
|
///
|
||||||
|
/// Should be freed with [free] to release allocated memory when no longer
|
||||||
|
/// needed.
|
||||||
|
///
|
||||||
|
/// Throws a [LibGit2Error] if error occured.
|
||||||
|
Branch.lookup({required Repository repo, required String name}) {
|
||||||
|
final ref = Reference(
|
||||||
|
reference_bindings.lookupDWIM(
|
||||||
|
repoPointer: repo.pointer,
|
||||||
|
name: name,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
late final GitBranch type;
|
||||||
|
ref.isBranch ? type = GitBranch.local : GitBranch.remote;
|
||||||
|
ref.free();
|
||||||
|
|
||||||
|
_branchPointer = bindings.lookup(
|
||||||
|
repoPointer: repo.pointer,
|
||||||
|
branchName: name,
|
||||||
|
branchType: type.value,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
late final Pointer<git_reference> _branchPointer;
|
||||||
|
|
||||||
/// Pointer to memory address for allocated branch object.
|
/// Pointer to memory address for allocated branch object.
|
||||||
final Pointer<git_reference> _branchPointer;
|
Pointer<git_reference> get pointer => _branchPointer;
|
||||||
|
|
||||||
/// Returns the OID pointed to by a branch.
|
/// Returns a list of branches that can be found in a [repo]sitory for provided [type].
|
||||||
|
/// Default is all branches (local and remote).
|
||||||
///
|
///
|
||||||
/// Throws an exception if error occured.
|
/// IMPORTANT: Branches must be freed manually when no longer needed to prevent
|
||||||
Oid get target => Oid(reference_bindings.target(_branchPointer));
|
/// memory leak.
|
||||||
|
///
|
||||||
|
/// Throws a [LibGit2Error] if error occured.
|
||||||
|
static List<Branch> list({
|
||||||
|
required Repository repo,
|
||||||
|
GitBranch type = GitBranch.all,
|
||||||
|
}) {
|
||||||
|
final pointers = bindings.list(
|
||||||
|
repoPointer: repo.pointer,
|
||||||
|
flags: type.value,
|
||||||
|
);
|
||||||
|
|
||||||
|
final result = <Branch>[];
|
||||||
|
for (var pointer in pointers) {
|
||||||
|
result.add(Branch(pointer));
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/// Deletes an existing branch reference.
|
/// Deletes an existing branch reference.
|
||||||
///
|
///
|
||||||
/// Note that if the deletion succeeds, the reference object will not be valid anymore,
|
|
||||||
/// and will be freed.
|
|
||||||
///
|
|
||||||
/// Throws a [LibGit2Error] if error occured.
|
/// Throws a [LibGit2Error] if error occured.
|
||||||
void delete() => bindings.delete(_branchPointer);
|
static void delete({required Repository repo, required String name}) {
|
||||||
|
final branch = Branch.lookup(repo: repo, name: name);
|
||||||
|
bindings.delete(branch.pointer);
|
||||||
|
}
|
||||||
|
|
||||||
/// Renames an existing local branch reference.
|
/// Renames an existing local branch reference.
|
||||||
///
|
///
|
||||||
/// The new branch name will be checked for validity.
|
/// The new branch name will be checked for validity.
|
||||||
///
|
///
|
||||||
/// Note that if the move succeeds, the old reference object will not be valid anymore,
|
|
||||||
/// and will be freed immediately.
|
|
||||||
///
|
|
||||||
/// If [force] is true, existing branch will be overwritten.
|
/// If [force] is true, existing branch will be overwritten.
|
||||||
///
|
///
|
||||||
/// Throws a [LibGit2Error] if error occured.
|
/// Throws a [LibGit2Error] if error occured.
|
||||||
Branch rename({required String newName, bool force = false}) {
|
static void rename({
|
||||||
return Branch(bindings.rename(
|
required Repository repo,
|
||||||
branchPointer: _branchPointer,
|
required String oldName,
|
||||||
|
required String newName,
|
||||||
|
bool force = false,
|
||||||
|
}) {
|
||||||
|
final branch = Branch.lookup(repo: repo, name: oldName);
|
||||||
|
|
||||||
|
bindings.rename(
|
||||||
|
branchPointer: branch.pointer,
|
||||||
newBranchName: newName,
|
newBranchName: newName,
|
||||||
force: force,
|
force: force,
|
||||||
));
|
);
|
||||||
|
|
||||||
|
branch.free();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the OID pointed to by a branch.
|
||||||
|
///
|
||||||
|
/// Throws an exception if error occured.
|
||||||
|
Oid get target => Oid(reference_bindings.target(_branchPointer));
|
||||||
|
|
||||||
/// Checks 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.
|
||||||
|
@ -155,4 +152,9 @@ class Branch {
|
||||||
|
|
||||||
/// Releases memory allocated for branch object.
|
/// Releases memory allocated for branch object.
|
||||||
void free() => bindings.free(_branchPointer);
|
void free() => bindings.free(_branchPointer);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'Branch{name: $name, target: $target}';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,18 +8,16 @@ class Commit {
|
||||||
/// Initializes a new instance of [Commit] class from provided pointer to
|
/// Initializes a new instance of [Commit] class from provided pointer to
|
||||||
/// commit object in memory.
|
/// commit object in memory.
|
||||||
///
|
///
|
||||||
/// Should be freed with `free()` to release allocated memory.
|
/// Should be freed to release allocated memory.
|
||||||
Commit(this._commitPointer);
|
Commit(this._commitPointer);
|
||||||
|
|
||||||
/// Initializes a new instance of [Commit] class from provided [Repository] object
|
/// Lookups commit object for provided [id] in a [repo]sitory.
|
||||||
/// and [sha] hex string.
|
|
||||||
///
|
///
|
||||||
/// Should be freed with `free()` to release allocated memory.
|
/// Should be freed to release allocated memory.
|
||||||
Commit.lookup({required Repository repo, required String sha}) {
|
Commit.lookup({required Repository repo, required Oid id}) {
|
||||||
final oid = Oid.fromSHA(repo: repo, sha: sha);
|
|
||||||
_commitPointer = bindings.lookup(
|
_commitPointer = bindings.lookup(
|
||||||
repoPointer: repo.pointer,
|
repoPointer: repo.pointer,
|
||||||
oidPointer: oid.pointer,
|
oidPointer: id.pointer,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,14 +40,14 @@ class Commit {
|
||||||
required String message,
|
required String message,
|
||||||
required Signature author,
|
required Signature author,
|
||||||
required Signature commiter,
|
required Signature commiter,
|
||||||
required String treeSHA,
|
required Tree tree,
|
||||||
required List<String> parents,
|
required List<Commit> parents,
|
||||||
String? updateRef,
|
String? updateRef,
|
||||||
String? messageEncoding,
|
String? messageEncoding,
|
||||||
}) {
|
}) {
|
||||||
final tree = Tree.lookup(repo: repo, sha: treeSHA);
|
final parentsPointers = parents.map((parent) => parent.pointer).toList();
|
||||||
|
|
||||||
final result = Oid(bindings.create(
|
return Oid(bindings.create(
|
||||||
repoPointer: repo.pointer,
|
repoPointer: repo.pointer,
|
||||||
updateRef: updateRef,
|
updateRef: updateRef,
|
||||||
authorPointer: author.pointer,
|
authorPointer: author.pointer,
|
||||||
|
@ -58,12 +56,8 @@ class Commit {
|
||||||
message: message,
|
message: message,
|
||||||
treePointer: tree.pointer,
|
treePointer: tree.pointer,
|
||||||
parentCount: parents.length,
|
parentCount: parents.length,
|
||||||
parents: parents,
|
parents: parentsPointers,
|
||||||
));
|
));
|
||||||
|
|
||||||
tree.free();
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the encoding for the message of a commit, as a string
|
/// Returns the encoding for the message of a commit, as a string
|
||||||
|
|
|
@ -139,25 +139,9 @@ class Index with IterableMixin<IndexEntry> {
|
||||||
bindings.read(indexPointer: _indexPointer, force: force);
|
bindings.read(indexPointer: _indexPointer, force: force);
|
||||||
|
|
||||||
/// Updates the contents of an existing index object in memory by reading from the
|
/// Updates the contents of an existing index object in memory by reading from the
|
||||||
/// specified tree.
|
/// specified [tree].
|
||||||
void readTree(Object target) {
|
void readTree(Tree tree) {
|
||||||
late final Tree tree;
|
|
||||||
|
|
||||||
if (target is Oid) {
|
|
||||||
final repo = Repository(bindings.owner(_indexPointer));
|
|
||||||
tree = Tree.lookup(repo: repo, sha: target.sha);
|
|
||||||
} else if (target is Tree) {
|
|
||||||
tree = target;
|
|
||||||
} else if (target is String) {
|
|
||||||
final repo = Repository(bindings.owner(_indexPointer));
|
|
||||||
tree = Tree.lookup(repo: repo, sha: target);
|
|
||||||
} else {
|
|
||||||
throw ArgumentError.value(
|
|
||||||
'$target should be either Oid object, SHA hex string or Tree object');
|
|
||||||
}
|
|
||||||
|
|
||||||
bindings.readTree(indexPointer: _indexPointer, treePointer: tree.pointer);
|
bindings.readTree(indexPointer: _indexPointer, treePointer: tree.pointer);
|
||||||
tree.free();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Writes an existing index object from memory back to disk using an atomic file lock.
|
/// Writes an existing index object from memory back to disk using an atomic file lock.
|
||||||
|
|
|
@ -3,43 +3,44 @@ import 'package:libgit2dart/libgit2dart.dart';
|
||||||
import 'bindings/libgit2_bindings.dart';
|
import 'bindings/libgit2_bindings.dart';
|
||||||
import 'bindings/note.dart' as bindings;
|
import 'bindings/note.dart' as bindings;
|
||||||
|
|
||||||
class Notes {
|
class Note {
|
||||||
/// Initializes a new instance of the [Notes] class from
|
/// Initializes a new instance of the [Note] class from provided
|
||||||
/// provided [Repository] object.
|
/// pointer to note and annotatedId objects in memory.
|
||||||
Notes(Repository repo) {
|
Note(this._notePointer, this._annotatedIdPointer);
|
||||||
_repoPointer = repo.pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Pointer to memory address for allocated repository object.
|
/// Reads the note for an [annotatedId].
|
||||||
late final Pointer<git_repository> _repoPointer;
|
|
||||||
|
|
||||||
/// Reads the note for an object.
|
|
||||||
///
|
///
|
||||||
/// The note must be freed manually by the user.
|
/// IMPORTANT: Notes must be freed manually when no longer needed to prevent
|
||||||
|
/// memory leak.
|
||||||
///
|
///
|
||||||
/// Throws a [LibGit2Error] if error occured.
|
/// Throws a [LibGit2Error] if error occured.
|
||||||
static Note lookup({
|
Note.lookup({
|
||||||
required Repository repo,
|
required Repository repo,
|
||||||
required Oid annotatedId,
|
required Oid annotatedId,
|
||||||
String notesRef = 'refs/notes/commits',
|
String notesRef = 'refs/notes/commits',
|
||||||
}) {
|
}) {
|
||||||
final note = bindings.lookup(
|
_notePointer = bindings.lookup(
|
||||||
repoPointer: repo.pointer,
|
repoPointer: repo.pointer,
|
||||||
oidPointer: annotatedId.pointer,
|
oidPointer: annotatedId.pointer,
|
||||||
notesRef: notesRef,
|
notesRef: notesRef,
|
||||||
);
|
);
|
||||||
|
_annotatedIdPointer = annotatedId.pointer;
|
||||||
return Note(note, annotatedId.pointer, repo.pointer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Adds a note for an [object].
|
/// Pointer to memory address for allocated note object.
|
||||||
|
late final Pointer<git_note> _notePointer;
|
||||||
|
|
||||||
|
/// Pointer to memory address for allocated annotetedId object.
|
||||||
|
late final Pointer<git_oid> _annotatedIdPointer;
|
||||||
|
|
||||||
|
/// Adds a note for an [annotatedId].
|
||||||
///
|
///
|
||||||
/// Throws a [LibGit2Error] if error occured.
|
/// Throws a [LibGit2Error] if error occured.
|
||||||
static Oid create({
|
static Oid create({
|
||||||
required Repository repo,
|
required Repository repo,
|
||||||
required Signature author,
|
required Signature author,
|
||||||
required Signature committer,
|
required Signature committer,
|
||||||
required Oid object,
|
required Oid annotatedId,
|
||||||
required String note,
|
required String note,
|
||||||
String notesRef = 'refs/notes/commits',
|
String notesRef = 'refs/notes/commits',
|
||||||
bool force = false,
|
bool force = false,
|
||||||
|
@ -48,62 +49,49 @@ class Notes {
|
||||||
repoPointer: repo.pointer,
|
repoPointer: repo.pointer,
|
||||||
authorPointer: author.pointer,
|
authorPointer: author.pointer,
|
||||||
committerPointer: committer.pointer,
|
committerPointer: committer.pointer,
|
||||||
oidPointer: object.pointer,
|
oidPointer: annotatedId.pointer,
|
||||||
note: note,
|
note: note,
|
||||||
notesRef: notesRef,
|
notesRef: notesRef,
|
||||||
force: force,
|
force: force,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns list of notes for repository.
|
/// Deletes the note for an [annotatedId].
|
||||||
///
|
|
||||||
/// Notes must be freed manually by the user.
|
|
||||||
///
|
///
|
||||||
/// Throws a [LibGit2Error] if error occured.
|
/// Throws a [LibGit2Error] if error occured.
|
||||||
List<Note> get list {
|
static void delete({
|
||||||
final notesPointers = bindings.list(_repoPointer);
|
required Repository repo,
|
||||||
|
required Oid annotatedId,
|
||||||
|
required Signature author,
|
||||||
|
required Signature committer,
|
||||||
|
String notesRef = 'refs/notes/commits',
|
||||||
|
}) {
|
||||||
|
bindings.delete(
|
||||||
|
repoPointer: repo.pointer,
|
||||||
|
authorPointer: author.pointer,
|
||||||
|
committerPointer: committer.pointer,
|
||||||
|
oidPointer: annotatedId.pointer,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns list of notes for repository.
|
||||||
|
///
|
||||||
|
/// IMPORTANT: Notes must be freed manually when no longer needed to prevent
|
||||||
|
/// memory leak.
|
||||||
|
///
|
||||||
|
/// Throws a [LibGit2Error] if error occured.
|
||||||
|
static List<Note> list(Repository repo) {
|
||||||
|
final notesPointers = bindings.list(repo.pointer);
|
||||||
var result = <Note>[];
|
var result = <Note>[];
|
||||||
for (var note in notesPointers) {
|
for (var note in notesPointers) {
|
||||||
result.add(Note(
|
result.add(Note(
|
||||||
note['note'] as Pointer<git_note>,
|
note['note'] as Pointer<git_note>,
|
||||||
note['annotatedId'] as Pointer<git_oid>,
|
note['annotatedId'] as Pointer<git_oid>,
|
||||||
_repoPointer,
|
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
class Note {
|
|
||||||
/// Initializes a new instance of the [Note] class from provided
|
|
||||||
/// pointer to note object in memory.
|
|
||||||
Note(this._notePointer, this._annotatedIdPointer, this._repoPointer);
|
|
||||||
|
|
||||||
/// Pointer to memory address for allocated note object.
|
|
||||||
final Pointer<git_note> _notePointer;
|
|
||||||
|
|
||||||
/// Pointer to memory address for allocated annotetedId object.
|
|
||||||
final Pointer<git_oid> _annotatedIdPointer;
|
|
||||||
|
|
||||||
/// Pointer to memory address for allocated repository object.
|
|
||||||
final Pointer<git_repository> _repoPointer;
|
|
||||||
|
|
||||||
/// Removes the note for an [object].
|
|
||||||
///
|
|
||||||
/// Throws a [LibGit2Error] if error occured.
|
|
||||||
void remove({
|
|
||||||
required Signature author,
|
|
||||||
required Signature committer,
|
|
||||||
String notesRef = 'refs/notes/commits',
|
|
||||||
}) {
|
|
||||||
bindings.remove(
|
|
||||||
repoPointer: _repoPointer,
|
|
||||||
authorPointer: author.pointer,
|
|
||||||
committerPointer: committer.pointer,
|
|
||||||
oidPointer: annotatedId.pointer,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the note object's [Oid].
|
/// Returns the note object's [Oid].
|
||||||
Oid get id => Oid(bindings.id(_notePointer));
|
Oid get id => Oid(bindings.id(_notePointer));
|
||||||
|
|
|
@ -7,53 +7,31 @@ import 'bindings/refdb.dart' as refdb_bindings;
|
||||||
import 'bindings/repository.dart' as repository_bindings;
|
import 'bindings/repository.dart' as repository_bindings;
|
||||||
import 'util.dart';
|
import 'util.dart';
|
||||||
|
|
||||||
class References {
|
class Reference {
|
||||||
/// Initializes a new instance of the [References] class
|
/// Initializes a new instance of the [Reference] class.
|
||||||
/// from provided [Repository] object.
|
/// Should be freed to release allocated memory.
|
||||||
References(Repository repo) {
|
Reference(this._refPointer);
|
||||||
_repoPointer = repo.pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Pointer to memory address for allocated repository object.
|
|
||||||
late final Pointer<git_repository> _repoPointer;
|
|
||||||
|
|
||||||
/// Returns a list of all the references that can be found in a repository.
|
|
||||||
///
|
|
||||||
/// Throws a [LibGit2Error] if error occured.
|
|
||||||
List<String> get list => bindings.list(_repoPointer);
|
|
||||||
|
|
||||||
/// Returns number of all the references that can be found in a repository.
|
|
||||||
int get length => list.length;
|
|
||||||
|
|
||||||
/// Returns a [Reference] by lookingup [name] in a repository.
|
|
||||||
///
|
|
||||||
/// Should be freed with `free()` to release allocated memory.
|
|
||||||
///
|
|
||||||
/// The name will be checked for validity.
|
|
||||||
///
|
|
||||||
/// Throws a [LibGit2Error] if error occured.
|
|
||||||
Reference operator [](String name) {
|
|
||||||
return Reference(bindings.lookup(repoPointer: _repoPointer, name: name));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Creates a new reference.
|
/// Creates a new reference.
|
||||||
///
|
///
|
||||||
/// The reference will be created in the repository and written to the disk.
|
/// The reference will be created in the [repo]sitory and written to the disk.
|
||||||
/// The generated [Reference] object must be freed by the user.
|
/// The generated [Reference] object must be freed by the user.
|
||||||
///
|
///
|
||||||
/// Valid reference names must follow one of two patterns:
|
/// Valid reference [name]s must follow one of two patterns:
|
||||||
///
|
///
|
||||||
/// Top-level names must contain only capital letters and underscores, and must begin and end
|
/// Top-level names must contain only capital letters and underscores, and must begin and end
|
||||||
/// with a letter. (e.g. "HEAD", "ORIG_HEAD").
|
/// with a letter. (e.g. "HEAD", "ORIG_HEAD").
|
||||||
/// Names prefixed with "refs/" can be almost anything. You must avoid the characters
|
/// Names prefixed with "refs/" can be almost anything. You must avoid the characters
|
||||||
/// '~', '^', ':', '\', '?', '[', and '*', and the sequences ".." and "@{" which have
|
/// '~', '^', ':', '\', '?', '[', and '*', and the sequences ".." and "@{" which have
|
||||||
/// special meaning to revparse.
|
/// special meaning to revparse.
|
||||||
/// Throws a [LibGit2Error] if a reference already exists with the given name
|
|
||||||
/// unless force is true, in which case it will be overwritten.
|
|
||||||
///
|
///
|
||||||
/// The message for the reflog will be ignored if the reference does not belong in the
|
/// Throws a [LibGit2Error] if a reference already exists with the given [name]
|
||||||
|
/// unless [force] is true, in which case it will be overwritten.
|
||||||
|
///
|
||||||
|
/// The [logMessage] message for the reflog will be ignored if the reference does not belong in the
|
||||||
/// standard set (HEAD, branches and remote-tracking branches) and it does not have a reflog.
|
/// standard set (HEAD, branches and remote-tracking branches) and it does not have a reflog.
|
||||||
Reference create({
|
Reference.create({
|
||||||
|
required Repository repo,
|
||||||
required String name,
|
required String name,
|
||||||
required Object target,
|
required Object target,
|
||||||
bool force = false,
|
bool force = false,
|
||||||
|
@ -66,7 +44,6 @@ class References {
|
||||||
oid = target;
|
oid = target;
|
||||||
isDirect = true;
|
isDirect = true;
|
||||||
} else if (isValidShaHex(target as String)) {
|
} else if (isValidShaHex(target as String)) {
|
||||||
final repo = Repository(_repoPointer);
|
|
||||||
oid = Oid.fromSHA(repo: repo, sha: target);
|
oid = Oid.fromSHA(repo: repo, sha: target);
|
||||||
isDirect = true;
|
isDirect = true;
|
||||||
} else {
|
} else {
|
||||||
|
@ -74,46 +51,97 @@ class References {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isDirect) {
|
if (isDirect) {
|
||||||
return Reference(bindings.createDirect(
|
_refPointer = bindings.createDirect(
|
||||||
repoPointer: _repoPointer,
|
repoPointer: repo.pointer,
|
||||||
name: name,
|
name: name,
|
||||||
oidPointer: oid.pointer,
|
oidPointer: oid.pointer,
|
||||||
force: force,
|
force: force,
|
||||||
logMessage: logMessage,
|
logMessage: logMessage,
|
||||||
));
|
);
|
||||||
} else {
|
} else {
|
||||||
return Reference(bindings.createSymbolic(
|
_refPointer = bindings.createSymbolic(
|
||||||
repoPointer: _repoPointer,
|
repoPointer: repo.pointer,
|
||||||
name: name,
|
name: name,
|
||||||
target: target as String,
|
target: target as String,
|
||||||
force: force,
|
force: force,
|
||||||
logMessage: logMessage,
|
logMessage: logMessage,
|
||||||
));
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Suggests that the given refdb compress or optimize its references.
|
/// Lookups reference [name] in a [repo]sitory.
|
||||||
/// This mechanism is implementation specific. For on-disk reference databases,
|
///
|
||||||
/// for example, this may pack all loose references.
|
/// Should be freed to release allocated memory.
|
||||||
|
///
|
||||||
|
/// The [name] will be checked for validity.
|
||||||
///
|
///
|
||||||
/// Throws a [LibGit2Error] if error occured.
|
/// Throws a [LibGit2Error] if error occured.
|
||||||
void compress() {
|
Reference.lookup({required Repository repo, required String name}) {
|
||||||
final refdb = repository_bindings.refdb(_repoPointer);
|
_refPointer = bindings.lookup(repoPointer: repo.pointer, name: name);
|
||||||
refdb_bindings.compress(refdb);
|
|
||||||
refdb_bindings.free(refdb);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
class Reference {
|
|
||||||
/// Initializes a new instance of the [Reference] class.
|
|
||||||
/// Should be freed with `free()` to release allocated memory.
|
|
||||||
Reference(this._refPointer);
|
|
||||||
|
|
||||||
late Pointer<git_reference> _refPointer;
|
late Pointer<git_reference> _refPointer;
|
||||||
|
|
||||||
/// Pointer to memory address for allocated reference object.
|
/// Pointer to memory address for allocated reference object.
|
||||||
Pointer<git_reference> get pointer => _refPointer;
|
Pointer<git_reference> get pointer => _refPointer;
|
||||||
|
|
||||||
|
/// Deletes an existing reference with provided [name].
|
||||||
|
///
|
||||||
|
/// This method works for both direct and symbolic references.
|
||||||
|
///
|
||||||
|
/// Throws a [LibGit2Error] if error occured.
|
||||||
|
static void delete({required Repository repo, required String name}) {
|
||||||
|
final ref = Reference.lookup(repo: repo, name: name);
|
||||||
|
bindings.delete(ref.pointer);
|
||||||
|
ref.free();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Renames an existing reference.
|
||||||
|
///
|
||||||
|
/// This method works for both direct and symbolic references.
|
||||||
|
///
|
||||||
|
/// The [newName] will be checked for validity.
|
||||||
|
///
|
||||||
|
/// If the [force] flag is set to false, and there's already a reference with the given name,
|
||||||
|
/// the renaming will fail.
|
||||||
|
///
|
||||||
|
/// IMPORTANT: The user needs to write a proper reflog entry [logMessage] if the reflog is
|
||||||
|
/// enabled for the repository. We only rename the reflog if it exists.
|
||||||
|
///
|
||||||
|
/// Throws a [LibGit2Error] if error occured.
|
||||||
|
static void rename({
|
||||||
|
required Repository repo,
|
||||||
|
required String oldName,
|
||||||
|
required String newName,
|
||||||
|
bool force = false,
|
||||||
|
String? logMessage,
|
||||||
|
}) {
|
||||||
|
final ref = Reference.lookup(repo: repo, name: oldName);
|
||||||
|
bindings.rename(
|
||||||
|
refPointer: ref.pointer,
|
||||||
|
newName: newName,
|
||||||
|
force: force,
|
||||||
|
logMessage: logMessage,
|
||||||
|
);
|
||||||
|
ref.free();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns a list of all the references that can be found in a [repo]sitory.
|
||||||
|
///
|
||||||
|
/// Throws a [LibGit2Error] if error occured.
|
||||||
|
static List<String> list(Repository repo) => bindings.list(repo.pointer);
|
||||||
|
|
||||||
|
/// Suggests that the [repo]sitory's refdb compress or optimize its references.
|
||||||
|
/// This mechanism is implementation specific. For on-disk reference databases,
|
||||||
|
/// for example, this may pack all loose references.
|
||||||
|
///
|
||||||
|
/// Throws a [LibGit2Error] if error occured.
|
||||||
|
static void compress(Repository repo) {
|
||||||
|
final refdb = repository_bindings.refdb(repo.pointer);
|
||||||
|
refdb_bindings.compress(refdb);
|
||||||
|
refdb_bindings.free(refdb);
|
||||||
|
}
|
||||||
|
|
||||||
/// 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
|
||||||
|
@ -180,6 +208,8 @@ class Reference {
|
||||||
/// ```dart
|
/// ```dart
|
||||||
/// final commit = ref.peel(GitObject.commit) as Commit;
|
/// final commit = ref.peel(GitObject.commit) as Commit;
|
||||||
/// final tree = ref.peel(GitObject.tree) as Tree;
|
/// final tree = ref.peel(GitObject.tree) as Tree;
|
||||||
|
/// final blob = ref.peel(GitObject.blob) as Blob;
|
||||||
|
/// final tag = ref.peel(GitObject.tag) as Tag;
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// Throws a [LibGit2Error] if error occured.
|
/// Throws a [LibGit2Error] if error occured.
|
||||||
|
@ -207,32 +237,6 @@ class Reference {
|
||||||
/// If no shortname is appropriate, it will return the full name.
|
/// If no shortname is appropriate, it will return the full name.
|
||||||
String get shorthand => bindings.shorthand(_refPointer);
|
String get shorthand => bindings.shorthand(_refPointer);
|
||||||
|
|
||||||
/// Renames an existing reference.
|
|
||||||
///
|
|
||||||
/// This method works for both direct and symbolic references.
|
|
||||||
///
|
|
||||||
/// The new name will be checked for validity.
|
|
||||||
///
|
|
||||||
/// If the force flag is not enabled, and there's already a reference with the given name,
|
|
||||||
/// the renaming will fail.
|
|
||||||
///
|
|
||||||
/// IMPORTANT: The user needs to write a proper reflog entry if the reflog is enabled for
|
|
||||||
/// the repository. We only rename the reflog if it exists.
|
|
||||||
///
|
|
||||||
/// Throws a [LibGit2Error] if error occured.
|
|
||||||
void rename({
|
|
||||||
required String newName,
|
|
||||||
bool force = false,
|
|
||||||
String? logMessage,
|
|
||||||
}) {
|
|
||||||
_refPointer = bindings.rename(
|
|
||||||
refPointer: _refPointer,
|
|
||||||
newName: newName,
|
|
||||||
force: force,
|
|
||||||
logMessage: logMessage,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Checks if a reflog exists for the specified reference [name].
|
/// Checks if a reflog exists for the specified reference [name].
|
||||||
///
|
///
|
||||||
/// Throws a [LibGit2Error] if error occured.
|
/// Throws a [LibGit2Error] if error occured.
|
||||||
|
@ -261,14 +265,6 @@ class Reference {
|
||||||
/// Returns the repository where a reference resides.
|
/// Returns the repository where a reference resides.
|
||||||
Repository get owner => Repository(bindings.owner(_refPointer));
|
Repository get owner => Repository(bindings.owner(_refPointer));
|
||||||
|
|
||||||
/// Delete an existing reference.
|
|
||||||
///
|
|
||||||
/// This method works for both direct and symbolic references.
|
|
||||||
/// The reference will be immediately removed on disk but the memory will not be freed.
|
|
||||||
///
|
|
||||||
/// Throws a [LibGit2Error] if the reference has changed from the time it was looked up.
|
|
||||||
void delete() => bindings.delete(_refPointer);
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(other) {
|
bool operator ==(other) {
|
||||||
return (other is Reference) &&
|
return (other is Reference) &&
|
||||||
|
@ -283,4 +279,9 @@ class Reference {
|
||||||
|
|
||||||
/// Releases memory allocated for reference object.
|
/// Releases memory allocated for reference object.
|
||||||
void free() => bindings.free(_refPointer);
|
void free() => bindings.free(_refPointer);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'Reference{name: $name, target: $target}';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,70 +3,63 @@ import 'package:libgit2dart/libgit2dart.dart';
|
||||||
import 'bindings/libgit2_bindings.dart';
|
import 'bindings/libgit2_bindings.dart';
|
||||||
import 'bindings/remote.dart' as bindings;
|
import 'bindings/remote.dart' as bindings;
|
||||||
|
|
||||||
class Remotes {
|
class Remote {
|
||||||
/// Initializes a new instance of the [Remotes] class from
|
/// Initializes a new instance of [Remote] class from provided pointer
|
||||||
/// provided [Repository] object.
|
/// to remote object in memory.
|
||||||
Remotes(Repository repo) {
|
Remote(this._remotePointer);
|
||||||
_repoPointer = repo.pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Pointer to memory address for allocated repository object.
|
/// Initializes a new instance of [Remote] class by looking up remote with
|
||||||
late final Pointer<git_repository> _repoPointer;
|
/// provided [name] in a [repo]sitory.
|
||||||
|
|
||||||
/// Returns a list of the configured remotes for a repo.
|
|
||||||
///
|
|
||||||
/// Throws a [LibGit2Error] if error occured.
|
|
||||||
List<String> get list {
|
|
||||||
return bindings.list(_repoPointer);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns number of the configured remotes for a repo.
|
|
||||||
int get length => list.length;
|
|
||||||
|
|
||||||
/// Returns [Remote] by looking up [name] in a repository.
|
|
||||||
///
|
///
|
||||||
/// The name will be checked for validity.
|
/// The name will be checked for validity.
|
||||||
///
|
///
|
||||||
/// Throws a [LibGit2Error] if error occured.
|
/// Throws a [LibGit2Error] if error occured.
|
||||||
Remote operator [](String name) {
|
Remote.lookup({required Repository repo, required String name}) {
|
||||||
return Remote(bindings.lookup(repoPointer: _repoPointer, name: name));
|
_remotePointer = bindings.lookup(repoPointer: repo.pointer, name: name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Adds a remote to the repository's configuration with the default [fetch]
|
/// Initializes a new instance of [Remote] class by adding a remote with
|
||||||
/// refspec if none provided .
|
/// provided [name] and [url] to the [repo]sitory's configuration with the
|
||||||
|
/// default [fetch] refspec if none provided .
|
||||||
///
|
///
|
||||||
/// Throws a [LibGit2Error] if error occured.
|
/// Throws a [LibGit2Error] if error occured.
|
||||||
Remote create({
|
Remote.create({
|
||||||
|
required Repository repo,
|
||||||
required String name,
|
required String name,
|
||||||
required String url,
|
required String url,
|
||||||
String? fetch,
|
String? fetch,
|
||||||
}) {
|
}) {
|
||||||
if (fetch == null) {
|
if (fetch == null) {
|
||||||
return Remote(bindings.create(
|
_remotePointer = bindings.create(
|
||||||
repoPointer: _repoPointer,
|
repoPointer: repo.pointer,
|
||||||
name: name,
|
name: name,
|
||||||
url: url,
|
url: url,
|
||||||
));
|
);
|
||||||
} else {
|
} else {
|
||||||
return Remote(bindings.createWithFetchSpec(
|
_remotePointer = bindings.createWithFetchSpec(
|
||||||
repoPointer: _repoPointer,
|
repoPointer: repo.pointer,
|
||||||
name: name,
|
name: name,
|
||||||
url: url,
|
url: url,
|
||||||
fetch: fetch,
|
fetch: fetch,
|
||||||
));
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
late final Pointer<git_remote> _remotePointer;
|
||||||
|
|
||||||
|
/// Pointer to memory address for allocated remote object.
|
||||||
|
Pointer<git_remote> get pointer => _remotePointer;
|
||||||
|
|
||||||
/// Deletes an existing persisted remote.
|
/// Deletes an existing persisted remote.
|
||||||
///
|
///
|
||||||
/// All remote-tracking branches and configuration settings for the remote will be removed.
|
/// All remote-tracking branches and configuration settings for the remote will be removed.
|
||||||
///
|
///
|
||||||
/// Throws a [LibGit2Error] if error occured.
|
/// Throws a [LibGit2Error] if error occured.
|
||||||
void delete(String name) {
|
static void delete({required Repository repo, required String name}) {
|
||||||
bindings.delete(repoPointer: _repoPointer, name: name);
|
bindings.delete(repoPointer: repo.pointer, name: name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Give the remote a new name.
|
/// Gives the remote a new name.
|
||||||
///
|
///
|
||||||
/// Returns list of non-default refspecs that cannot be renamed.
|
/// Returns list of non-default refspecs that cannot be renamed.
|
||||||
///
|
///
|
||||||
|
@ -78,23 +71,38 @@ class Remotes {
|
||||||
/// their list of refspecs.
|
/// their list of refspecs.
|
||||||
///
|
///
|
||||||
/// Throws a [LibGit2Error] if error occured.
|
/// Throws a [LibGit2Error] if error occured.
|
||||||
List<String> rename({required String remote, required String newName}) {
|
static List<String> rename({
|
||||||
|
required Repository repo,
|
||||||
|
required String oldName,
|
||||||
|
required String newName,
|
||||||
|
}) {
|
||||||
return bindings.rename(
|
return bindings.rename(
|
||||||
repoPointer: _repoPointer,
|
repoPointer: repo.pointer,
|
||||||
name: remote,
|
name: oldName,
|
||||||
newName: newName,
|
newName: newName,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns a list of the configured remotes for a [repo]sitory.
|
||||||
|
///
|
||||||
|
/// Throws a [LibGit2Error] if error occured.
|
||||||
|
static List<String> list(Repository repo) {
|
||||||
|
return bindings.list(repo.pointer);
|
||||||
|
}
|
||||||
|
|
||||||
/// Sets the remote's url in the configuration.
|
/// Sets the remote's url in the configuration.
|
||||||
///
|
///
|
||||||
/// Remote objects already in memory will not be affected. This assumes the common
|
/// Remote objects already in memory will not be affected. This assumes the common
|
||||||
/// case of a single-url remote and will otherwise return an error.
|
/// case of a single-url remote and will otherwise return an error.
|
||||||
///
|
///
|
||||||
/// Throws a [LibGit2Error] if error occured.
|
/// Throws a [LibGit2Error] if error occured.
|
||||||
void setUrl({required String remote, required String url}) {
|
static void setUrl({
|
||||||
|
required Repository repo,
|
||||||
|
required String remote,
|
||||||
|
required String url,
|
||||||
|
}) {
|
||||||
bindings.setUrl(
|
bindings.setUrl(
|
||||||
repoPointer: _repoPointer,
|
repoPointer: repo.pointer,
|
||||||
remote: remote,
|
remote: remote,
|
||||||
url: url,
|
url: url,
|
||||||
);
|
);
|
||||||
|
@ -106,9 +114,13 @@ class Remotes {
|
||||||
/// case of a single-url remote and will otherwise return an error.
|
/// case of a single-url remote and will otherwise return an error.
|
||||||
///
|
///
|
||||||
/// Throws a [LibGit2Error] if error occured.
|
/// Throws a [LibGit2Error] if error occured.
|
||||||
void setPushUrl({required String remote, required String url}) {
|
static void setPushUrl({
|
||||||
|
required Repository repo,
|
||||||
|
required String remote,
|
||||||
|
required String url,
|
||||||
|
}) {
|
||||||
bindings.setPushUrl(
|
bindings.setPushUrl(
|
||||||
repoPointer: _repoPointer,
|
repoPointer: repo.pointer,
|
||||||
remote: remote,
|
remote: remote,
|
||||||
url: url,
|
url: url,
|
||||||
);
|
);
|
||||||
|
@ -119,9 +131,13 @@ class Remotes {
|
||||||
/// No loaded remote instances will be affected.
|
/// No loaded remote instances will be affected.
|
||||||
///
|
///
|
||||||
/// Throws a [LibGit2Error] if error occured.
|
/// Throws a [LibGit2Error] if error occured.
|
||||||
void addFetch({required String remote, required String refspec}) {
|
static void addFetch({
|
||||||
|
required Repository repo,
|
||||||
|
required String remote,
|
||||||
|
required String refspec,
|
||||||
|
}) {
|
||||||
bindings.addFetch(
|
bindings.addFetch(
|
||||||
repoPointer: _repoPointer,
|
repoPointer: repo.pointer,
|
||||||
remote: remote,
|
remote: remote,
|
||||||
refspec: refspec,
|
refspec: refspec,
|
||||||
);
|
);
|
||||||
|
@ -132,24 +148,17 @@ class Remotes {
|
||||||
/// No loaded remote instances will be affected.
|
/// No loaded remote instances will be affected.
|
||||||
///
|
///
|
||||||
/// Throws a [LibGit2Error] if error occured.
|
/// Throws a [LibGit2Error] if error occured.
|
||||||
void addPush({required String remote, required String refspec}) {
|
static void addPush({
|
||||||
|
required Repository repo,
|
||||||
|
required String remote,
|
||||||
|
required String refspec,
|
||||||
|
}) {
|
||||||
bindings.addPush(
|
bindings.addPush(
|
||||||
repoPointer: _repoPointer,
|
repoPointer: repo.pointer,
|
||||||
remote: remote,
|
remote: remote,
|
||||||
refspec: refspec,
|
refspec: refspec,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
class Remote {
|
|
||||||
/// Initializes a new instance of [Remote] class from provided pointer
|
|
||||||
/// to remote object in memory.
|
|
||||||
const Remote(this._remotePointer);
|
|
||||||
|
|
||||||
final Pointer<git_remote> _remotePointer;
|
|
||||||
|
|
||||||
/// Pointer to memory address for allocated remote object.
|
|
||||||
Pointer<git_remote> get pointer => _remotePointer;
|
|
||||||
|
|
||||||
/// Returns the remote's name.
|
/// Returns the remote's name.
|
||||||
String get name => bindings.name(_remotePointer);
|
String get name => bindings.name(_remotePointer);
|
||||||
|
|
|
@ -130,6 +130,16 @@ class Repository {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns [Oid] object if it can be found in the ODB of repository with
|
||||||
|
/// provided hexadecimal [sha] string that is 40 characters long or shorter.
|
||||||
|
///
|
||||||
|
/// Throws [ArgumentError] if provided [sha] hex string is not valid.
|
||||||
|
///
|
||||||
|
/// Throws a [LibGit2Error] if error occured.
|
||||||
|
Oid operator [](String sha) {
|
||||||
|
return Oid.fromSHA(repo: this, sha: sha);
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns path to the `.git` folder for normal repositories
|
/// Returns path to the `.git` folder for normal repositories
|
||||||
/// or path to the repository itself for bare repositories.
|
/// or path to the repository itself for bare repositories.
|
||||||
String get path => bindings.path(_repoPointer);
|
String get path => bindings.path(_repoPointer);
|
||||||
|
@ -322,8 +332,89 @@ class Repository {
|
||||||
/// Must be freed once it's no longer being used.
|
/// 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 [References] object.
|
/// Returns a list of all the references that can be found in a repository.
|
||||||
References get references => References(this);
|
///
|
||||||
|
/// Throws a [LibGit2Error] if error occured.
|
||||||
|
List<String> get references => Reference.list(this);
|
||||||
|
|
||||||
|
/// Lookups reference [name] in a [repo]sitory.
|
||||||
|
///
|
||||||
|
/// Should be freed to release allocated memory.
|
||||||
|
///
|
||||||
|
/// The [name] will be checked for validity.
|
||||||
|
///
|
||||||
|
/// Throws a [LibGit2Error] if error occured.
|
||||||
|
Reference lookupReference(String name) {
|
||||||
|
return Reference.lookup(repo: this, name: name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates a new reference.
|
||||||
|
///
|
||||||
|
/// The reference will be created in the repository and written to the disk.
|
||||||
|
/// The generated [Reference] object must be freed by the user.
|
||||||
|
///
|
||||||
|
/// Valid reference [name]s must follow one of two patterns:
|
||||||
|
///
|
||||||
|
/// Top-level names must contain only capital letters and underscores, and must begin and end
|
||||||
|
/// with a letter. (e.g. "HEAD", "ORIG_HEAD").
|
||||||
|
/// Names prefixed with "refs/" can be almost anything. You must avoid the characters
|
||||||
|
/// '~', '^', ':', '\', '?', '[', and '*', and the sequences ".." and "@{" which have
|
||||||
|
/// special meaning to revparse.
|
||||||
|
///
|
||||||
|
/// Throws a [LibGit2Error] if a reference already exists with the given [name]
|
||||||
|
/// unless [force] is true, in which case it will be overwritten.
|
||||||
|
///
|
||||||
|
/// The [logMessage] message for the reflog will be ignored if the reference does not belong in the
|
||||||
|
/// standard set (HEAD, branches and remote-tracking branches) and it does not have a reflog.
|
||||||
|
Reference createReference({
|
||||||
|
required String name,
|
||||||
|
required Object target,
|
||||||
|
bool force = false,
|
||||||
|
String? logMessage,
|
||||||
|
}) {
|
||||||
|
return Reference.create(
|
||||||
|
repo: this,
|
||||||
|
name: name,
|
||||||
|
target: target,
|
||||||
|
force: force,
|
||||||
|
logMessage: logMessage,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Deletes an existing reference with provided [name].
|
||||||
|
///
|
||||||
|
/// This method works for both direct and symbolic references.
|
||||||
|
///
|
||||||
|
/// Throws a [LibGit2Error] if error occured.
|
||||||
|
void deleteReference(String name) => Reference.delete(repo: this, name: name);
|
||||||
|
|
||||||
|
/// Renames an existing reference.
|
||||||
|
///
|
||||||
|
/// This method works for both direct and symbolic references.
|
||||||
|
///
|
||||||
|
/// The [newName] will be checked for validity.
|
||||||
|
///
|
||||||
|
/// If the [force] flag is set to false, and there's already a reference with the given name,
|
||||||
|
/// the renaming will fail.
|
||||||
|
///
|
||||||
|
/// IMPORTANT: The user needs to write a proper reflog entry [logMessage] if the reflog is
|
||||||
|
/// enabled for the repository. We only rename the reflog if it exists.
|
||||||
|
///
|
||||||
|
/// Throws a [LibGit2Error] if error occured.
|
||||||
|
void renameReference({
|
||||||
|
required String oldName,
|
||||||
|
required String newName,
|
||||||
|
bool force = false,
|
||||||
|
String? logMessage,
|
||||||
|
}) {
|
||||||
|
Reference.rename(
|
||||||
|
repo: this,
|
||||||
|
oldName: oldName,
|
||||||
|
newName: newName,
|
||||||
|
force: force,
|
||||||
|
logMessage: logMessage,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns [Index] file for this repository.
|
/// Returns [Index] file for this repository.
|
||||||
///
|
///
|
||||||
|
@ -337,39 +428,11 @@ class Repository {
|
||||||
/// Throws a [LibGit2Error] if error occured.
|
/// Throws a [LibGit2Error] if error occured.
|
||||||
Odb get odb => Odb(bindings.odb(_repoPointer));
|
Odb get odb => Odb(bindings.odb(_repoPointer));
|
||||||
|
|
||||||
/// Looksup git object (commit, tree, blob, tag) for provided [sha] hex string.
|
/// Lookups a tree object for provided [id].
|
||||||
///
|
///
|
||||||
/// Returned object should be explicitly downcasted to one of four of git object types.
|
/// Should be freed to release allocated memory.
|
||||||
///
|
Tree lookupTree(Oid id) {
|
||||||
/// ```dart
|
return Tree.lookup(repo: this, id: id);
|
||||||
/// final commit = repo['s0m3sh4'] as Commit;
|
|
||||||
/// final tree = repo['s0m3sh4'] as Tree;
|
|
||||||
/// final blob = repo['s0m3sh4'] as Blob;
|
|
||||||
/// final tag = repo['s0m3sh4'] as Tag;
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// Throws [ArgumentError] if provided [sha] is not pointing to commit, tree, blob or tag.
|
|
||||||
Object operator [](String sha) {
|
|
||||||
final oid = Oid.fromSHA(repo: this, sha: sha);
|
|
||||||
final object = object_bindings.lookup(
|
|
||||||
repoPointer: _repoPointer,
|
|
||||||
oidPointer: oid.pointer,
|
|
||||||
type: GitObject.any.value,
|
|
||||||
);
|
|
||||||
final type = object_bindings.type(object);
|
|
||||||
|
|
||||||
if (type == GitObject.commit.value) {
|
|
||||||
return Commit(object.cast());
|
|
||||||
} else if (type == GitObject.tree.value) {
|
|
||||||
return Tree(object.cast());
|
|
||||||
} else if (type == GitObject.blob.value) {
|
|
||||||
return Blob(object.cast());
|
|
||||||
} else if (type == GitObject.tag.value) {
|
|
||||||
return Tag(object.cast());
|
|
||||||
} else {
|
|
||||||
throw ArgumentError.value(
|
|
||||||
'$sha should be pointing to either commit, tree, blob or a tag');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a new action signature with default user and now timestamp.
|
/// Creates a new action signature with default user and now timestamp.
|
||||||
|
@ -410,6 +473,13 @@ class Repository {
|
||||||
return RevParse.single(repo: this, spec: spec);
|
return RevParse.single(repo: this, spec: spec);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Lookups commit object for provided [id].
|
||||||
|
///
|
||||||
|
/// Should be freed to release allocated memory.
|
||||||
|
Commit lookupCommit(Oid id) {
|
||||||
|
return Commit.lookup(repo: this, id: id);
|
||||||
|
}
|
||||||
|
|
||||||
/// Creates new commit in the repository.
|
/// Creates new commit in the repository.
|
||||||
///
|
///
|
||||||
/// [updateRef] is name of the reference that will be updated to point to this commit.
|
/// [updateRef] is name of the reference that will be updated to point to this commit.
|
||||||
|
@ -423,8 +493,8 @@ class Repository {
|
||||||
required String message,
|
required String message,
|
||||||
required Signature author,
|
required Signature author,
|
||||||
required Signature commiter,
|
required Signature commiter,
|
||||||
required String treeSHA,
|
required Tree tree,
|
||||||
required List<String> parents,
|
required List<Commit> parents,
|
||||||
String? updateRef,
|
String? updateRef,
|
||||||
String? messageEncoding,
|
String? messageEncoding,
|
||||||
}) {
|
}) {
|
||||||
|
@ -433,7 +503,7 @@ class Repository {
|
||||||
message: message,
|
message: message,
|
||||||
author: author,
|
author: author,
|
||||||
commiter: commiter,
|
commiter: commiter,
|
||||||
treeSHA: treeSHA,
|
tree: tree,
|
||||||
parents: parents,
|
parents: parents,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -464,6 +534,13 @@ class Repository {
|
||||||
return RevParse.range(repo: this, spec: spec);
|
return RevParse.range(repo: this, spec: spec);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Lookups a blob object for provided [id].
|
||||||
|
///
|
||||||
|
/// Should be freed to release allocated memory.
|
||||||
|
Blob lookupBlob(Oid id) {
|
||||||
|
return Blob.lookup(repo: this, id: id);
|
||||||
|
}
|
||||||
|
|
||||||
/// Creates a new blob from a [content] string and writes it to ODB.
|
/// Creates a new blob from a [content] string and writes it to ODB.
|
||||||
///
|
///
|
||||||
/// Throws a [LibGit2Error] if error occured.
|
/// Throws a [LibGit2Error] if error occured.
|
||||||
|
@ -487,12 +564,22 @@ class Repository {
|
||||||
return Blob.createFromDisk(repo: this, path: path);
|
return Blob.createFromDisk(repo: this, path: path);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a new tag in the repository from provided Oid object.
|
/// Returns a list with all the tags in the repository.
|
||||||
///
|
///
|
||||||
/// A new reference will also be created pointing to this tag object. If force is true
|
/// Throws a [LibGit2Error] if error occured.
|
||||||
|
List<String> get tags => Tag.list(this);
|
||||||
|
|
||||||
|
/// Lookups tag object for provided [id].
|
||||||
|
///
|
||||||
|
/// Should be freed to release allocated memory.
|
||||||
|
Tag lookupTag(Oid id) => Tag.lookup(repo: this, id: id);
|
||||||
|
|
||||||
|
/// Creates a new tag in the repository for provided [target] object.
|
||||||
|
///
|
||||||
|
/// A new reference will also be created pointing to this tag object. If [force] is true
|
||||||
/// and a reference already exists with the given name, it'll be replaced.
|
/// and a reference already exists with the given name, it'll be replaced.
|
||||||
///
|
///
|
||||||
/// The message will not be cleaned up.
|
/// The [message] will not be cleaned up.
|
||||||
///
|
///
|
||||||
/// The tag name will be checked for validity. You must avoid the characters
|
/// The tag name will be checked for validity. You must avoid the characters
|
||||||
/// '~', '^', ':', '\', '?', '[', and '*', and the sequences ".." and "@{" which have
|
/// '~', '^', ':', '\', '?', '[', and '*', and the sequences ".." and "@{" which have
|
||||||
|
@ -501,7 +588,7 @@ class Repository {
|
||||||
/// Throws a [LibGit2Error] if error occured.
|
/// Throws a [LibGit2Error] if error occured.
|
||||||
Oid createTag({
|
Oid createTag({
|
||||||
required String tagName,
|
required String tagName,
|
||||||
required String target,
|
required Oid target,
|
||||||
required GitObject targetType,
|
required GitObject targetType,
|
||||||
required Signature tagger,
|
required Signature tagger,
|
||||||
required String message,
|
required String message,
|
||||||
|
@ -517,13 +604,93 @@ class Repository {
|
||||||
force: force);
|
force: force);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a list with all the tags in the repository.
|
/// Deletes an existing tag reference with provided [name].
|
||||||
|
///
|
||||||
|
/// The tag [name] will be checked for validity.
|
||||||
///
|
///
|
||||||
/// Throws a [LibGit2Error] if error occured.
|
/// Throws a [LibGit2Error] if error occured.
|
||||||
List<String> get tags => Tag.list(this);
|
void deleteTag(String name) => Tag.delete(repo: this, name: name);
|
||||||
|
|
||||||
/// Returns a [Branches] object.
|
/// Returns a list of all branches that can be found in a repository.
|
||||||
Branches get branches => Branches(this);
|
///
|
||||||
|
/// IMPORTANT: Branches must be freed manually when no longer needed to prevent
|
||||||
|
/// memory leak.
|
||||||
|
///
|
||||||
|
/// Throws a [LibGit2Error] if error occured.
|
||||||
|
List<Branch> get branches => Branch.list(repo: this);
|
||||||
|
|
||||||
|
/// Returns a list of local branches that can be found in a repository.
|
||||||
|
///
|
||||||
|
/// IMPORTANT: Branches must be freed manually when no longer needed to prevent
|
||||||
|
/// memory leak.
|
||||||
|
///
|
||||||
|
/// Throws a [LibGit2Error] if error occured.
|
||||||
|
List<Branch> get branchesLocal =>
|
||||||
|
Branch.list(repo: this, type: GitBranch.local);
|
||||||
|
|
||||||
|
/// Returns a list of remote branches that can be found in a repository.
|
||||||
|
///
|
||||||
|
/// IMPORTANT: Branches must be freed manually when no longer needed to prevent
|
||||||
|
/// memory leak.
|
||||||
|
///
|
||||||
|
/// Throws a [LibGit2Error] if error occured.
|
||||||
|
List<Branch> get branchesRemote =>
|
||||||
|
Branch.list(repo: this, type: GitBranch.remote);
|
||||||
|
|
||||||
|
/// Lookups a branch by its [name] in a repository.
|
||||||
|
///
|
||||||
|
/// The branch name will be checked for validity.
|
||||||
|
///
|
||||||
|
/// Should be freed to release allocated memory when no longer needed.
|
||||||
|
///
|
||||||
|
/// Throws a [LibGit2Error] if error occured.
|
||||||
|
Branch lookupBranch(String name) {
|
||||||
|
return Branch.lookup(repo: this, name: name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates a new branch pointing at a [target] commit.
|
||||||
|
///
|
||||||
|
/// A new direct reference will be created pointing to this target commit.
|
||||||
|
/// If [force] is true and a reference already exists with the given name, it'll be replaced.
|
||||||
|
///
|
||||||
|
/// Should be freed with [free] to release allocated memory when no longer
|
||||||
|
/// needed.
|
||||||
|
///
|
||||||
|
/// The branch name will be checked for validity.
|
||||||
|
///
|
||||||
|
/// Throws a [LibGit2Error] if error occured.
|
||||||
|
Branch createBranch({
|
||||||
|
required String name,
|
||||||
|
required Commit target,
|
||||||
|
bool force = false,
|
||||||
|
}) {
|
||||||
|
return Branch.create(
|
||||||
|
repo: this,
|
||||||
|
name: name,
|
||||||
|
target: target,
|
||||||
|
force: force,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Deletes an existing branch reference.
|
||||||
|
///
|
||||||
|
/// Throws a [LibGit2Error] if error occured.
|
||||||
|
void deleteBranch(String name) => Branch.delete(repo: this, name: name);
|
||||||
|
|
||||||
|
/// Renames an existing local branch reference.
|
||||||
|
///
|
||||||
|
/// The new branch name will be checked for validity.
|
||||||
|
///
|
||||||
|
/// If [force] is true, existing branch will be overwritten.
|
||||||
|
///
|
||||||
|
/// Throws a [LibGit2Error] if error occured.
|
||||||
|
void renameBranch({
|
||||||
|
required String oldName,
|
||||||
|
required String newName,
|
||||||
|
bool force = false,
|
||||||
|
}) {
|
||||||
|
Branch.rename(repo: this, oldName: oldName, newName: newName, force: force);
|
||||||
|
}
|
||||||
|
|
||||||
/// Checks status of the repository and returns map of file paths and their statuses.
|
/// Checks status of the repository and returns map of file paths and their statuses.
|
||||||
///
|
///
|
||||||
|
@ -619,7 +786,7 @@ class Repository {
|
||||||
required Oid theirHead,
|
required Oid theirHead,
|
||||||
String ourRef = 'HEAD',
|
String ourRef = 'HEAD',
|
||||||
}) {
|
}) {
|
||||||
final ref = references[ourRef];
|
final ref = lookupReference(ourRef);
|
||||||
final head = commit_bindings.annotatedLookup(
|
final head = commit_bindings.annotatedLookup(
|
||||||
repoPointer: _repoPointer,
|
repoPointer: _repoPointer,
|
||||||
oidPointer: theirHead.pointer,
|
oidPointer: theirHead.pointer,
|
||||||
|
@ -831,7 +998,7 @@ class Repository {
|
||||||
paths: paths,
|
paths: paths,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
final ref = references[refName];
|
final ref = lookupReference(refName);
|
||||||
final treeish = object_bindings.lookup(
|
final treeish = object_bindings.lookup(
|
||||||
repoPointer: _repoPointer,
|
repoPointer: _repoPointer,
|
||||||
oidPointer: ref.target.pointer,
|
oidPointer: ref.target.pointer,
|
||||||
|
@ -1062,8 +1229,57 @@ class Repository {
|
||||||
return stash_bindings.list(_repoPointer);
|
return stash_bindings.list(_repoPointer);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns [Remotes] object.
|
/// Returns a list of the configured remotes for a repository.
|
||||||
Remotes get remotes => Remotes(this);
|
///
|
||||||
|
/// Throws a [LibGit2Error] if error occured.
|
||||||
|
List<String> get remotes => Remote.list(this);
|
||||||
|
|
||||||
|
/// Lookups remote with provided [name].
|
||||||
|
///
|
||||||
|
/// The name will be checked for validity.
|
||||||
|
///
|
||||||
|
/// Throws a [LibGit2Error] if error occured.
|
||||||
|
Remote lookupRemote(String name) {
|
||||||
|
return Remote.lookup(repo: this, name: name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Adds a remote with provided [name] and [url] to the repository's
|
||||||
|
/// configuration with the default [fetch] refspec if none provided .
|
||||||
|
///
|
||||||
|
/// Throws a [LibGit2Error] if error occured.
|
||||||
|
Remote createRemote({
|
||||||
|
required String name,
|
||||||
|
required String url,
|
||||||
|
String? fetch,
|
||||||
|
}) {
|
||||||
|
return Remote.create(repo: this, name: name, url: url, fetch: fetch);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Deletes an existing persisted remote.
|
||||||
|
///
|
||||||
|
/// All remote-tracking branches and configuration settings for the remote will be removed.
|
||||||
|
///
|
||||||
|
/// Throws a [LibGit2Error] if error occured.
|
||||||
|
void deleteRemote(String name) => Remote.delete(repo: this, name: name);
|
||||||
|
|
||||||
|
/// Gives the remote a new name.
|
||||||
|
///
|
||||||
|
/// Returns list of non-default refspecs that cannot be renamed.
|
||||||
|
///
|
||||||
|
/// All remote-tracking branches and configuration settings for the remote are updated.
|
||||||
|
///
|
||||||
|
/// The new name will be checked for validity.
|
||||||
|
///
|
||||||
|
/// No loaded instances of a the remote with the old name will change their name or
|
||||||
|
/// their list of refspecs.
|
||||||
|
///
|
||||||
|
/// Throws a [LibGit2Error] if error occured.
|
||||||
|
List<String> renameRemote({
|
||||||
|
required String oldName,
|
||||||
|
required String newName,
|
||||||
|
}) {
|
||||||
|
return Remote.rename(repo: this, oldName: oldName, newName: newName);
|
||||||
|
}
|
||||||
|
|
||||||
/// Looks up the value of one git attribute for path.
|
/// Looks up the value of one git attribute for path.
|
||||||
///
|
///
|
||||||
|
@ -1132,49 +1348,69 @@ class Repository {
|
||||||
|
|
||||||
/// Returns list of notes for repository.
|
/// Returns list of notes for repository.
|
||||||
///
|
///
|
||||||
/// Notes must be freed manually.
|
/// IMPORTANT: Notes must be freed manually when no longer needed to prevent
|
||||||
|
/// memory leak.
|
||||||
///
|
///
|
||||||
/// Throws a [LibGit2Error] if error occured.
|
/// Throws a [LibGit2Error] if error occured.
|
||||||
List<Note> get notes => Notes(this).list;
|
List<Note> get notes => Note.list(this);
|
||||||
|
|
||||||
/// Reads the note for an object.
|
/// Reads the note for an [annotatedId].
|
||||||
///
|
///
|
||||||
/// The note must be freed manually.
|
/// IMPORTANT: Notes must be freed manually when no longer needed to prevent
|
||||||
|
/// memory leak.
|
||||||
///
|
///
|
||||||
/// Throws a [LibGit2Error] if error occured.
|
/// Throws a [LibGit2Error] if error occured.
|
||||||
Note lookupNote({
|
Note lookupNote({
|
||||||
required Oid annotatedId,
|
required Oid annotatedId,
|
||||||
String notesRef = 'refs/notes/commits',
|
String notesRef = 'refs/notes/commits',
|
||||||
}) {
|
}) {
|
||||||
return Notes.lookup(
|
return Note.lookup(
|
||||||
repo: this,
|
repo: this,
|
||||||
annotatedId: annotatedId,
|
annotatedId: annotatedId,
|
||||||
notesRef: notesRef,
|
notesRef: notesRef,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Adds a note for an [object].
|
/// Adds a note for an [annotatedId].
|
||||||
///
|
///
|
||||||
/// Throws a [LibGit2Error] if error occured.
|
/// Throws a [LibGit2Error] if error occured.
|
||||||
Oid createNote({
|
Oid createNote({
|
||||||
required Signature author,
|
required Signature author,
|
||||||
required Signature committer,
|
required Signature committer,
|
||||||
required Oid object,
|
required Oid annotatedId,
|
||||||
required String note,
|
required String note,
|
||||||
String notesRef = 'refs/notes/commits',
|
String notesRef = 'refs/notes/commits',
|
||||||
bool force = false,
|
bool force = false,
|
||||||
}) {
|
}) {
|
||||||
return Notes.create(
|
return Note.create(
|
||||||
repo: this,
|
repo: this,
|
||||||
author: author,
|
author: author,
|
||||||
committer: committer,
|
committer: committer,
|
||||||
object: object,
|
annotatedId: annotatedId,
|
||||||
note: note,
|
note: note,
|
||||||
notesRef: notesRef,
|
notesRef: notesRef,
|
||||||
force: force,
|
force: force,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Deletes the note for an [annotatedId].
|
||||||
|
///
|
||||||
|
/// Throws a [LibGit2Error] if error occured.
|
||||||
|
void deleteNote({
|
||||||
|
required Oid annotatedId,
|
||||||
|
required Signature author,
|
||||||
|
required Signature committer,
|
||||||
|
String notesRef = 'refs/notes/commits',
|
||||||
|
}) {
|
||||||
|
Note.delete(
|
||||||
|
repo: this,
|
||||||
|
annotatedId: annotatedId,
|
||||||
|
author: author,
|
||||||
|
committer: committer,
|
||||||
|
notesRef: notesRef,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/// Checks if a commit is the descendant of another commit.
|
/// Checks if a commit is the descendant of another commit.
|
||||||
///
|
///
|
||||||
/// Note that a commit is not considered a descendant of itself, in contrast to
|
/// Note that a commit is not considered a descendant of itself, in contrast to
|
||||||
|
@ -1397,4 +1633,34 @@ class Repository {
|
||||||
callbacks: callbacks,
|
callbacks: callbacks,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns list of names of linked working trees.
|
||||||
|
///
|
||||||
|
/// Throws a [LibGit2Error] if error occured.
|
||||||
|
List<String> get worktrees => Worktree.list(this);
|
||||||
|
|
||||||
|
/// Lookups up existing worktree for provided [name].
|
||||||
|
///
|
||||||
|
/// Should be freed to release allocated memory.
|
||||||
|
///
|
||||||
|
/// Throws a [LibGit2Error] if error occured.
|
||||||
|
Worktree lookupWorktree(String name) {
|
||||||
|
return Worktree.lookup(repo: this, name: name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates new worktree.
|
||||||
|
///
|
||||||
|
/// 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.
|
||||||
|
///
|
||||||
|
/// Throws a [LibGit2Error] if error occured.
|
||||||
|
Worktree createWorktree({
|
||||||
|
required String name,
|
||||||
|
required String path,
|
||||||
|
Reference? ref,
|
||||||
|
}) {
|
||||||
|
return Worktree.create(repo: this, name: name, path: path, ref: ref);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,18 +8,16 @@ class Tag {
|
||||||
/// Initializes a new instance of [Tag] class from provided pointer to
|
/// Initializes a new instance of [Tag] class from provided pointer to
|
||||||
/// tag object in memory.
|
/// tag object in memory.
|
||||||
///
|
///
|
||||||
/// Should be freed with `free()` to release allocated memory.
|
/// Should be freed to release allocated memory.
|
||||||
Tag(this._tagPointer);
|
Tag(this._tagPointer);
|
||||||
|
|
||||||
/// Initializes a new instance of [Tag] class from provided
|
/// Lookups tag object for provided [id] in a [repo]sitory.
|
||||||
/// [Repository] object and [sha] hex string.
|
|
||||||
///
|
///
|
||||||
/// Should be freed with `free()` to release allocated memory.
|
/// Should be freed to release allocated memory.
|
||||||
Tag.lookup({required Repository repo, required String sha}) {
|
Tag.lookup({required Repository repo, required Oid id}) {
|
||||||
final oid = Oid.fromSHA(repo: repo, sha: sha);
|
|
||||||
_tagPointer = bindings.lookup(
|
_tagPointer = bindings.lookup(
|
||||||
repoPointer: repo.pointer,
|
repoPointer: repo.pointer,
|
||||||
oidPointer: oid.pointer,
|
oidPointer: id.pointer,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,12 +26,12 @@ class Tag {
|
||||||
/// Pointer to memory address for allocated tag object.
|
/// Pointer to memory address for allocated tag object.
|
||||||
Pointer<git_tag> get pointer => _tagPointer;
|
Pointer<git_tag> get pointer => _tagPointer;
|
||||||
|
|
||||||
/// Creates a new tag in the repository from provided Oid object.
|
/// Creates a new tag in the repository for provided [target] object.
|
||||||
///
|
///
|
||||||
/// A new reference will also be created pointing to this tag object. If force is true
|
/// A new reference will also be created pointing to this tag object. If [force] is true
|
||||||
/// and a reference already exists with the given name, it'll be replaced.
|
/// and a reference already exists with the given name, it'll be replaced.
|
||||||
///
|
///
|
||||||
/// The message will not be cleaned up.
|
/// The [message] will not be cleaned up.
|
||||||
///
|
///
|
||||||
/// The tag name will be checked for validity. You must avoid the characters
|
/// The tag name will be checked for validity. You must avoid the characters
|
||||||
/// '~', '^', ':', '\', '?', '[', and '*', and the sequences ".." and "@{" which have
|
/// '~', '^', ':', '\', '?', '[', and '*', and the sequences ".." and "@{" which have
|
||||||
|
@ -43,16 +41,15 @@ class Tag {
|
||||||
static Oid create({
|
static Oid create({
|
||||||
required Repository repo,
|
required Repository repo,
|
||||||
required String tagName,
|
required String tagName,
|
||||||
required String target,
|
required Oid target,
|
||||||
required GitObject targetType,
|
required GitObject targetType,
|
||||||
required Signature tagger,
|
required Signature tagger,
|
||||||
required String message,
|
required String message,
|
||||||
bool force = false,
|
bool force = false,
|
||||||
}) {
|
}) {
|
||||||
final targetOid = Oid.fromSHA(repo: repo, sha: target);
|
|
||||||
final object = object_bindings.lookup(
|
final object = object_bindings.lookup(
|
||||||
repoPointer: repo.pointer,
|
repoPointer: repo.pointer,
|
||||||
oidPointer: targetOid.pointer,
|
oidPointer: target.pointer,
|
||||||
type: targetType.value,
|
type: targetType.value,
|
||||||
);
|
);
|
||||||
final result = bindings.create(
|
final result = bindings.create(
|
||||||
|
@ -68,6 +65,15 @@ class Tag {
|
||||||
return Oid(result);
|
return Oid(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Deletes an existing tag reference with provided [name] in a [repo]sitory.
|
||||||
|
///
|
||||||
|
/// The tag [name] will be checked for validity.
|
||||||
|
///
|
||||||
|
/// Throws a [LibGit2Error] if error occured.
|
||||||
|
static void delete({required Repository repo, required String name}) {
|
||||||
|
bindings.delete(repoPointer: repo.pointer, tagName: name);
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns a list with all the tags in the repository.
|
/// Returns a list with all the tags in the repository.
|
||||||
///
|
///
|
||||||
/// Throws a [LibGit2Error] if error occured.
|
/// Throws a [LibGit2Error] if error occured.
|
||||||
|
@ -123,16 +129,6 @@ class Tag {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Deletes an existing tag reference.
|
|
||||||
///
|
|
||||||
/// The tag name will be checked for validity.
|
|
||||||
///
|
|
||||||
/// Throws a [LibGit2Error] if error occured.
|
|
||||||
void delete() {
|
|
||||||
final owner = bindings.owner(_tagPointer);
|
|
||||||
bindings.delete(repoPointer: owner, tagName: name);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Releases memory allocated for tag object.
|
/// Releases memory allocated for tag object.
|
||||||
void free() => bindings.free(_tagPointer);
|
void free() => bindings.free(_tagPointer);
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,18 +8,16 @@ class Tree {
|
||||||
/// Initializes a new instance of [Tree] class from provided pointer to
|
/// Initializes a new instance of [Tree] class from provided pointer to
|
||||||
/// tree object in memory.
|
/// tree object in memory.
|
||||||
///
|
///
|
||||||
/// Should be freed with `free()` to release allocated memory.
|
/// Should be freed to release allocated memory.
|
||||||
Tree(this._treePointer);
|
Tree(this._treePointer);
|
||||||
|
|
||||||
/// Initializes a new instance of [Tree] class from provided
|
/// Lookups a tree object for provided [id] in a [repo]sitory.
|
||||||
/// [Repository] object and [sha] hex string.
|
|
||||||
///
|
///
|
||||||
/// Should be freed with `free()` to release allocated memory.
|
/// Should be freed to release allocated memory.
|
||||||
Tree.lookup({required Repository repo, required String sha}) {
|
Tree.lookup({required Repository repo, required Oid id}) {
|
||||||
final oid = Oid.fromSHA(repo: repo, sha: sha);
|
|
||||||
_treePointer = bindings.lookup(
|
_treePointer = bindings.lookup(
|
||||||
repoPointer: repo.pointer,
|
repoPointer: repo.pointer,
|
||||||
oidPointer: oid.pointer,
|
oidPointer: id.pointer,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,9 +5,9 @@ import 'bindings/treebuilder.dart' as bindings;
|
||||||
|
|
||||||
class TreeBuilder {
|
class TreeBuilder {
|
||||||
/// Initializes a new instance of [TreeBuilder] class from provided
|
/// Initializes a new instance of [TreeBuilder] class from provided
|
||||||
/// [Repository] and optional [Tree] objects.
|
/// [repo]sitory and optional [tree] objects.
|
||||||
///
|
///
|
||||||
/// Should be freed with `free()` to release allocated memory.
|
/// Should be freed to release allocated memory.
|
||||||
///
|
///
|
||||||
/// Throws a [LibGit2Error] if error occured.
|
/// Throws a [LibGit2Error] if error occured.
|
||||||
TreeBuilder({required Repository repo, Tree? tree}) {
|
TreeBuilder({required Repository repo, Tree? tree}) {
|
||||||
|
@ -79,6 +79,6 @@ class TreeBuilder {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Releases memory allocated for tree builder object.
|
/// Releases memory allocated for tree builder object and all the entries.
|
||||||
void free() => bindings.free(_treeBuilderPointer);
|
void free() => bindings.free(_treeBuilderPointer);
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,8 +10,8 @@ void main() {
|
||||||
late Signature sig2;
|
late Signature sig2;
|
||||||
var hunks = <Map<String, dynamic>>[];
|
var hunks = <Map<String, dynamic>>[];
|
||||||
|
|
||||||
setUp(() async {
|
setUp(() {
|
||||||
tmpDir = await setupRepo(Directory('test/assets/blamerepo/'));
|
tmpDir = setupRepo(Directory('test/assets/blamerepo/'));
|
||||||
repo = Repository.open(tmpDir.path);
|
repo = Repository.open(tmpDir.path);
|
||||||
sig1 = Signature.create(
|
sig1 = Signature.create(
|
||||||
name: 'Aleksey Kulikov',
|
name: 'Aleksey Kulikov',
|
||||||
|
@ -48,11 +48,11 @@ void main() {
|
||||||
];
|
];
|
||||||
});
|
});
|
||||||
|
|
||||||
tearDown(() async {
|
tearDown(() {
|
||||||
sig1.free();
|
sig1.free();
|
||||||
sig2.free();
|
sig2.free();
|
||||||
repo.free();
|
repo.free();
|
||||||
await tmpDir.delete(recursive: true);
|
tmpDir.deleteSync(recursive: true);
|
||||||
});
|
});
|
||||||
|
|
||||||
group('Blame', () {
|
group('Blame', () {
|
||||||
|
|
|
@ -11,16 +11,16 @@ void main() {
|
||||||
const blobContent = 'Feature edit\n';
|
const blobContent = 'Feature edit\n';
|
||||||
const newBlobContent = 'New blob\n';
|
const newBlobContent = 'New blob\n';
|
||||||
|
|
||||||
setUp(() async {
|
setUp(() {
|
||||||
tmpDir = await setupRepo(Directory('test/assets/testrepo/'));
|
tmpDir = setupRepo(Directory('test/assets/testrepo/'));
|
||||||
repo = Repository.open(tmpDir.path);
|
repo = Repository.open(tmpDir.path);
|
||||||
blob = Blob.lookup(repo: repo, sha: blobSHA);
|
blob = repo.lookupBlob(repo[blobSHA]);
|
||||||
});
|
});
|
||||||
|
|
||||||
tearDown(() async {
|
tearDown(() {
|
||||||
blob.free();
|
blob.free();
|
||||||
repo.free();
|
repo.free();
|
||||||
await tmpDir.delete(recursive: true);
|
tmpDir.deleteSync(recursive: true);
|
||||||
});
|
});
|
||||||
|
|
||||||
group('Blob', () {
|
group('Blob', () {
|
||||||
|
@ -36,8 +36,8 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('successfully creates new blob', () {
|
test('successfully creates new blob', () {
|
||||||
final oid = Blob.create(repo: repo, content: newBlobContent);
|
final oid = repo.createBlob(newBlobContent);
|
||||||
final newBlob = Blob.lookup(repo: repo, sha: oid.sha);
|
final newBlob = repo.lookupBlob(oid);
|
||||||
|
|
||||||
expect(newBlob.id.sha, '18fdaeef018e57a92bcad2d4a35b577f34089af6');
|
expect(newBlob.id.sha, '18fdaeef018e57a92bcad2d4a35b577f34089af6');
|
||||||
expect(newBlob.isBinary, false);
|
expect(newBlob.isBinary, false);
|
||||||
|
@ -49,11 +49,8 @@ void main() {
|
||||||
|
|
||||||
test('successfully creates new blob from file at provided relative path',
|
test('successfully creates new blob from file at provided relative path',
|
||||||
() {
|
() {
|
||||||
final oid = Blob.createFromWorkdir(
|
final oid = repo.createBlobFromWorkdir('feature_file');
|
||||||
repo: repo,
|
final newBlob = repo.lookupBlob(oid);
|
||||||
relativePath: 'feature_file',
|
|
||||||
);
|
|
||||||
final newBlob = Blob.lookup(repo: repo, sha: oid.sha);
|
|
||||||
|
|
||||||
expect(newBlob.id.sha, blobSHA);
|
expect(newBlob.id.sha, blobSHA);
|
||||||
expect(newBlob.isBinary, false);
|
expect(newBlob.isBinary, false);
|
||||||
|
@ -65,10 +62,7 @@ void main() {
|
||||||
|
|
||||||
test('throws when creating new blob from invalid path', () {
|
test('throws when creating new blob from invalid path', () {
|
||||||
expect(
|
expect(
|
||||||
() => Blob.createFromWorkdir(
|
() => repo.createBlobFromWorkdir('invalid/path.txt'),
|
||||||
repo: repo,
|
|
||||||
relativePath: 'invalid/path.txt',
|
|
||||||
),
|
|
||||||
throwsA(isA<LibGit2Error>()),
|
throwsA(isA<LibGit2Error>()),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@ -79,10 +73,7 @@ void main() {
|
||||||
final outsideFile =
|
final outsideFile =
|
||||||
File('${Directory.current.absolute.path}/test/blob_test.dart');
|
File('${Directory.current.absolute.path}/test/blob_test.dart');
|
||||||
expect(
|
expect(
|
||||||
() => Blob.createFromWorkdir(
|
() => repo.createBlobFromWorkdir(outsideFile.path),
|
||||||
repo: repo,
|
|
||||||
relativePath: outsideFile.path,
|
|
||||||
),
|
|
||||||
throwsA(isA<LibGit2Error>()),
|
throwsA(isA<LibGit2Error>()),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@ -90,8 +81,8 @@ void main() {
|
||||||
test('successfully creates new blob from file at provided path', () {
|
test('successfully creates new blob from file at provided path', () {
|
||||||
final outsideFile =
|
final outsideFile =
|
||||||
File('${Directory.current.absolute.path}/test/blob_test.dart');
|
File('${Directory.current.absolute.path}/test/blob_test.dart');
|
||||||
final oid = Blob.createFromDisk(repo: repo, path: outsideFile.path);
|
final oid = repo.createBlobFromDisk(outsideFile.path);
|
||||||
final newBlob = Blob.lookup(repo: repo, sha: oid.sha);
|
final newBlob = repo.lookupBlob(oid);
|
||||||
|
|
||||||
expect(newBlob, isA<Blob>());
|
expect(newBlob, isA<Blob>());
|
||||||
expect(newBlob.isBinary, false);
|
expect(newBlob.isBinary, false);
|
||||||
|
@ -101,8 +92,6 @@ void main() {
|
||||||
|
|
||||||
group('diff', () {
|
group('diff', () {
|
||||||
const path = 'feature_file';
|
const path = 'feature_file';
|
||||||
const oldBlobSha = 'e69de29bb2d1d6434b8b29ae775ad8c2e48c5391';
|
|
||||||
const newBlobSha = '9c78c21d6680a7ffebc76f7ac68cacc11d8f48bc';
|
|
||||||
const blobPatch = """
|
const blobPatch = """
|
||||||
diff --git a/feature_file b/feature_file
|
diff --git a/feature_file b/feature_file
|
||||||
index e69de29..9c78c21 100644
|
index e69de29..9c78c21 100644
|
||||||
|
@ -120,8 +109,12 @@ index e69de29..0000000
|
||||||
+++ /dev/null
|
+++ /dev/null
|
||||||
""";
|
""";
|
||||||
test('successfully creates from blobs', () {
|
test('successfully creates from blobs', () {
|
||||||
final a = repo[oldBlobSha] as Blob;
|
final a = repo.lookupBlob(
|
||||||
final b = repo[newBlobSha] as Blob;
|
repo['e69de29bb2d1d6434b8b29ae775ad8c2e48c5391'],
|
||||||
|
);
|
||||||
|
final b = repo.lookupBlob(
|
||||||
|
repo['9c78c21d6680a7ffebc76f7ac68cacc11d8f48bc'],
|
||||||
|
);
|
||||||
final patch = repo.diffBlobs(
|
final patch = repo.diffBlobs(
|
||||||
a: a,
|
a: a,
|
||||||
b: b,
|
b: b,
|
||||||
|
@ -135,7 +128,9 @@ index e69de29..0000000
|
||||||
});
|
});
|
||||||
|
|
||||||
test('successfully creates from one blob (delete)', () {
|
test('successfully creates from one blob (delete)', () {
|
||||||
final a = repo[oldBlobSha] as Blob;
|
final a = repo.lookupBlob(
|
||||||
|
repo['e69de29bb2d1d6434b8b29ae775ad8c2e48c5391'],
|
||||||
|
);
|
||||||
final patch = a.diff(
|
final patch = a.diff(
|
||||||
newBlob: null,
|
newBlob: null,
|
||||||
oldAsPath: path,
|
oldAsPath: path,
|
||||||
|
@ -148,7 +143,9 @@ index e69de29..0000000
|
||||||
});
|
});
|
||||||
|
|
||||||
test('successfully creates from blob and buffer', () {
|
test('successfully creates from blob and buffer', () {
|
||||||
final a = repo[oldBlobSha] as Blob;
|
final a = repo.lookupBlob(
|
||||||
|
repo['e69de29bb2d1d6434b8b29ae775ad8c2e48c5391'],
|
||||||
|
);
|
||||||
final patch = Patch.createFrom(
|
final patch = Patch.createFrom(
|
||||||
a: a,
|
a: a,
|
||||||
b: 'Feature edit\n',
|
b: 'Feature edit\n',
|
||||||
|
@ -162,7 +159,9 @@ index e69de29..0000000
|
||||||
});
|
});
|
||||||
|
|
||||||
test('successfully creates from blob and buffer (delete)', () {
|
test('successfully creates from blob and buffer (delete)', () {
|
||||||
final a = repo[oldBlobSha] as Blob;
|
final a = repo.lookupBlob(
|
||||||
|
repo['e69de29bb2d1d6434b8b29ae775ad8c2e48c5391'],
|
||||||
|
);
|
||||||
final patch = Patch.createFrom(
|
final patch = Patch.createFrom(
|
||||||
a: a,
|
a: a,
|
||||||
b: null,
|
b: null,
|
||||||
|
|
|
@ -6,48 +6,59 @@ import 'helpers/util.dart';
|
||||||
void main() {
|
void main() {
|
||||||
late Repository repo;
|
late Repository repo;
|
||||||
late Directory tmpDir;
|
late Directory tmpDir;
|
||||||
const lastCommit = '821ed6e80627b8769d170a293862f9fc60825226';
|
late Oid lastCommit;
|
||||||
const featureCommit = '5aecfa0fb97eadaac050ccb99f03c3fb65460ad4';
|
late Oid featureCommit;
|
||||||
|
|
||||||
setUp(() async {
|
setUp(() {
|
||||||
tmpDir = await setupRepo(Directory('test/assets/testrepo/'));
|
tmpDir = setupRepo(Directory('test/assets/testrepo/'));
|
||||||
repo = Repository.open(tmpDir.path);
|
repo = Repository.open(tmpDir.path);
|
||||||
|
lastCommit = repo['821ed6e80627b8769d170a293862f9fc60825226'];
|
||||||
|
featureCommit = repo['5aecfa0fb97eadaac050ccb99f03c3fb65460ad4'];
|
||||||
});
|
});
|
||||||
|
|
||||||
tearDown(() async {
|
tearDown(() {
|
||||||
repo.free();
|
repo.free();
|
||||||
await tmpDir.delete(recursive: true);
|
tmpDir.deleteSync(recursive: true);
|
||||||
});
|
});
|
||||||
|
|
||||||
group('Branch', () {
|
group('Branch', () {
|
||||||
test('returns a list of all branches', () {
|
test('returns a list of all branches', () {
|
||||||
final branches = Branches(repo);
|
const branchesExpected = ['feature', 'master'];
|
||||||
expect(branches.list(), ['feature', 'master']);
|
final branches = repo.branches;
|
||||||
|
|
||||||
|
for (var i = 0; i < branches.length; i++) {
|
||||||
|
expect(branches[i].name, branchesExpected[i]);
|
||||||
|
branches[i].free();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
test('returns a list of local branches', () {
|
test('returns a list of local branches', () {
|
||||||
final branches = repo.branches.local;
|
const branchesExpected = ['feature', 'master'];
|
||||||
expect(branches, ['feature', 'master']);
|
final branches = repo.branchesLocal;
|
||||||
|
|
||||||
|
for (var i = 0; i < branches.length; i++) {
|
||||||
|
expect(branches[i].name, branchesExpected[i]);
|
||||||
|
branches[i].free();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
test('returns a list of remote branches for provided type', () {
|
test('returns a list of remote branches', () {
|
||||||
final branches = repo.branches.remote;
|
expect(repo.branchesRemote, []);
|
||||||
expect(branches, []);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('returns a branch with provided name', () {
|
test('returns a branch with provided name', () {
|
||||||
final branch = repo.branches['master'];
|
final branch = repo.lookupBranch('master');
|
||||||
expect(branch.target.sha, lastCommit);
|
expect(branch.target.sha, lastCommit.sha);
|
||||||
branch.free();
|
branch.free();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('throws when provided name not found', () {
|
test('throws when provided name not found', () {
|
||||||
expect(() => repo.branches['invalid'], throwsA(isA<LibGit2Error>()));
|
expect(() => repo.lookupBranch('invalid'), throwsA(isA<LibGit2Error>()));
|
||||||
});
|
});
|
||||||
|
|
||||||
test('checks if branch is current head', () {
|
test('checks if branch is current head', () {
|
||||||
final masterBranch = repo.branches['master'];
|
final masterBranch = repo.lookupBranch('master');
|
||||||
final featureBranch = repo.branches['feature'];
|
final featureBranch = repo.lookupBranch('feature');
|
||||||
|
|
||||||
expect(masterBranch.isHead, true);
|
expect(masterBranch.isHead, true);
|
||||||
expect(featureBranch.isHead, false);
|
expect(featureBranch.isHead, false);
|
||||||
|
@ -57,30 +68,33 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('returns name', () {
|
test('returns name', () {
|
||||||
final branch = repo.branches['master'];
|
final branch = repo.lookupBranch('master');
|
||||||
expect(branch.name, 'master');
|
expect(branch.name, 'master');
|
||||||
branch.free();
|
branch.free();
|
||||||
});
|
});
|
||||||
|
|
||||||
group('create()', () {
|
group('create()', () {
|
||||||
test('successfully creates', () {
|
test('successfully creates', () {
|
||||||
final commit = repo[lastCommit] as Commit;
|
final commit = repo.lookupCommit(lastCommit);
|
||||||
|
|
||||||
final ref = repo.branches.create(name: 'testing', target: commit);
|
final branch = repo.createBranch(name: 'testing', target: commit);
|
||||||
final branch = repo.branches['testing'];
|
final branches = repo.branches;
|
||||||
expect(repo.branches.list().length, 3);
|
|
||||||
expect(branch.target.sha, lastCommit);
|
|
||||||
|
|
||||||
|
expect(repo.branches.length, 3);
|
||||||
|
expect(branch.target, lastCommit);
|
||||||
|
|
||||||
|
for (final branch in branches) {
|
||||||
|
branch.free();
|
||||||
|
}
|
||||||
branch.free();
|
branch.free();
|
||||||
ref.free();
|
|
||||||
commit.free();
|
commit.free();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('throws when name already exists', () {
|
test('throws when name already exists', () {
|
||||||
final commit = repo[lastCommit] as Commit;
|
final commit = repo.lookupCommit(lastCommit);
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
() => repo.branches.create(name: 'feature', target: commit),
|
() => repo.createBranch(name: 'feature', target: commit),
|
||||||
throwsA(isA<LibGit2Error>()),
|
throwsA(isA<LibGit2Error>()),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -88,30 +102,39 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('successfully creates with force flag when name already exists', () {
|
test('successfully creates with force flag when name already exists', () {
|
||||||
final commit = repo[lastCommit] as Commit;
|
final commit = repo.lookupCommit(lastCommit);
|
||||||
|
|
||||||
final ref =
|
final branch = repo.createBranch(
|
||||||
repo.branches.create(name: 'feature', target: commit, force: true);
|
name: 'feature',
|
||||||
final branch = repo.branches['feature'];
|
target: commit,
|
||||||
expect(repo.branches.local.length, 2);
|
force: true,
|
||||||
expect(branch.target.sha, lastCommit);
|
);
|
||||||
|
final localBranches = repo.branchesLocal;
|
||||||
|
|
||||||
|
expect(localBranches.length, 2);
|
||||||
|
expect(branch.target, lastCommit);
|
||||||
|
|
||||||
|
for (final branch in localBranches) {
|
||||||
|
branch.free();
|
||||||
|
}
|
||||||
branch.free();
|
branch.free();
|
||||||
ref.free();
|
|
||||||
commit.free();
|
commit.free();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
group('delete()', () {
|
group('delete()', () {
|
||||||
test('successfully deletes', () {
|
test('successfully deletes', () {
|
||||||
repo.branches['feature'].delete();
|
repo.deleteBranch('feature');
|
||||||
expect(repo.branches.local.length, 1);
|
|
||||||
expect(() => repo.branches['feature'], throwsA(isA<LibGit2Error>()));
|
expect(
|
||||||
|
() => repo.lookupBranch('feature'),
|
||||||
|
throwsA(isA<LibGit2Error>()),
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('throws when trying to delete current HEAD', () {
|
test('throws when trying to delete current HEAD', () {
|
||||||
expect(
|
expect(
|
||||||
() => repo.branches['master'].delete(),
|
() => repo.deleteBranch('master'),
|
||||||
throwsA(isA<LibGit2Error>()),
|
throwsA(isA<LibGit2Error>()),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@ -119,43 +142,48 @@ void main() {
|
||||||
|
|
||||||
group('rename()', () {
|
group('rename()', () {
|
||||||
test('successfully renames', () {
|
test('successfully renames', () {
|
||||||
final renamed = repo.branches['feature'].rename(newName: 'renamed');
|
repo.renameBranch(oldName: 'feature', newName: 'renamed');
|
||||||
final branch = repo.branches['renamed'];
|
final branch = repo.lookupBranch('renamed');
|
||||||
|
final branches = repo.branches;
|
||||||
|
|
||||||
expect(renamed.target.sha, featureCommit);
|
expect(branches.length, 2);
|
||||||
expect(branch.target.sha, featureCommit);
|
expect(
|
||||||
|
() => repo.lookupBranch('feature'),
|
||||||
|
throwsA(isA<LibGit2Error>()),
|
||||||
|
);
|
||||||
|
expect(branch.target, featureCommit);
|
||||||
|
|
||||||
|
for (final branch in branches) {
|
||||||
|
branch.free();
|
||||||
|
}
|
||||||
branch.free();
|
branch.free();
|
||||||
renamed.free();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('throws when name already exists', () {
|
test('throws when name already exists', () {
|
||||||
final branch = repo.branches['feature'];
|
|
||||||
expect(
|
expect(
|
||||||
() => branch.rename(newName: 'master'),
|
() => repo.renameBranch(oldName: 'feature', newName: 'master'),
|
||||||
throwsA(isA<LibGit2Error>()),
|
throwsA(isA<LibGit2Error>()),
|
||||||
);
|
);
|
||||||
branch.free();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('successfully renames with force flag when name already exists', () {
|
test('successfully renames with force flag when name already exists', () {
|
||||||
final renamed = repo.branches['master'].rename(
|
repo.renameBranch(
|
||||||
|
oldName: 'master',
|
||||||
newName: 'feature',
|
newName: 'feature',
|
||||||
force: true,
|
force: true,
|
||||||
);
|
);
|
||||||
|
final branch = repo.lookupBranch('feature');
|
||||||
|
|
||||||
expect(renamed.target.sha, lastCommit);
|
expect(branch.target, lastCommit);
|
||||||
|
|
||||||
renamed.free();
|
branch.free();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('throws when name is invalid', () {
|
test('throws when name is invalid', () {
|
||||||
final branch = repo.branches['feature'];
|
|
||||||
expect(
|
expect(
|
||||||
() => branch.rename(newName: 'inv@{id'),
|
() => repo.renameBranch(oldName: 'feature', newName: 'inv@{id'),
|
||||||
throwsA(isA<LibGit2Error>()),
|
throwsA(isA<LibGit2Error>()),
|
||||||
);
|
);
|
||||||
branch.free();
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -8,14 +8,14 @@ void main() {
|
||||||
late Repository repo;
|
late Repository repo;
|
||||||
late Directory tmpDir;
|
late Directory tmpDir;
|
||||||
|
|
||||||
setUp(() async {
|
setUp(() {
|
||||||
tmpDir = await setupRepo(Directory('test/assets/testrepo/'));
|
tmpDir = setupRepo(Directory('test/assets/testrepo/'));
|
||||||
repo = Repository.open(tmpDir.path);
|
repo = Repository.open(tmpDir.path);
|
||||||
});
|
});
|
||||||
|
|
||||||
tearDown(() async {
|
tearDown(() {
|
||||||
repo.free();
|
repo.free();
|
||||||
await tmpDir.delete(recursive: true);
|
tmpDir.deleteSync(recursive: true);
|
||||||
});
|
});
|
||||||
|
|
||||||
group('Checkout', () {
|
group('Checkout', () {
|
||||||
|
@ -39,8 +39,9 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('successfully checkouts tree', () {
|
test('successfully checkouts tree', () {
|
||||||
final masterHead =
|
final masterHead = repo.lookupCommit(
|
||||||
repo['821ed6e80627b8769d170a293862f9fc60825226'] as Commit;
|
repo['821ed6e80627b8769d170a293862f9fc60825226'],
|
||||||
|
);
|
||||||
final masterTree = masterHead.tree;
|
final masterTree = masterHead.tree;
|
||||||
expect(
|
expect(
|
||||||
masterTree.entries.any((e) => e.name == 'another_feature_file'),
|
masterTree.entries.any((e) => e.name == 'another_feature_file'),
|
||||||
|
@ -48,8 +49,9 @@ void main() {
|
||||||
);
|
);
|
||||||
|
|
||||||
repo.checkout(refName: 'refs/heads/feature');
|
repo.checkout(refName: 'refs/heads/feature');
|
||||||
final featureHead =
|
final featureHead = repo.lookupCommit(
|
||||||
repo['5aecfa0fb97eadaac050ccb99f03c3fb65460ad4'] as Commit;
|
repo['5aecfa0fb97eadaac050ccb99f03c3fb65460ad4'],
|
||||||
|
);
|
||||||
final featureTree = featureHead.tree;
|
final featureTree = featureHead.tree;
|
||||||
final repoHead = repo.head;
|
final repoHead = repo.head;
|
||||||
expect(repoHead.target.sha, featureHead.id.sha);
|
expect(repoHead.target.sha, featureHead.id.sha);
|
||||||
|
|
|
@ -6,15 +6,14 @@ import 'helpers/util.dart';
|
||||||
void main() {
|
void main() {
|
||||||
late Repository repo;
|
late Repository repo;
|
||||||
late Directory tmpDir;
|
late Directory tmpDir;
|
||||||
|
|
||||||
const mergeCommit = '78b8bf123e3952c970ae5c1ce0a3ea1d1336f6e8';
|
|
||||||
const message = "Commit message.\n\nSome description.\n";
|
|
||||||
const tree = '7796359a96eb722939c24bafdb1afe9f07f2f628';
|
|
||||||
late Signature author;
|
late Signature author;
|
||||||
late Signature commiter;
|
late Signature commiter;
|
||||||
|
late Tree tree;
|
||||||
|
late Oid mergeCommit;
|
||||||
|
const message = "Commit message.\n\nSome description.\n";
|
||||||
|
|
||||||
setUp(() async {
|
setUp(() {
|
||||||
tmpDir = await setupRepo(Directory('test/assets/testrepo/'));
|
tmpDir = setupRepo(Directory('test/assets/testrepo/'));
|
||||||
repo = Repository.open(tmpDir.path);
|
repo = Repository.open(tmpDir.path);
|
||||||
author = Signature.create(
|
author = Signature.create(
|
||||||
name: 'Author Name',
|
name: 'Author Name',
|
||||||
|
@ -26,31 +25,35 @@ void main() {
|
||||||
email: 'commiter@email.com',
|
email: 'commiter@email.com',
|
||||||
time: 124,
|
time: 124,
|
||||||
);
|
);
|
||||||
|
mergeCommit = repo['78b8bf123e3952c970ae5c1ce0a3ea1d1336f6e8'];
|
||||||
|
tree = Tree.lookup(
|
||||||
|
repo: repo,
|
||||||
|
id: repo['7796359a96eb722939c24bafdb1afe9f07f2f628'],
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
tearDown(() async {
|
tearDown(() {
|
||||||
author.free();
|
author.free();
|
||||||
commiter.free();
|
commiter.free();
|
||||||
|
tree.free();
|
||||||
repo.free();
|
repo.free();
|
||||||
await tmpDir.delete(recursive: true);
|
tmpDir.deleteSync(recursive: true);
|
||||||
});
|
});
|
||||||
|
|
||||||
group('Commit', () {
|
group('Commit', () {
|
||||||
test('successfully returns when 40 char sha hex is provided', () {
|
test('successfully returns when 40 char sha hex is provided', () {
|
||||||
final commit = repo[mergeCommit] as Commit;
|
final commit = repo.lookupCommit(mergeCommit);
|
||||||
expect(commit, isA<Commit>());
|
|
||||||
commit.free();
|
|
||||||
});
|
|
||||||
|
|
||||||
test('successfully returns when sha hex is short', () {
|
|
||||||
final commit = repo[mergeCommit.substring(0, 5)] as Commit;
|
|
||||||
expect(commit, isA<Commit>());
|
expect(commit, isA<Commit>());
|
||||||
commit.free();
|
commit.free();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('successfully reverts commit', () {
|
test('successfully reverts commit', () {
|
||||||
final to = repo['78b8bf123e3952c970ae5c1ce0a3ea1d1336f6e8'] as Commit;
|
final to = repo.lookupCommit(
|
||||||
final from = repo['821ed6e80627b8769d170a293862f9fc60825226'] as Commit;
|
repo['78b8bf123e3952c970ae5c1ce0a3ea1d1336f6e8'],
|
||||||
|
);
|
||||||
|
final from = repo.lookupCommit(
|
||||||
|
repo['821ed6e80627b8769d170a293862f9fc60825226'],
|
||||||
|
);
|
||||||
final index = repo.index;
|
final index = repo.index;
|
||||||
expect(index.find('dir/dir_file.txt'), true);
|
expect(index.find('dir/dir_file.txt'), true);
|
||||||
|
|
||||||
|
@ -64,16 +67,16 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('successfully creates commit', () {
|
test('successfully creates commit', () {
|
||||||
final oid = Commit.create(
|
final parent = repo.lookupCommit(mergeCommit);
|
||||||
repo: repo,
|
final oid = repo.createCommit(
|
||||||
message: message,
|
message: message,
|
||||||
author: author,
|
author: author,
|
||||||
commiter: commiter,
|
commiter: commiter,
|
||||||
treeSHA: tree,
|
tree: tree,
|
||||||
parents: [mergeCommit],
|
parents: [parent],
|
||||||
);
|
);
|
||||||
|
|
||||||
final commit = repo[oid.sha] as Commit;
|
final commit = repo.lookupCommit(oid);
|
||||||
|
|
||||||
expect(commit.id.sha, oid.sha);
|
expect(commit.id.sha, oid.sha);
|
||||||
expect(commit.message, message);
|
expect(commit.message, message);
|
||||||
|
@ -81,11 +84,12 @@ void main() {
|
||||||
expect(commit.author, author);
|
expect(commit.author, author);
|
||||||
expect(commit.committer, commiter);
|
expect(commit.committer, commiter);
|
||||||
expect(commit.time, 124);
|
expect(commit.time, 124);
|
||||||
expect(commit.tree.id.sha, tree);
|
expect(commit.tree.id, tree.id);
|
||||||
expect(commit.parents.length, 1);
|
expect(commit.parents.length, 1);
|
||||||
expect(commit.parents[0].sha, mergeCommit);
|
expect(commit.parents[0], mergeCommit);
|
||||||
|
|
||||||
commit.free();
|
commit.free();
|
||||||
|
parent.free();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('successfully creates commit without parents', () {
|
test('successfully creates commit without parents', () {
|
||||||
|
@ -93,11 +97,11 @@ void main() {
|
||||||
message: message,
|
message: message,
|
||||||
author: author,
|
author: author,
|
||||||
commiter: commiter,
|
commiter: commiter,
|
||||||
treeSHA: tree,
|
tree: tree,
|
||||||
parents: [],
|
parents: [],
|
||||||
);
|
);
|
||||||
|
|
||||||
final commit = repo[oid.sha] as Commit;
|
final commit = repo.lookupCommit(oid);
|
||||||
|
|
||||||
expect(commit.id.sha, oid.sha);
|
expect(commit.id.sha, oid.sha);
|
||||||
expect(commit.message, message);
|
expect(commit.message, message);
|
||||||
|
@ -105,23 +109,28 @@ void main() {
|
||||||
expect(commit.author, author);
|
expect(commit.author, author);
|
||||||
expect(commit.committer, commiter);
|
expect(commit.committer, commiter);
|
||||||
expect(commit.time, 124);
|
expect(commit.time, 124);
|
||||||
expect(commit.tree.id.sha, tree);
|
expect(commit.tree.id, tree.id);
|
||||||
expect(commit.parents.length, 0);
|
expect(commit.parents.length, 0);
|
||||||
|
|
||||||
commit.free();
|
commit.free();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('successfully creates commit with 2 parents', () {
|
test('successfully creates commit with 2 parents', () {
|
||||||
|
final parent1 = repo.lookupCommit(mergeCommit);
|
||||||
|
final parent2 = repo.lookupCommit(
|
||||||
|
repo['fc38877b2552ab554752d9a77e1f48f738cca79b'],
|
||||||
|
);
|
||||||
|
|
||||||
final oid = Commit.create(
|
final oid = Commit.create(
|
||||||
repo: repo,
|
repo: repo,
|
||||||
message: message,
|
message: message,
|
||||||
author: author,
|
author: author,
|
||||||
commiter: commiter,
|
commiter: commiter,
|
||||||
treeSHA: tree,
|
tree: tree,
|
||||||
parents: [mergeCommit, 'fc38877b2552ab554752d9a77e1f48f738cca79b'],
|
parents: [parent1, parent2],
|
||||||
);
|
);
|
||||||
|
|
||||||
final commit = repo[oid.sha] as Commit;
|
final commit = repo.lookupCommit(oid);
|
||||||
|
|
||||||
expect(commit.id.sha, oid.sha);
|
expect(commit.id.sha, oid.sha);
|
||||||
expect(commit.message, message);
|
expect(commit.message, message);
|
||||||
|
@ -129,36 +138,13 @@ void main() {
|
||||||
expect(commit.author, author);
|
expect(commit.author, author);
|
||||||
expect(commit.committer, commiter);
|
expect(commit.committer, commiter);
|
||||||
expect(commit.time, 124);
|
expect(commit.time, 124);
|
||||||
expect(commit.tree.id.sha, tree);
|
expect(commit.tree.id, tree.id);
|
||||||
expect(commit.parents.length, 2);
|
expect(commit.parents.length, 2);
|
||||||
expect(commit.parents[0].sha, mergeCommit);
|
expect(commit.parents[0], mergeCommit);
|
||||||
expect(commit.parents[1].sha, 'fc38877b2552ab554752d9a77e1f48f738cca79b');
|
expect(commit.parents[1], parent2.id);
|
||||||
|
|
||||||
commit.free();
|
|
||||||
});
|
|
||||||
|
|
||||||
test('successfully creates commit with short sha of tree', () {
|
|
||||||
final oid = Commit.create(
|
|
||||||
repo: repo,
|
|
||||||
message: message,
|
|
||||||
author: author,
|
|
||||||
commiter: commiter,
|
|
||||||
treeSHA: tree.substring(0, 5),
|
|
||||||
parents: [mergeCommit],
|
|
||||||
);
|
|
||||||
|
|
||||||
final commit = repo[oid.sha] as Commit;
|
|
||||||
|
|
||||||
expect(commit.id.sha, oid.sha);
|
|
||||||
expect(commit.message, message);
|
|
||||||
expect(commit.messageEncoding, 'utf-8');
|
|
||||||
expect(commit.author, author);
|
|
||||||
expect(commit.committer, commiter);
|
|
||||||
expect(commit.time, 124);
|
|
||||||
expect(commit.tree.id.sha, tree);
|
|
||||||
expect(commit.parents.length, 1);
|
|
||||||
expect(commit.parents[0].sha, mergeCommit);
|
|
||||||
|
|
||||||
|
parent1.free();
|
||||||
|
parent2.free();
|
||||||
commit.free();
|
commit.free();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -7,14 +7,14 @@ void main() {
|
||||||
late Repository repo;
|
late Repository repo;
|
||||||
late Directory tmpDir;
|
late Directory tmpDir;
|
||||||
|
|
||||||
setUp(() async {
|
setUp(() {
|
||||||
tmpDir = await setupRepo(Directory('test/assets/testrepo/'));
|
tmpDir = setupRepo(Directory('test/assets/testrepo/'));
|
||||||
repo = Repository.open(tmpDir.path);
|
repo = Repository.open(tmpDir.path);
|
||||||
});
|
});
|
||||||
|
|
||||||
tearDown(() async {
|
tearDown(() {
|
||||||
repo.free();
|
repo.free();
|
||||||
await tmpDir.delete(recursive: true);
|
tmpDir.deleteSync(recursive: true);
|
||||||
});
|
});
|
||||||
|
|
||||||
group('Describe', () {
|
group('Describe', () {
|
||||||
|
@ -23,25 +23,22 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('successfully describes commit', () {
|
test('successfully describes commit', () {
|
||||||
final tag = Tag.lookup(repo: repo, sha: 'f0fdbf5');
|
repo.deleteTag('v0.2');
|
||||||
tag.delete();
|
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
repo.describe(describeStrategy: GitDescribeStrategy.tags),
|
repo.describe(describeStrategy: GitDescribeStrategy.tags),
|
||||||
'v0.1-1-g821ed6e',
|
'v0.1-1-g821ed6e',
|
||||||
);
|
);
|
||||||
|
|
||||||
tag.free();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('throws when trying to describe and no reference found', () {
|
test('throws when trying to describe and no reference found', () {
|
||||||
final commit = repo['f17d0d48'] as Commit;
|
final commit = repo.lookupCommit(repo['f17d0d48']);
|
||||||
expect(() => repo.describe(commit: commit), throwsA(isA<LibGit2Error>()));
|
expect(() => repo.describe(commit: commit), throwsA(isA<LibGit2Error>()));
|
||||||
commit.free();
|
commit.free();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('returns oid when fallback argument is provided', () {
|
test('returns oid when fallback argument is provided', () {
|
||||||
final commit = repo['f17d0d48'] as Commit;
|
final commit = repo.lookupCommit(repo['f17d0d48']);
|
||||||
expect(
|
expect(
|
||||||
repo.describe(commit: commit, showCommitOidAsFallback: true),
|
repo.describe(commit: commit, showCommitOidAsFallback: true),
|
||||||
'f17d0d4',
|
'f17d0d4',
|
||||||
|
@ -50,7 +47,7 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('successfully describes with provided strategy', () {
|
test('successfully describes with provided strategy', () {
|
||||||
final commit = repo['5aecfa0'] as Commit;
|
final commit = repo.lookupCommit(repo['5aecfa0']);
|
||||||
expect(
|
expect(
|
||||||
repo.describe(
|
repo.describe(
|
||||||
commit: commit,
|
commit: commit,
|
||||||
|
@ -63,10 +60,10 @@ void main() {
|
||||||
|
|
||||||
test('successfully describes with provided pattern', () {
|
test('successfully describes with provided pattern', () {
|
||||||
final signature = repo.defaultSignature;
|
final signature = repo.defaultSignature;
|
||||||
final commit = repo['fc38877'] as Commit;
|
final commit = repo.lookupCommit(repo['fc38877']);
|
||||||
repo.createTag(
|
repo.createTag(
|
||||||
tagName: 'test/tag1',
|
tagName: 'test/tag1',
|
||||||
target: 'f17d0d48',
|
target: repo['f17d0d48'],
|
||||||
targetType: GitObject.commit,
|
targetType: GitObject.commit,
|
||||||
tagger: signature,
|
tagger: signature,
|
||||||
message: '',
|
message: '',
|
||||||
|
@ -82,10 +79,9 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('successfully describes and follows first parent only', () {
|
test('successfully describes and follows first parent only', () {
|
||||||
final tag = Tag.lookup(repo: repo, sha: 'f0fdbf5');
|
final commit = repo.lookupCommit(repo['821ed6e']);
|
||||||
tag.delete();
|
repo.deleteTag('v0.2');
|
||||||
|
|
||||||
final commit = repo['821ed6e'] as Commit;
|
|
||||||
expect(
|
expect(
|
||||||
repo.describe(
|
repo.describe(
|
||||||
commit: commit,
|
commit: commit,
|
||||||
|
@ -95,15 +91,13 @@ void main() {
|
||||||
'v0.1-1-g821ed6e',
|
'v0.1-1-g821ed6e',
|
||||||
);
|
);
|
||||||
|
|
||||||
tag.free();
|
|
||||||
commit.free();
|
commit.free();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('successfully describes with abbreviated size provided', () {
|
test('successfully describes with provided abbreviated size', () {
|
||||||
final tag = Tag.lookup(repo: repo, sha: 'f0fdbf5');
|
final commit = repo.lookupCommit(repo['821ed6e']);
|
||||||
tag.delete();
|
repo.deleteTag('v0.2');
|
||||||
|
|
||||||
final commit = repo['821ed6e'] as Commit;
|
|
||||||
expect(
|
expect(
|
||||||
repo.describe(
|
repo.describe(
|
||||||
commit: commit,
|
commit: commit,
|
||||||
|
@ -122,7 +116,6 @@ void main() {
|
||||||
'v0.1',
|
'v0.1',
|
||||||
);
|
);
|
||||||
|
|
||||||
tag.free();
|
|
||||||
commit.free();
|
commit.free();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -74,14 +74,14 @@ index e69de29..c217c63 100644
|
||||||
8 files changed, 4 insertions(+), 2 deletions(-)
|
8 files changed, 4 insertions(+), 2 deletions(-)
|
||||||
""";
|
""";
|
||||||
|
|
||||||
setUp(() async {
|
setUp(() {
|
||||||
tmpDir = await setupRepo(Directory('test/assets/dirtyrepo/'));
|
tmpDir = setupRepo(Directory('test/assets/dirtyrepo/'));
|
||||||
repo = Repository.open(tmpDir.path);
|
repo = Repository.open(tmpDir.path);
|
||||||
});
|
});
|
||||||
|
|
||||||
tearDown(() async {
|
tearDown(() {
|
||||||
repo.free();
|
repo.free();
|
||||||
await tmpDir.delete(recursive: true);
|
tmpDir.deleteSync(recursive: true);
|
||||||
});
|
});
|
||||||
|
|
||||||
group('Diff', () {
|
group('Diff', () {
|
||||||
|
@ -100,7 +100,9 @@ index e69de29..c217c63 100644
|
||||||
|
|
||||||
test('successfully returns diff between index and tree', () {
|
test('successfully returns diff between index and tree', () {
|
||||||
final index = repo.index;
|
final index = repo.index;
|
||||||
final tree = (repo[repo.head.target.sha] as Commit).tree;
|
final head = repo.head;
|
||||||
|
final commit = repo.lookupCommit(head.target);
|
||||||
|
final tree = commit.tree;
|
||||||
final diff = index.diffToTree(tree: tree);
|
final diff = index.diffToTree(tree: tree);
|
||||||
|
|
||||||
expect(diff.length, 8);
|
expect(diff.length, 8);
|
||||||
|
@ -108,13 +110,17 @@ index e69de29..c217c63 100644
|
||||||
expect(diff.deltas[i].newFile.path, indexToTree[i]);
|
expect(diff.deltas[i].newFile.path, indexToTree[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
commit.free();
|
||||||
|
head.free();
|
||||||
tree.free();
|
tree.free();
|
||||||
diff.free();
|
diff.free();
|
||||||
index.free();
|
index.free();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('successfully returns diff between tree and workdir', () {
|
test('successfully returns diff between tree and workdir', () {
|
||||||
final tree = (repo[repo.head.target.sha] as Commit).tree;
|
final head = repo.head;
|
||||||
|
final commit = repo.lookupCommit(head.target);
|
||||||
|
final tree = commit.tree;
|
||||||
final diff = repo.diff(a: tree);
|
final diff = repo.diff(a: tree);
|
||||||
|
|
||||||
expect(diff.length, 9);
|
expect(diff.length, 9);
|
||||||
|
@ -122,13 +128,17 @@ index e69de29..c217c63 100644
|
||||||
expect(diff.deltas[i].newFile.path, treeToWorkdir[i]);
|
expect(diff.deltas[i].newFile.path, treeToWorkdir[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
commit.free();
|
||||||
|
head.free();
|
||||||
tree.free();
|
tree.free();
|
||||||
diff.free();
|
diff.free();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('successfully returns diff between tree and index', () {
|
test('successfully returns diff between tree and index', () {
|
||||||
final index = repo.index;
|
final index = repo.index;
|
||||||
final tree = (repo[repo.head.target.sha] as Commit).tree;
|
final head = repo.head;
|
||||||
|
final commit = repo.lookupCommit(head.target);
|
||||||
|
final tree = commit.tree;
|
||||||
final diff = repo.diff(a: tree, cached: true);
|
final diff = repo.diff(a: tree, cached: true);
|
||||||
|
|
||||||
expect(diff.length, 8);
|
expect(diff.length, 8);
|
||||||
|
@ -136,14 +146,20 @@ index e69de29..c217c63 100644
|
||||||
expect(diff.deltas[i].newFile.path, indexToTree[i]);
|
expect(diff.deltas[i].newFile.path, indexToTree[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
commit.free();
|
||||||
|
head.free();
|
||||||
tree.free();
|
tree.free();
|
||||||
diff.free();
|
diff.free();
|
||||||
index.free();
|
index.free();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('successfully returns diff between tree and tree', () {
|
test('successfully returns diff between tree and tree', () {
|
||||||
final tree1 = (repo[repo.head.target.sha] as Commit).tree;
|
final head = repo.head;
|
||||||
final tree2 = repo['b85d53c9236e89aff2b62558adaa885fd1d6ff1c'] as Tree;
|
final commit = repo.lookupCommit(head.target);
|
||||||
|
final tree1 = commit.tree;
|
||||||
|
final tree2 = repo.lookupTree(
|
||||||
|
repo['b85d53c9236e89aff2b62558adaa885fd1d6ff1c'],
|
||||||
|
);
|
||||||
final diff = repo.diff(a: tree1, b: tree2);
|
final diff = repo.diff(a: tree1, b: tree2);
|
||||||
|
|
||||||
expect(diff.length, 10);
|
expect(diff.length, 10);
|
||||||
|
@ -151,14 +167,20 @@ index e69de29..c217c63 100644
|
||||||
expect(diff.deltas[i].newFile.path, treeToTree[i]);
|
expect(diff.deltas[i].newFile.path, treeToTree[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
commit.free();
|
||||||
|
head.free();
|
||||||
tree1.free();
|
tree1.free();
|
||||||
tree2.free();
|
tree2.free();
|
||||||
diff.free();
|
diff.free();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('successfully merges diffs', () {
|
test('successfully merges diffs', () {
|
||||||
final tree1 = (repo[repo.head.target.sha] as Commit).tree;
|
final head = repo.head;
|
||||||
final tree2 = repo['b85d53c9236e89aff2b62558adaa885fd1d6ff1c'] as Tree;
|
final commit = repo.lookupCommit(head.target);
|
||||||
|
final tree1 = commit.tree;
|
||||||
|
final tree2 = repo.lookupTree(
|
||||||
|
repo['b85d53c9236e89aff2b62558adaa885fd1d6ff1c'],
|
||||||
|
);
|
||||||
final diff1 = tree1.diffToTree(tree: tree2);
|
final diff1 = tree1.diffToTree(tree: tree2);
|
||||||
final diff2 = tree1.diffToWorkdir();
|
final diff2 = tree1.diffToWorkdir();
|
||||||
|
|
||||||
|
@ -168,6 +190,8 @@ index e69de29..c217c63 100644
|
||||||
diff1.merge(diff2);
|
diff1.merge(diff2);
|
||||||
expect(diff1.length, 11);
|
expect(diff1.length, 11);
|
||||||
|
|
||||||
|
commit.free();
|
||||||
|
head.free();
|
||||||
tree1.free();
|
tree1.free();
|
||||||
tree2.free();
|
tree2.free();
|
||||||
diff1.free();
|
diff1.free();
|
||||||
|
@ -219,8 +243,10 @@ index e69de29..c217c63 100644
|
||||||
|
|
||||||
test('successfully finds similar entries', () {
|
test('successfully finds similar entries', () {
|
||||||
final index = repo.index;
|
final index = repo.index;
|
||||||
final oldTree = (repo[repo.head.target.sha] as Commit).tree;
|
final head = repo.head;
|
||||||
final newTree = repo[index.writeTree().sha] as Tree;
|
final commit = repo.lookupCommit(head.target);
|
||||||
|
final oldTree = commit.tree;
|
||||||
|
final newTree = repo.lookupTree(index.writeTree());
|
||||||
|
|
||||||
final diff = oldTree.diffToTree(tree: newTree);
|
final diff = oldTree.diffToTree(tree: newTree);
|
||||||
expect(
|
expect(
|
||||||
|
@ -234,6 +260,8 @@ index e69de29..c217c63 100644
|
||||||
GitDelta.renamed,
|
GitDelta.renamed,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
commit.free();
|
||||||
|
head.free();
|
||||||
diff.free();
|
diff.free();
|
||||||
index.free();
|
index.free();
|
||||||
oldTree.free();
|
oldTree.free();
|
||||||
|
|
|
@ -3,29 +3,31 @@ import 'package:path/path.dart' as p;
|
||||||
|
|
||||||
final tmpDir = Directory.systemTemp.createTempSync('testrepo');
|
final tmpDir = Directory.systemTemp.createTempSync('testrepo');
|
||||||
|
|
||||||
Future<Directory> setupRepo(Directory repoDir) async {
|
Directory setupRepo(Directory repoDir) {
|
||||||
if (await tmpDir.exists()) {
|
if (tmpDir.existsSync()) {
|
||||||
await tmpDir.delete(recursive: true);
|
tmpDir.deleteSync(recursive: true);
|
||||||
}
|
}
|
||||||
await copyRepo(from: repoDir, to: await tmpDir.create());
|
tmpDir.createSync();
|
||||||
|
copyRepo(from: repoDir, to: tmpDir);
|
||||||
return tmpDir;
|
return tmpDir;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> copyRepo({required Directory from, required Directory to}) async {
|
void copyRepo({required Directory from, required Directory to}) {
|
||||||
await for (final entity in from.list()) {
|
for (final entity in from.listSync()) {
|
||||||
if (entity is Directory) {
|
if (entity is Directory) {
|
||||||
Directory newDir;
|
Directory newDir;
|
||||||
if (p.basename(entity.path) == '.gitdir') {
|
if (p.basename(entity.path) == '.gitdir') {
|
||||||
newDir = Directory(p.join(to.absolute.path, '.git'));
|
newDir = Directory(p.join(to.absolute.path, '.git'))..createSync();
|
||||||
} else {
|
} else {
|
||||||
newDir = Directory(p.join(to.absolute.path, p.basename(entity.path)));
|
newDir = Directory(p.join(to.absolute.path, p.basename(entity.path)))
|
||||||
|
..createSync();
|
||||||
}
|
}
|
||||||
await copyRepo(from: entity.absolute, to: await newDir.create());
|
copyRepo(from: entity.absolute, to: newDir);
|
||||||
} else if (entity is File) {
|
} else if (entity is File) {
|
||||||
if (p.basename(entity.path) == 'gitignore') {
|
if (p.basename(entity.path) == 'gitignore') {
|
||||||
await entity.copy(p.join(to.path, '.gitignore'));
|
entity.copySync(p.join(to.path, '.gitignore'));
|
||||||
} else {
|
} else {
|
||||||
await entity.copy(p.join(to.path, p.basename(entity.path)));
|
entity.copySync(p.join(to.path, p.basename(entity.path)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,16 +8,16 @@ void main() {
|
||||||
late Index index;
|
late Index index;
|
||||||
late Directory tmpDir;
|
late Directory tmpDir;
|
||||||
|
|
||||||
setUp(() async {
|
setUp(() {
|
||||||
tmpDir = await setupRepo(Directory('test/assets/testrepo/'));
|
tmpDir = setupRepo(Directory('test/assets/testrepo/'));
|
||||||
repo = Repository.open(tmpDir.path);
|
repo = Repository.open(tmpDir.path);
|
||||||
index = repo.index;
|
index = repo.index;
|
||||||
});
|
});
|
||||||
|
|
||||||
tearDown(() async {
|
tearDown(() {
|
||||||
index.free();
|
index.free();
|
||||||
repo.free();
|
repo.free();
|
||||||
await tmpDir.delete(recursive: true);
|
tmpDir.deleteSync(recursive: true);
|
||||||
});
|
});
|
||||||
|
|
||||||
group('Index', () {
|
group('Index', () {
|
||||||
|
@ -156,11 +156,12 @@ void main() {
|
||||||
expect(index.find('feature_file'), false);
|
expect(index.find('feature_file'), false);
|
||||||
});
|
});
|
||||||
|
|
||||||
group('read tree', () {
|
test('successfully reads tree with provided SHA hex', () {
|
||||||
const treeSha = 'df2b8fc99e1c1d4dbc0a854d9f72157f1d6ea078';
|
final tree = repo.lookupTree(
|
||||||
test('successfully reads with provided SHA hex', () {
|
repo['df2b8fc99e1c1d4dbc0a854d9f72157f1d6ea078'],
|
||||||
|
);
|
||||||
expect(index.length, 4);
|
expect(index.length, 4);
|
||||||
index.readTree(treeSha);
|
index.readTree(tree);
|
||||||
|
|
||||||
expect(index.length, 1);
|
expect(index.length, 1);
|
||||||
|
|
||||||
|
@ -169,14 +170,6 @@ void main() {
|
||||||
expect(index.length, 4);
|
expect(index.length, 4);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('successfully reads with provided short SHA hex', () {
|
|
||||||
expect(index.length, 4);
|
|
||||||
index.readTree(treeSha.substring(0, 5));
|
|
||||||
|
|
||||||
expect(index.length, 1);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
test('successfully writes tree', () {
|
test('successfully writes tree', () {
|
||||||
final oid = index.writeTree();
|
final oid = index.writeTree();
|
||||||
expect(oid.sha, 'a8ae3dd59e6e1802c6f78e05e301bfd57c9f334f');
|
expect(oid.sha, 'a8ae3dd59e6e1802c6f78e05e301bfd57c9f334f');
|
||||||
|
|
|
@ -126,14 +126,14 @@ Santa Claus <santa.claus@northpole.xx> <me@company.xx>
|
||||||
late Repository repo;
|
late Repository repo;
|
||||||
late Directory tmpDir;
|
late Directory tmpDir;
|
||||||
|
|
||||||
setUp(() async {
|
setUp(() {
|
||||||
tmpDir = await setupRepo(Directory('test/assets/mailmaprepo/'));
|
tmpDir = setupRepo(Directory('test/assets/mailmaprepo/'));
|
||||||
repo = Repository.open(tmpDir.path);
|
repo = Repository.open(tmpDir.path);
|
||||||
});
|
});
|
||||||
|
|
||||||
tearDown(() async {
|
tearDown(() {
|
||||||
repo.free();
|
repo.free();
|
||||||
await tmpDir.delete(recursive: true);
|
tmpDir.deleteSync(recursive: true);
|
||||||
});
|
});
|
||||||
|
|
||||||
group('Mailmap', () {
|
group('Mailmap', () {
|
||||||
|
|
|
@ -9,21 +9,22 @@ void main() {
|
||||||
late Repository repo;
|
late Repository repo;
|
||||||
late Directory tmpDir;
|
late Directory tmpDir;
|
||||||
|
|
||||||
setUp(() async {
|
setUp(() {
|
||||||
tmpDir = await setupRepo(Directory('test/assets/mergerepo/'));
|
tmpDir = setupRepo(Directory('test/assets/mergerepo/'));
|
||||||
repo = Repository.open(tmpDir.path);
|
repo = Repository.open(tmpDir.path);
|
||||||
});
|
});
|
||||||
|
|
||||||
tearDown(() async {
|
tearDown(() {
|
||||||
repo.free();
|
repo.free();
|
||||||
await tmpDir.delete(recursive: true);
|
tmpDir.deleteSync(recursive: true);
|
||||||
});
|
});
|
||||||
|
|
||||||
group('Merge', () {
|
group('Merge', () {
|
||||||
group('analysis', () {
|
group('analysis', () {
|
||||||
test('is up to date when no reference is provided', () {
|
test('is up to date when no reference is provided', () {
|
||||||
final commit =
|
final commit = repo.lookupCommit(
|
||||||
repo['c68ff54aabf660fcdd9a2838d401583fe31249e3'] as Commit;
|
repo['c68ff54aabf660fcdd9a2838d401583fe31249e3'],
|
||||||
|
);
|
||||||
|
|
||||||
final result = repo.mergeAnalysis(theirHead: commit.id);
|
final result = repo.mergeAnalysis(theirHead: commit.id);
|
||||||
expect(result[0], {GitMergeAnalysis.upToDate});
|
expect(result[0], {GitMergeAnalysis.upToDate});
|
||||||
|
@ -34,8 +35,9 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('is up to date for provided ref', () {
|
test('is up to date for provided ref', () {
|
||||||
final commit =
|
final commit = repo.lookupCommit(
|
||||||
repo['c68ff54aabf660fcdd9a2838d401583fe31249e3'] as Commit;
|
repo['c68ff54aabf660fcdd9a2838d401583fe31249e3'],
|
||||||
|
);
|
||||||
|
|
||||||
final result = repo.mergeAnalysis(
|
final result = repo.mergeAnalysis(
|
||||||
theirHead: commit.id,
|
theirHead: commit.id,
|
||||||
|
@ -48,18 +50,20 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('is fast forward', () {
|
test('is fast forward', () {
|
||||||
final theirHead =
|
final theirHead = repo.lookupCommit(
|
||||||
repo['6cbc22e509d72758ab4c8d9f287ea846b90c448b'] as Commit;
|
repo['6cbc22e509d72758ab4c8d9f287ea846b90c448b'],
|
||||||
final ffCommit =
|
);
|
||||||
repo['f17d0d48eae3aa08cecf29128a35e310c97b3521'] as Commit;
|
final ffCommit = repo.lookupCommit(
|
||||||
final ffBranch = repo.branches.create(
|
repo['f17d0d48eae3aa08cecf29128a35e310c97b3521'],
|
||||||
|
);
|
||||||
|
final ffBranch = repo.createBranch(
|
||||||
name: 'ff-branch',
|
name: 'ff-branch',
|
||||||
target: ffCommit,
|
target: ffCommit,
|
||||||
);
|
);
|
||||||
|
|
||||||
final result = repo.mergeAnalysis(
|
final result = repo.mergeAnalysis(
|
||||||
theirHead: theirHead.id,
|
theirHead: theirHead.id,
|
||||||
ourRef: ffBranch.name,
|
ourRef: 'refs/heads/${ffBranch.name}',
|
||||||
);
|
);
|
||||||
expect(
|
expect(
|
||||||
result[0],
|
result[0],
|
||||||
|
@ -73,8 +77,9 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('is not fast forward and there is no conflicts', () {
|
test('is not fast forward and there is no conflicts', () {
|
||||||
final commit =
|
final commit = repo.lookupCommit(
|
||||||
repo['5aecfa0fb97eadaac050ccb99f03c3fb65460ad4'] as Commit;
|
repo['5aecfa0fb97eadaac050ccb99f03c3fb65460ad4'],
|
||||||
|
);
|
||||||
|
|
||||||
final result = repo.mergeAnalysis(theirHead: commit.id);
|
final result = repo.mergeAnalysis(theirHead: commit.id);
|
||||||
expect(result[0], {GitMergeAnalysis.normal});
|
expect(result[0], {GitMergeAnalysis.normal});
|
||||||
|
@ -85,7 +90,7 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('writes conflicts to index', () {
|
test('writes conflicts to index', () {
|
||||||
final conflictBranch = repo.branches['conflict-branch'];
|
final conflictBranch = repo.lookupBranch('conflict-branch');
|
||||||
final index = repo.index;
|
final index = repo.index;
|
||||||
|
|
||||||
final result = repo.mergeAnalysis(theirHead: conflictBranch.target);
|
final result = repo.mergeAnalysis(theirHead: conflictBranch.target);
|
||||||
|
@ -123,7 +128,7 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('successfully removes conflicts', () {
|
test('successfully removes conflicts', () {
|
||||||
final conflictBranch = repo.branches['conflict-branch'];
|
final conflictBranch = repo.lookupBranch('conflict-branch');
|
||||||
final index = repo.index;
|
final index = repo.index;
|
||||||
|
|
||||||
repo.merge(conflictBranch.target);
|
repo.merge(conflictBranch.target);
|
||||||
|
@ -149,7 +154,7 @@ master conflict edit
|
||||||
conflict branch edit
|
conflict branch edit
|
||||||
>>>>>>> conflict_file
|
>>>>>>> conflict_file
|
||||||
""";
|
""";
|
||||||
final conflictBranch = repo.branches['conflict-branch'];
|
final conflictBranch = repo.lookupBranch('conflict-branch');
|
||||||
final index = repo.index;
|
final index = repo.index;
|
||||||
repo.merge(conflictBranch.target);
|
repo.merge(conflictBranch.target);
|
||||||
|
|
||||||
|
@ -171,10 +176,12 @@ conflict branch edit
|
||||||
|
|
||||||
group('merge commits', () {
|
group('merge commits', () {
|
||||||
test('successfully merges with default values', () {
|
test('successfully merges with default values', () {
|
||||||
final theirCommit =
|
final theirCommit = repo.lookupCommit(
|
||||||
repo['5aecfa0fb97eadaac050ccb99f03c3fb65460ad4'] as Commit;
|
repo['5aecfa0fb97eadaac050ccb99f03c3fb65460ad4'],
|
||||||
final ourCommit =
|
);
|
||||||
repo['14905459d775f3f56a39ebc2ff081163f7da3529'] as Commit;
|
final ourCommit = repo.lookupCommit(
|
||||||
|
repo['14905459d775f3f56a39ebc2ff081163f7da3529'],
|
||||||
|
);
|
||||||
|
|
||||||
final mergeIndex = repo.mergeCommits(
|
final mergeIndex = repo.mergeCommits(
|
||||||
ourCommit: ourCommit,
|
ourCommit: ourCommit,
|
||||||
|
@ -197,10 +204,12 @@ conflict branch edit
|
||||||
});
|
});
|
||||||
|
|
||||||
test('successfully merges with provided favor', () {
|
test('successfully merges with provided favor', () {
|
||||||
final theirCommit =
|
final theirCommit = repo.lookupCommit(
|
||||||
repo['5aecfa0fb97eadaac050ccb99f03c3fb65460ad4'] as Commit;
|
repo['5aecfa0fb97eadaac050ccb99f03c3fb65460ad4'],
|
||||||
final ourCommit =
|
);
|
||||||
repo['14905459d775f3f56a39ebc2ff081163f7da3529'] as Commit;
|
final ourCommit = repo.lookupCommit(
|
||||||
|
repo['14905459d775f3f56a39ebc2ff081163f7da3529'],
|
||||||
|
);
|
||||||
|
|
||||||
final mergeIndex = repo.mergeCommits(
|
final mergeIndex = repo.mergeCommits(
|
||||||
ourCommit: ourCommit,
|
ourCommit: ourCommit,
|
||||||
|
@ -215,10 +224,12 @@ conflict branch edit
|
||||||
});
|
});
|
||||||
|
|
||||||
test('successfully merges with provided merge and file flags', () {
|
test('successfully merges with provided merge and file flags', () {
|
||||||
final theirCommit =
|
final theirCommit = repo.lookupCommit(
|
||||||
repo['5aecfa0fb97eadaac050ccb99f03c3fb65460ad4'] as Commit;
|
repo['5aecfa0fb97eadaac050ccb99f03c3fb65460ad4'],
|
||||||
final ourCommit =
|
);
|
||||||
repo['14905459d775f3f56a39ebc2ff081163f7da3529'] as Commit;
|
final ourCommit = repo.lookupCommit(
|
||||||
|
repo['14905459d775f3f56a39ebc2ff081163f7da3529'],
|
||||||
|
);
|
||||||
|
|
||||||
final mergeIndex = repo.mergeCommits(
|
final mergeIndex = repo.mergeCommits(
|
||||||
ourCommit: ourCommit,
|
ourCommit: ourCommit,
|
||||||
|
@ -243,13 +254,15 @@ conflict branch edit
|
||||||
|
|
||||||
group('merge trees', () {
|
group('merge trees', () {
|
||||||
test('successfully merges with default values', () {
|
test('successfully merges with default values', () {
|
||||||
final theirCommit =
|
final theirCommit = repo.lookupCommit(
|
||||||
repo['5aecfa0fb97eadaac050ccb99f03c3fb65460ad4'] as Commit;
|
repo['5aecfa0fb97eadaac050ccb99f03c3fb65460ad4'],
|
||||||
final ourCommit =
|
);
|
||||||
repo['14905459d775f3f56a39ebc2ff081163f7da3529'] as Commit;
|
final ourCommit = repo.lookupCommit(
|
||||||
final baseCommit =
|
repo['14905459d775f3f56a39ebc2ff081163f7da3529'],
|
||||||
repo[repo.mergeBase(a: ourCommit.id.sha, b: theirCommit.id.sha).sha]
|
);
|
||||||
as Commit;
|
final baseCommit = repo.lookupCommit(
|
||||||
|
repo.mergeBase(a: ourCommit.id.sha, b: theirCommit.id.sha),
|
||||||
|
);
|
||||||
final theirTree = theirCommit.tree;
|
final theirTree = theirCommit.tree;
|
||||||
final ourTree = ourCommit.tree;
|
final ourTree = ourCommit.tree;
|
||||||
final ancestorTree = baseCommit.tree;
|
final ancestorTree = baseCommit.tree;
|
||||||
|
@ -281,13 +294,15 @@ conflict branch edit
|
||||||
});
|
});
|
||||||
|
|
||||||
test('successfully merges with provided favor', () {
|
test('successfully merges with provided favor', () {
|
||||||
final theirCommit =
|
final theirCommit = repo.lookupCommit(
|
||||||
repo['5aecfa0fb97eadaac050ccb99f03c3fb65460ad4'] as Commit;
|
repo['5aecfa0fb97eadaac050ccb99f03c3fb65460ad4'],
|
||||||
final ourCommit =
|
);
|
||||||
repo['14905459d775f3f56a39ebc2ff081163f7da3529'] as Commit;
|
final ourCommit = repo.lookupCommit(
|
||||||
final baseCommit =
|
repo['14905459d775f3f56a39ebc2ff081163f7da3529'],
|
||||||
repo[repo.mergeBase(a: ourCommit.id.sha, b: theirCommit.id.sha).sha]
|
);
|
||||||
as Commit;
|
final baseCommit = repo.lookupCommit(
|
||||||
|
repo.mergeBase(a: ourCommit.id.sha, b: theirCommit.id.sha),
|
||||||
|
);
|
||||||
final theirTree = theirCommit.tree;
|
final theirTree = theirCommit.tree;
|
||||||
final ourTree = ourCommit.tree;
|
final ourTree = ourCommit.tree;
|
||||||
final ancestorTree = baseCommit.tree;
|
final ancestorTree = baseCommit.tree;
|
||||||
|
@ -311,7 +326,9 @@ conflict branch edit
|
||||||
});
|
});
|
||||||
|
|
||||||
test('successfully cherry-picks commit', () {
|
test('successfully cherry-picks commit', () {
|
||||||
final cherry = repo['5aecfa0fb97eadaac050ccb99f03c3fb65460ad4'] as Commit;
|
final cherry = repo.lookupCommit(
|
||||||
|
repo['5aecfa0fb97eadaac050ccb99f03c3fb65460ad4'],
|
||||||
|
);
|
||||||
repo.cherryPick(cherry);
|
repo.cherryPick(cherry);
|
||||||
expect(repo.state, GitRepositoryState.cherrypick);
|
expect(repo.state, GitRepositoryState.cherrypick);
|
||||||
expect(repo.message, 'add another feature file\n');
|
expect(repo.message, 'add another feature file\n');
|
||||||
|
|
|
@ -19,14 +19,14 @@ void main() {
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
setUp(() async {
|
setUp(() {
|
||||||
tmpDir = await setupRepo(Directory('test/assets/testrepo/'));
|
tmpDir = setupRepo(Directory('test/assets/testrepo/'));
|
||||||
repo = Repository.open(tmpDir.path);
|
repo = Repository.open(tmpDir.path);
|
||||||
});
|
});
|
||||||
|
|
||||||
tearDown(() async {
|
tearDown(() {
|
||||||
repo.free();
|
repo.free();
|
||||||
await tmpDir.delete(recursive: true);
|
tmpDir.deleteSync(recursive: true);
|
||||||
});
|
});
|
||||||
|
|
||||||
group('Note', () {
|
group('Note', () {
|
||||||
|
@ -39,10 +39,7 @@ void main() {
|
||||||
expect(notes[i].id.sha, notesExpected[i]['id']);
|
expect(notes[i].id.sha, notesExpected[i]['id']);
|
||||||
expect(notes[i].message, notesExpected[i]['message']);
|
expect(notes[i].message, notesExpected[i]['message']);
|
||||||
expect(notes[i].annotatedId.sha, notesExpected[i]['annotatedId']);
|
expect(notes[i].annotatedId.sha, notesExpected[i]['annotatedId']);
|
||||||
}
|
notes[i].free();
|
||||||
|
|
||||||
for (var note in notes) {
|
|
||||||
note.free();
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -64,11 +61,11 @@ void main() {
|
||||||
final noteOid = repo.createNote(
|
final noteOid = repo.createNote(
|
||||||
author: signature,
|
author: signature,
|
||||||
committer: signature,
|
committer: signature,
|
||||||
object: head.target,
|
annotatedId: head.target,
|
||||||
note: 'New note for HEAD',
|
note: 'New note for HEAD',
|
||||||
force: true,
|
force: true,
|
||||||
);
|
);
|
||||||
final noteBlob = repo[noteOid.sha] as Blob;
|
final noteBlob = repo.lookupBlob(noteOid);
|
||||||
|
|
||||||
expect(noteOid.sha, 'ffd6e2ceaf91c00ea6d29e2e897f906da720529f');
|
expect(noteOid.sha, 'ffd6e2ceaf91c00ea6d29e2e897f906da720529f');
|
||||||
expect(noteBlob.content, 'New note for HEAD');
|
expect(noteBlob.content, 'New note for HEAD');
|
||||||
|
@ -81,15 +78,18 @@ void main() {
|
||||||
test('successfully removes note', () {
|
test('successfully removes note', () {
|
||||||
final signature = repo.defaultSignature;
|
final signature = repo.defaultSignature;
|
||||||
final head = repo.head;
|
final head = repo.head;
|
||||||
final note = repo.lookupNote(annotatedId: head.target);
|
|
||||||
|
|
||||||
note.remove(author: signature, committer: signature);
|
repo.deleteNote(
|
||||||
|
annotatedId: repo.head.target,
|
||||||
|
author: signature,
|
||||||
|
committer: signature,
|
||||||
|
);
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
() => repo.lookupNote(annotatedId: head.target),
|
() => repo.lookupNote(annotatedId: head.target),
|
||||||
throwsA(isA<LibGit2Error>()),
|
throwsA(isA<LibGit2Error>()),
|
||||||
);
|
);
|
||||||
|
|
||||||
note.free();
|
|
||||||
head.free();
|
head.free();
|
||||||
signature.free();
|
signature.free();
|
||||||
});
|
});
|
||||||
|
|
|
@ -10,14 +10,14 @@ void main() {
|
||||||
const blobSha = '9c78c21d6680a7ffebc76f7ac68cacc11d8f48bc';
|
const blobSha = '9c78c21d6680a7ffebc76f7ac68cacc11d8f48bc';
|
||||||
const blobContent = 'Feature edit\n';
|
const blobContent = 'Feature edit\n';
|
||||||
|
|
||||||
setUp(() async {
|
setUp(() {
|
||||||
tmpDir = await setupRepo(Directory('test/assets/testrepo/'));
|
tmpDir = setupRepo(Directory('test/assets/testrepo/'));
|
||||||
repo = Repository.open(tmpDir.path);
|
repo = Repository.open(tmpDir.path);
|
||||||
});
|
});
|
||||||
|
|
||||||
tearDown(() async {
|
tearDown(() {
|
||||||
repo.free();
|
repo.free();
|
||||||
await tmpDir.delete(recursive: true);
|
tmpDir.deleteSync(recursive: true);
|
||||||
});
|
});
|
||||||
|
|
||||||
group('Odb', () {
|
group('Odb', () {
|
||||||
|
|
|
@ -11,14 +11,14 @@ void main() {
|
||||||
const biggerSha = '78b8bf123e3952c970ae5c1ce0a3ea1d1336f6e9';
|
const biggerSha = '78b8bf123e3952c970ae5c1ce0a3ea1d1336f6e9';
|
||||||
const lesserSha = '78b8bf123e3952c970ae5c1ce0a3ea1d1336f6e7';
|
const lesserSha = '78b8bf123e3952c970ae5c1ce0a3ea1d1336f6e7';
|
||||||
|
|
||||||
setUp(() async {
|
setUp(() {
|
||||||
tmpDir = await setupRepo(Directory('test/assets/testrepo/'));
|
tmpDir = setupRepo(Directory('test/assets/testrepo/'));
|
||||||
repo = Repository.open(tmpDir.path);
|
repo = Repository.open(tmpDir.path);
|
||||||
});
|
});
|
||||||
|
|
||||||
tearDown(() async {
|
tearDown(() {
|
||||||
repo.free();
|
repo.free();
|
||||||
await tmpDir.delete(recursive: true);
|
tmpDir.deleteSync(recursive: true);
|
||||||
});
|
});
|
||||||
|
|
||||||
group('Oid', () {
|
group('Oid', () {
|
||||||
|
|
|
@ -7,14 +7,14 @@ void main() {
|
||||||
late Repository repo;
|
late Repository repo;
|
||||||
late Directory tmpDir;
|
late Directory tmpDir;
|
||||||
|
|
||||||
setUp(() async {
|
setUp(() {
|
||||||
tmpDir = await setupRepo(Directory('test/assets/testrepo/'));
|
tmpDir = setupRepo(Directory('test/assets/testrepo/'));
|
||||||
repo = Repository.open(tmpDir.path);
|
repo = Repository.open(tmpDir.path);
|
||||||
});
|
});
|
||||||
|
|
||||||
tearDown(() async {
|
tearDown(() {
|
||||||
repo.free();
|
repo.free();
|
||||||
await tmpDir.delete(recursive: true);
|
tmpDir.deleteSync(recursive: true);
|
||||||
});
|
});
|
||||||
|
|
||||||
group('PackBuilder', () {
|
group('PackBuilder', () {
|
||||||
|
@ -86,12 +86,14 @@ void main() {
|
||||||
|
|
||||||
test('successfully packs with provided packDelegate', () {
|
test('successfully packs with provided packDelegate', () {
|
||||||
void packDelegate(PackBuilder packBuilder) {
|
void packDelegate(PackBuilder packBuilder) {
|
||||||
for (var branchName in repo.branches.list()) {
|
final branches = repo.branches;
|
||||||
final branch = repo.references['refs/heads/$branchName'];
|
for (var branch in branches) {
|
||||||
for (var commit in repo.log(sha: branch.target.sha)) {
|
final ref = repo.lookupReference('refs/heads/${branch.name}');
|
||||||
|
for (var commit in repo.log(sha: ref.target.sha)) {
|
||||||
packBuilder.addRecursively(commit.id);
|
packBuilder.addRecursively(commit.id);
|
||||||
commit.free();
|
commit.free();
|
||||||
}
|
}
|
||||||
|
ref.free();
|
||||||
branch.free();
|
branch.free();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,9 +8,9 @@ void main() {
|
||||||
late Directory tmpDir;
|
late Directory tmpDir;
|
||||||
const oldBlob = '';
|
const oldBlob = '';
|
||||||
const newBlob = 'Feature edit\n';
|
const newBlob = 'Feature edit\n';
|
||||||
|
late Oid oldBlobID;
|
||||||
|
late Oid newBlobID;
|
||||||
const path = 'feature_file';
|
const path = 'feature_file';
|
||||||
const oldBlobSha = 'e69de29bb2d1d6434b8b29ae775ad8c2e48c5391';
|
|
||||||
const newBlobSha = '9c78c21d6680a7ffebc76f7ac68cacc11d8f48bc';
|
|
||||||
const blobPatch = """
|
const blobPatch = """
|
||||||
diff --git a/feature_file b/feature_file
|
diff --git a/feature_file b/feature_file
|
||||||
index e69de29..9c78c21 100644
|
index e69de29..9c78c21 100644
|
||||||
|
@ -38,14 +38,16 @@ index e69de29..0000000
|
||||||
+++ /dev/null
|
+++ /dev/null
|
||||||
""";
|
""";
|
||||||
|
|
||||||
setUp(() async {
|
setUp(() {
|
||||||
tmpDir = await setupRepo(Directory('test/assets/testrepo/'));
|
tmpDir = setupRepo(Directory('test/assets/testrepo/'));
|
||||||
repo = Repository.open(tmpDir.path);
|
repo = Repository.open(tmpDir.path);
|
||||||
|
oldBlobID = repo['e69de29bb2d1d6434b8b29ae775ad8c2e48c5391'];
|
||||||
|
newBlobID = repo['9c78c21d6680a7ffebc76f7ac68cacc11d8f48bc'];
|
||||||
});
|
});
|
||||||
|
|
||||||
tearDown(() async {
|
tearDown(() {
|
||||||
repo.free();
|
repo.free();
|
||||||
await tmpDir.delete(recursive: true);
|
tmpDir.deleteSync(recursive: true);
|
||||||
});
|
});
|
||||||
|
|
||||||
group('Patch', () {
|
group('Patch', () {
|
||||||
|
@ -90,8 +92,8 @@ index e69de29..0000000
|
||||||
});
|
});
|
||||||
|
|
||||||
test('successfully creates from blobs', () {
|
test('successfully creates from blobs', () {
|
||||||
final a = repo[oldBlobSha] as Blob;
|
final a = repo.lookupBlob(oldBlobID);
|
||||||
final b = repo[newBlobSha] as Blob;
|
final b = repo.lookupBlob(newBlobID);
|
||||||
final patch = Patch.createFrom(
|
final patch = Patch.createFrom(
|
||||||
a: a,
|
a: a,
|
||||||
b: b,
|
b: b,
|
||||||
|
@ -105,7 +107,7 @@ index e69de29..0000000
|
||||||
});
|
});
|
||||||
|
|
||||||
test('successfully creates from one blob (add)', () {
|
test('successfully creates from one blob (add)', () {
|
||||||
final b = repo[newBlobSha] as Blob;
|
final b = repo.lookupBlob(newBlobID);
|
||||||
final patch = Patch.createFrom(
|
final patch = Patch.createFrom(
|
||||||
a: null,
|
a: null,
|
||||||
b: b,
|
b: b,
|
||||||
|
@ -119,7 +121,7 @@ index e69de29..0000000
|
||||||
});
|
});
|
||||||
|
|
||||||
test('successfully creates from one blob (delete)', () {
|
test('successfully creates from one blob (delete)', () {
|
||||||
final a = repo[oldBlobSha] as Blob;
|
final a = repo.lookupBlob(oldBlobID);
|
||||||
final patch = Patch.createFrom(
|
final patch = Patch.createFrom(
|
||||||
a: a,
|
a: a,
|
||||||
b: null,
|
b: null,
|
||||||
|
@ -133,7 +135,7 @@ index e69de29..0000000
|
||||||
});
|
});
|
||||||
|
|
||||||
test('successfully creates from blob and buffer', () {
|
test('successfully creates from blob and buffer', () {
|
||||||
final a = repo[oldBlobSha] as Blob;
|
final a = repo.lookupBlob(oldBlobID);
|
||||||
final patch = Patch.createFrom(
|
final patch = Patch.createFrom(
|
||||||
a: a,
|
a: a,
|
||||||
b: newBlob,
|
b: newBlob,
|
||||||
|
@ -147,7 +149,9 @@ index e69de29..0000000
|
||||||
});
|
});
|
||||||
|
|
||||||
test('throws when argument is not Blob or String', () {
|
test('throws when argument is not Blob or String', () {
|
||||||
final commit = repo['fc38877b2552ab554752d9a77e1f48f738cca79b'] as Commit;
|
final commit = repo.lookupCommit(
|
||||||
|
repo['fc38877b2552ab554752d9a77e1f48f738cca79b'],
|
||||||
|
);
|
||||||
expect(
|
expect(
|
||||||
() => Patch.createFrom(
|
() => Patch.createFrom(
|
||||||
a: commit,
|
a: commit,
|
||||||
|
|
|
@ -12,21 +12,21 @@ void main() {
|
||||||
'14905459d775f3f56a39ebc2ff081163f7da3529',
|
'14905459d775f3f56a39ebc2ff081163f7da3529',
|
||||||
];
|
];
|
||||||
|
|
||||||
setUp(() async {
|
setUp(() {
|
||||||
tmpDir = await setupRepo(Directory('test/assets/mergerepo/'));
|
tmpDir = setupRepo(Directory('test/assets/mergerepo/'));
|
||||||
repo = Repository.open(tmpDir.path);
|
repo = Repository.open(tmpDir.path);
|
||||||
});
|
});
|
||||||
|
|
||||||
tearDown(() async {
|
tearDown(() {
|
||||||
repo.free();
|
repo.free();
|
||||||
await tmpDir.delete(recursive: true);
|
tmpDir.deleteSync(recursive: true);
|
||||||
});
|
});
|
||||||
|
|
||||||
group('Rebase', () {
|
group('Rebase', () {
|
||||||
test('successfully performs rebase when there is no conflicts', () {
|
test('successfully performs rebase when there is no conflicts', () {
|
||||||
final signature = repo.defaultSignature;
|
final signature = repo.defaultSignature;
|
||||||
final master = repo.references['refs/heads/master'];
|
final master = repo.lookupReference('refs/heads/master');
|
||||||
final feature = repo.references['refs/heads/feature'];
|
final feature = repo.lookupReference('refs/heads/feature');
|
||||||
|
|
||||||
repo.checkout(refName: feature.name);
|
repo.checkout(refName: feature.name);
|
||||||
expect(() => repo.index['.gitignore'], throwsA(isA<ArgumentError>()));
|
expect(() => repo.index['.gitignore'], throwsA(isA<ArgumentError>()));
|
||||||
|
@ -60,9 +60,9 @@ void main() {
|
||||||
|
|
||||||
test('successfully performs rebase with provided upstream', () {
|
test('successfully performs rebase with provided upstream', () {
|
||||||
final signature = repo.defaultSignature;
|
final signature = repo.defaultSignature;
|
||||||
final master = repo.references['refs/heads/master'];
|
final master = repo.lookupReference('refs/heads/master');
|
||||||
final feature = repo.references['refs/heads/feature'];
|
final feature = repo.lookupReference('refs/heads/feature');
|
||||||
final startCommit = repo[shas[1]] as Commit;
|
final startCommit = repo.lookupCommit(repo[shas[1]]);
|
||||||
|
|
||||||
repo.checkout(refName: feature.name);
|
repo.checkout(refName: feature.name);
|
||||||
expect(
|
expect(
|
||||||
|
@ -97,8 +97,8 @@ void main() {
|
||||||
|
|
||||||
test('stops when there is conflicts', () {
|
test('stops when there is conflicts', () {
|
||||||
final signature = repo.defaultSignature;
|
final signature = repo.defaultSignature;
|
||||||
final master = repo.references['refs/heads/master'];
|
final master = repo.lookupReference('refs/heads/master');
|
||||||
final conflict = repo.references['refs/heads/conflict-branch'];
|
final conflict = repo.lookupReference('refs/heads/conflict-branch');
|
||||||
|
|
||||||
repo.checkout(refName: conflict.name);
|
repo.checkout(refName: conflict.name);
|
||||||
|
|
||||||
|
@ -124,8 +124,8 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('successfully aborts rebase in progress', () {
|
test('successfully aborts rebase in progress', () {
|
||||||
final master = repo.references['refs/heads/master'];
|
final master = repo.lookupReference('refs/heads/master');
|
||||||
final conflict = repo.references['refs/heads/conflict-branch'];
|
final conflict = repo.lookupReference('refs/heads/conflict-branch');
|
||||||
|
|
||||||
repo.checkout(refName: conflict.name);
|
repo.checkout(refName: conflict.name);
|
||||||
|
|
||||||
|
|
|
@ -9,20 +9,20 @@ void main() {
|
||||||
const lastCommit = '821ed6e80627b8769d170a293862f9fc60825226';
|
const lastCommit = '821ed6e80627b8769d170a293862f9fc60825226';
|
||||||
const newCommit = 'c68ff54aabf660fcdd9a2838d401583fe31249e3';
|
const newCommit = 'c68ff54aabf660fcdd9a2838d401583fe31249e3';
|
||||||
|
|
||||||
setUp(() async {
|
setUp(() {
|
||||||
tmpDir = await setupRepo(Directory('test/assets/testrepo/'));
|
tmpDir = setupRepo(Directory('test/assets/testrepo/'));
|
||||||
repo = Repository.open(tmpDir.path);
|
repo = Repository.open(tmpDir.path);
|
||||||
});
|
});
|
||||||
|
|
||||||
tearDown(() async {
|
tearDown(() {
|
||||||
repo.free();
|
repo.free();
|
||||||
await tmpDir.delete(recursive: true);
|
tmpDir.deleteSync(recursive: true);
|
||||||
});
|
});
|
||||||
|
|
||||||
group('Reference', () {
|
group('Reference', () {
|
||||||
test('returns a list', () {
|
test('returns a list', () {
|
||||||
expect(
|
expect(
|
||||||
repo.references.list,
|
repo.references,
|
||||||
[
|
[
|
||||||
'refs/heads/feature',
|
'refs/heads/feature',
|
||||||
'refs/heads/master',
|
'refs/heads/master',
|
||||||
|
@ -38,7 +38,7 @@ void main() {
|
||||||
expect(head.type, ReferenceType.direct);
|
expect(head.type, ReferenceType.direct);
|
||||||
head.free();
|
head.free();
|
||||||
|
|
||||||
final ref = repo.references['HEAD'];
|
final ref = repo.lookupReference('HEAD');
|
||||||
expect(ref.type, ReferenceType.symbolic);
|
expect(ref.type, ReferenceType.symbolic);
|
||||||
ref.free();
|
ref.free();
|
||||||
});
|
});
|
||||||
|
@ -50,7 +50,7 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('returns SHA hex of symbolic reference', () {
|
test('returns SHA hex of symbolic reference', () {
|
||||||
final ref = repo.references['HEAD'];
|
final ref = repo.lookupReference('HEAD');
|
||||||
expect(ref.target.sha, lastCommit);
|
expect(ref.target.sha, lastCommit);
|
||||||
ref.free();
|
ref.free();
|
||||||
});
|
});
|
||||||
|
@ -62,7 +62,7 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('returns the short name', () {
|
test('returns the short name', () {
|
||||||
final ref = repo.references.create(
|
final ref = repo.createReference(
|
||||||
name: 'refs/remotes/origin/master',
|
name: 'refs/remotes/origin/master',
|
||||||
target: lastCommit,
|
target: lastCommit,
|
||||||
);
|
);
|
||||||
|
@ -77,19 +77,19 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('checks if reference is a local branch', () {
|
test('checks if reference is a local branch', () {
|
||||||
final ref = repo.references['refs/heads/feature'];
|
final ref = repo.lookupReference('refs/heads/feature');
|
||||||
expect(ref.isBranch, true);
|
expect(ref.isBranch, true);
|
||||||
ref.free();
|
ref.free();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('checks if reference is a note', () {
|
test('checks if reference is a note', () {
|
||||||
final ref = repo.references['refs/heads/master'];
|
final ref = repo.lookupReference('refs/heads/master');
|
||||||
expect(ref.isNote, false);
|
expect(ref.isNote, false);
|
||||||
ref.free();
|
ref.free();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('checks if reference is a remote branch', () {
|
test('checks if reference is a remote branch', () {
|
||||||
final ref = repo.references.create(
|
final ref = repo.createReference(
|
||||||
name: 'refs/remotes/origin/master',
|
name: 'refs/remotes/origin/master',
|
||||||
target: lastCommit,
|
target: lastCommit,
|
||||||
);
|
);
|
||||||
|
@ -100,16 +100,16 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('checks if reference is a tag', () {
|
test('checks if reference is a tag', () {
|
||||||
final ref = repo.references['refs/tags/v0.1'];
|
final ref = repo.lookupReference('refs/tags/v0.1');
|
||||||
expect(ref.isTag, true);
|
expect(ref.isTag, true);
|
||||||
ref.free();
|
ref.free();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('checks if reflog exists for the reference', () {
|
test('checks if reflog exists for the reference', () {
|
||||||
var ref = repo.references['refs/heads/master'];
|
var ref = repo.lookupReference('refs/heads/master');
|
||||||
expect(ref.hasLog, true);
|
expect(ref.hasLog, true);
|
||||||
|
|
||||||
ref = repo.references['refs/tags/v0.1'];
|
ref = repo.lookupReference('refs/tags/v0.1');
|
||||||
expect(ref.hasLog, false);
|
expect(ref.hasLog, false);
|
||||||
|
|
||||||
ref.free();
|
ref.free();
|
||||||
|
@ -117,43 +117,43 @@ void main() {
|
||||||
|
|
||||||
group('create direct', () {
|
group('create direct', () {
|
||||||
test('successfully creates with Oid as target', () {
|
test('successfully creates with Oid as target', () {
|
||||||
final ref = repo.references['refs/heads/master'];
|
final ref = repo.lookupReference('refs/heads/master');
|
||||||
final refFromOid = repo.references.create(
|
final refFromOid = repo.createReference(
|
||||||
name: 'refs/tags/from.oid',
|
name: 'refs/tags/from.oid',
|
||||||
target: ref.target,
|
target: ref.target,
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(repo.references.list, contains('refs/tags/from.oid'));
|
expect(repo.references, contains('refs/tags/from.oid'));
|
||||||
|
|
||||||
refFromOid.free();
|
refFromOid.free();
|
||||||
ref.free();
|
ref.free();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('successfully creates with SHA hash as target', () {
|
test('successfully creates with SHA hash as target', () {
|
||||||
final refFromHash = repo.references.create(
|
final refFromHash = repo.createReference(
|
||||||
name: 'refs/tags/from.hash',
|
name: 'refs/tags/from.hash',
|
||||||
target: lastCommit,
|
target: lastCommit,
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(repo.references.list, contains('refs/tags/from.hash'));
|
expect(repo.references, contains('refs/tags/from.hash'));
|
||||||
|
|
||||||
refFromHash.free();
|
refFromHash.free();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('successfully creates with short SHA hash as target', () {
|
test('successfully creates with short SHA hash as target', () {
|
||||||
final refFromHash = repo.references.create(
|
final refFromHash = repo.createReference(
|
||||||
name: 'refs/tags/from.short.hash',
|
name: 'refs/tags/from.short.hash',
|
||||||
target: '78b8bf',
|
target: '78b8bf',
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(repo.references.list, contains('refs/tags/from.short.hash'));
|
expect(repo.references, contains('refs/tags/from.short.hash'));
|
||||||
|
|
||||||
refFromHash.free();
|
refFromHash.free();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('successfully creates with log message', () {
|
test('successfully creates with log message', () {
|
||||||
repo.setIdentity(name: 'name', email: 'email');
|
repo.setIdentity(name: 'name', email: 'email');
|
||||||
final ref = repo.references.create(
|
final ref = repo.createReference(
|
||||||
name: 'refs/heads/log.message',
|
name: 'refs/heads/log.message',
|
||||||
target: lastCommit,
|
target: lastCommit,
|
||||||
logMessage: 'log message',
|
logMessage: 'log message',
|
||||||
|
@ -172,7 +172,7 @@ void main() {
|
||||||
|
|
||||||
test('throws if target is not valid', () {
|
test('throws if target is not valid', () {
|
||||||
expect(
|
expect(
|
||||||
() => repo.references.create(
|
() => repo.createReference(
|
||||||
name: 'refs/tags/invalid',
|
name: 'refs/tags/invalid',
|
||||||
target: '78b',
|
target: '78b',
|
||||||
),
|
),
|
||||||
|
@ -182,7 +182,7 @@ void main() {
|
||||||
|
|
||||||
test('throws if name is not valid', () {
|
test('throws if name is not valid', () {
|
||||||
expect(
|
expect(
|
||||||
() => repo.references.create(
|
() => repo.createReference(
|
||||||
name: 'refs/tags/invalid~',
|
name: 'refs/tags/invalid~',
|
||||||
target: lastCommit,
|
target: lastCommit,
|
||||||
),
|
),
|
||||||
|
@ -191,12 +191,12 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('successfully creates with force flag if name already exists', () {
|
test('successfully creates with force flag if name already exists', () {
|
||||||
final ref = repo.references.create(
|
final ref = repo.createReference(
|
||||||
name: 'refs/tags/test',
|
name: 'refs/tags/test',
|
||||||
target: lastCommit,
|
target: lastCommit,
|
||||||
);
|
);
|
||||||
|
|
||||||
final forceRef = repo.references.create(
|
final forceRef = repo.createReference(
|
||||||
name: 'refs/tags/test',
|
name: 'refs/tags/test',
|
||||||
target: lastCommit,
|
target: lastCommit,
|
||||||
force: true,
|
force: true,
|
||||||
|
@ -209,13 +209,13 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('throws if name already exists', () {
|
test('throws if name already exists', () {
|
||||||
final ref = repo.references.create(
|
final ref = repo.createReference(
|
||||||
name: 'refs/tags/test',
|
name: 'refs/tags/test',
|
||||||
target: lastCommit,
|
target: lastCommit,
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
() => repo.references.create(
|
() => repo.createReference(
|
||||||
name: 'refs/tags/test',
|
name: 'refs/tags/test',
|
||||||
target: lastCommit,
|
target: lastCommit,
|
||||||
),
|
),
|
||||||
|
@ -228,24 +228,24 @@ void main() {
|
||||||
|
|
||||||
group('create symbolic', () {
|
group('create symbolic', () {
|
||||||
test('successfully creates with valid target', () {
|
test('successfully creates with valid target', () {
|
||||||
final ref = repo.references.create(
|
final ref = repo.createReference(
|
||||||
name: 'refs/tags/symbolic',
|
name: 'refs/tags/symbolic',
|
||||||
target: 'refs/heads/master',
|
target: 'refs/heads/master',
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(repo.references.list, contains('refs/tags/symbolic'));
|
expect(repo.references, contains('refs/tags/symbolic'));
|
||||||
expect(ref.type, ReferenceType.symbolic);
|
expect(ref.type, ReferenceType.symbolic);
|
||||||
|
|
||||||
ref.free();
|
ref.free();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('successfully creates with force flag if name already exists', () {
|
test('successfully creates with force flag if name already exists', () {
|
||||||
final ref = repo.references.create(
|
final ref = repo.createReference(
|
||||||
name: 'refs/tags/test',
|
name: 'refs/tags/test',
|
||||||
target: 'refs/heads/master',
|
target: 'refs/heads/master',
|
||||||
);
|
);
|
||||||
|
|
||||||
final forceRef = repo.references.create(
|
final forceRef = repo.createReference(
|
||||||
name: 'refs/tags/test',
|
name: 'refs/tags/test',
|
||||||
target: 'refs/heads/master',
|
target: 'refs/heads/master',
|
||||||
force: true,
|
force: true,
|
||||||
|
@ -259,13 +259,13 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('throws if name already exists', () {
|
test('throws if name already exists', () {
|
||||||
final ref = repo.references.create(
|
final ref = repo.createReference(
|
||||||
name: 'refs/tags/exists',
|
name: 'refs/tags/exists',
|
||||||
target: 'refs/heads/master',
|
target: 'refs/heads/master',
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
() => repo.references.create(
|
() => repo.createReference(
|
||||||
name: 'refs/tags/exists',
|
name: 'refs/tags/exists',
|
||||||
target: 'refs/heads/master',
|
target: 'refs/heads/master',
|
||||||
),
|
),
|
||||||
|
@ -277,7 +277,7 @@ void main() {
|
||||||
|
|
||||||
test('throws if name is not valid', () {
|
test('throws if name is not valid', () {
|
||||||
expect(
|
expect(
|
||||||
() => repo.references.create(
|
() => repo.createReference(
|
||||||
name: 'refs/tags/invalid~',
|
name: 'refs/tags/invalid~',
|
||||||
target: 'refs/heads/master',
|
target: 'refs/heads/master',
|
||||||
),
|
),
|
||||||
|
@ -287,7 +287,7 @@ void main() {
|
||||||
|
|
||||||
test('successfully creates with log message', () {
|
test('successfully creates with log message', () {
|
||||||
repo.setIdentity(name: 'name', email: 'email');
|
repo.setIdentity(name: 'name', email: 'email');
|
||||||
final ref = repo.references.create(
|
final ref = repo.createReference(
|
||||||
name: 'HEAD',
|
name: 'HEAD',
|
||||||
target: 'refs/heads/feature',
|
target: 'refs/heads/feature',
|
||||||
force: true,
|
force: true,
|
||||||
|
@ -307,34 +307,34 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('successfully deletes reference', () {
|
test('successfully deletes reference', () {
|
||||||
final ref = repo.references.create(
|
final ref = repo.createReference(
|
||||||
name: 'refs/tags/test',
|
name: 'refs/tags/test',
|
||||||
target: lastCommit,
|
target: lastCommit,
|
||||||
);
|
);
|
||||||
expect(repo.references.list, contains('refs/tags/test'));
|
expect(repo.references, contains('refs/tags/test'));
|
||||||
|
|
||||||
ref.delete();
|
repo.deleteReference('refs/tags/test');
|
||||||
expect(repo.references.list, isNot(contains('refs/tags/test')));
|
expect(repo.references, isNot(contains('refs/tags/test')));
|
||||||
ref.free();
|
ref.free();
|
||||||
});
|
});
|
||||||
|
|
||||||
group('finds', () {
|
group('finds', () {
|
||||||
test('with provided name', () {
|
test('with provided name', () {
|
||||||
final ref = repo.references['refs/heads/master'];
|
final ref = repo.lookupReference('refs/heads/master');
|
||||||
expect(ref.target.sha, lastCommit);
|
expect(ref.target.sha, lastCommit);
|
||||||
ref.free();
|
ref.free();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('throws when error occured', () {
|
test('throws when error occured', () {
|
||||||
expect(
|
expect(
|
||||||
() => repo.references['refs/heads/not/there'],
|
() => repo.lookupReference('refs/heads/not/there'),
|
||||||
throwsA(isA<LibGit2Error>()),
|
throwsA(isA<LibGit2Error>()),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
test('returns log for reference', () {
|
test('returns log for reference', () {
|
||||||
final ref = repo.references['refs/heads/master'];
|
final ref = repo.lookupReference('refs/heads/master');
|
||||||
final reflog = ref.log;
|
final reflog = ref.log;
|
||||||
expect(reflog.last.message, 'commit (initial): init');
|
expect(reflog.last.message, 'commit (initial): init');
|
||||||
|
|
||||||
|
@ -344,7 +344,7 @@ void main() {
|
||||||
|
|
||||||
group('set target', () {
|
group('set target', () {
|
||||||
test('successfully sets with SHA hex', () {
|
test('successfully sets with SHA hex', () {
|
||||||
final ref = repo.references['refs/heads/master'];
|
final ref = repo.lookupReference('refs/heads/master');
|
||||||
ref.setTarget(target: newCommit);
|
ref.setTarget(target: newCommit);
|
||||||
expect(ref.target.sha, newCommit);
|
expect(ref.target.sha, newCommit);
|
||||||
|
|
||||||
|
@ -352,7 +352,7 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('successfully sets target with short SHA hex', () {
|
test('successfully sets target with short SHA hex', () {
|
||||||
final ref = repo.references['refs/heads/master'];
|
final ref = repo.lookupReference('refs/heads/master');
|
||||||
ref.setTarget(target: newCommit.substring(0, 5));
|
ref.setTarget(target: newCommit.substring(0, 5));
|
||||||
expect(ref.target.sha, newCommit);
|
expect(ref.target.sha, newCommit);
|
||||||
|
|
||||||
|
@ -360,7 +360,7 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('successfully sets symbolic target', () {
|
test('successfully sets symbolic target', () {
|
||||||
final ref = repo.references['HEAD'];
|
final ref = repo.lookupReference('HEAD');
|
||||||
expect(ref.target.sha, lastCommit);
|
expect(ref.target.sha, lastCommit);
|
||||||
|
|
||||||
ref.setTarget(target: 'refs/heads/feature');
|
ref.setTarget(target: 'refs/heads/feature');
|
||||||
|
@ -370,7 +370,7 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('successfully sets target with log message', () {
|
test('successfully sets target with log message', () {
|
||||||
final ref = repo.references['HEAD'];
|
final ref = repo.lookupReference('HEAD');
|
||||||
expect(ref.target.sha, lastCommit);
|
expect(ref.target.sha, lastCommit);
|
||||||
|
|
||||||
repo.setIdentity(name: 'name', email: 'email');
|
repo.setIdentity(name: 'name', email: 'email');
|
||||||
|
@ -386,7 +386,7 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('throws on invalid target', () {
|
test('throws on invalid target', () {
|
||||||
final ref = repo.references['HEAD'];
|
final ref = repo.lookupReference('HEAD');
|
||||||
expect(
|
expect(
|
||||||
() => ref.setTarget(target: 'refs/heads/invalid~'),
|
() => ref.setTarget(target: 'refs/heads/invalid~'),
|
||||||
throwsA(isA<LibGit2Error>()),
|
throwsA(isA<LibGit2Error>()),
|
||||||
|
@ -398,67 +398,56 @@ void main() {
|
||||||
|
|
||||||
group('rename', () {
|
group('rename', () {
|
||||||
test('successfully renames reference', () {
|
test('successfully renames reference', () {
|
||||||
final ref = repo.references.create(
|
repo.renameReference(
|
||||||
name: 'refs/tags/v1',
|
oldName: 'refs/tags/v0.1',
|
||||||
target: lastCommit,
|
newName: 'refs/tags/renamed',
|
||||||
);
|
);
|
||||||
expect(ref.name, 'refs/tags/v1');
|
|
||||||
|
|
||||||
ref.rename(newName: 'refs/tags/v2');
|
expect(repo.references, contains('refs/tags/renamed'));
|
||||||
expect(ref.name, 'refs/tags/v2');
|
expect(repo.references, isNot(contains('refs/tags/v0.1')));
|
||||||
|
|
||||||
ref.free();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('throws on invalid name', () {
|
test('throws on invalid name', () {
|
||||||
final ref = repo.references.create(
|
|
||||||
name: 'refs/tags/v1',
|
|
||||||
target: lastCommit,
|
|
||||||
);
|
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
() => ref.rename(newName: 'refs/tags/invalid~'),
|
() => repo.renameReference(
|
||||||
|
oldName: 'refs/tags/v0.1',
|
||||||
|
newName: 'refs/tags/invalid~',
|
||||||
|
),
|
||||||
throwsA(isA<LibGit2Error>()),
|
throwsA(isA<LibGit2Error>()),
|
||||||
);
|
);
|
||||||
|
|
||||||
ref.free();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('throws if name already exists', () {
|
test('throws if name already exists', () {
|
||||||
final ref1 = repo.references.create(
|
|
||||||
name: 'refs/tags/v1',
|
|
||||||
target: lastCommit,
|
|
||||||
);
|
|
||||||
|
|
||||||
final ref2 = repo.references.create(
|
|
||||||
name: 'refs/tags/v2',
|
|
||||||
target: lastCommit,
|
|
||||||
);
|
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
() => ref1.rename(newName: 'refs/tags/v2'),
|
() => repo.renameReference(
|
||||||
|
oldName: 'refs/tags/v0.1',
|
||||||
|
newName: 'refs/tags/v0.2',
|
||||||
|
),
|
||||||
throwsA(isA<LibGit2Error>()),
|
throwsA(isA<LibGit2Error>()),
|
||||||
);
|
);
|
||||||
|
|
||||||
ref1.free();
|
|
||||||
ref2.free();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('successfully renames with force flag set to true', () {
|
test('successfully renames with force flag set to true', () {
|
||||||
final ref1 = repo.references.create(
|
final ref1 = repo.lookupReference('refs/tags/v0.1');
|
||||||
name: 'refs/tags/v1',
|
final ref2 = repo.lookupReference('refs/tags/v0.2');
|
||||||
target: lastCommit,
|
|
||||||
|
expect(ref1.target.sha, '78b8bf123e3952c970ae5c1ce0a3ea1d1336f6e8');
|
||||||
|
expect(ref2.target.sha, 'f0fdbf506397e9f58c59b88dfdd72778ec06cc0c');
|
||||||
|
expect(repo.references.length, 5);
|
||||||
|
|
||||||
|
repo.renameReference(
|
||||||
|
oldName: 'refs/tags/v0.1',
|
||||||
|
newName: 'refs/tags/v0.2',
|
||||||
|
force: true,
|
||||||
);
|
);
|
||||||
|
|
||||||
final ref2 = repo.references.create(
|
final updatedRef1 = repo.lookupReference('refs/tags/v0.2');
|
||||||
name: 'refs/tags/v2',
|
expect(
|
||||||
target: newCommit,
|
updatedRef1.target.sha,
|
||||||
|
'78b8bf123e3952c970ae5c1ce0a3ea1d1336f6e8',
|
||||||
);
|
);
|
||||||
|
expect(repo.references, isNot(contains('refs/tags/v0.1')));
|
||||||
expect(ref2.target.sha, newCommit);
|
expect(repo.references.length, 4);
|
||||||
|
|
||||||
ref1.rename(newName: 'refs/tags/v2', force: true);
|
|
||||||
expect(ref1.name, 'refs/tags/v2');
|
|
||||||
|
|
||||||
ref1.free();
|
ref1.free();
|
||||||
ref2.free();
|
ref2.free();
|
||||||
|
@ -466,9 +455,9 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('checks equality', () {
|
test('checks equality', () {
|
||||||
final ref1 = repo.references['refs/heads/master'];
|
final ref1 = repo.lookupReference('refs/heads/master');
|
||||||
final ref2 = repo.references['refs/heads/master'];
|
final ref2 = repo.lookupReference('refs/heads/master');
|
||||||
final ref3 = repo.references['refs/heads/feature'];
|
final ref3 = repo.lookupReference('refs/heads/feature');
|
||||||
|
|
||||||
expect(ref1 == ref2, true);
|
expect(ref1 == ref2, true);
|
||||||
expect(ref1 != ref2, false);
|
expect(ref1 != ref2, false);
|
||||||
|
@ -481,8 +470,8 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('successfully peels to non-tag object when no type is provided', () {
|
test('successfully peels to non-tag object when no type is provided', () {
|
||||||
final ref = repo.references['refs/heads/master'];
|
final ref = repo.lookupReference('refs/heads/master');
|
||||||
final commit = repo[ref.target.sha] as Commit;
|
final commit = repo.lookupCommit(ref.target);
|
||||||
final peeled = ref.peel() as Commit;
|
final peeled = ref.peel() as Commit;
|
||||||
|
|
||||||
expect(peeled.id, commit.id);
|
expect(peeled.id, commit.id);
|
||||||
|
@ -493,8 +482,8 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('successfully peels to object of provided type', () {
|
test('successfully peels to object of provided type', () {
|
||||||
final ref = repo.references['refs/heads/master'];
|
final ref = repo.lookupReference('refs/heads/master');
|
||||||
final commit = repo[ref.target.sha] as Commit;
|
final commit = repo.lookupCommit(ref.target);
|
||||||
final tree = commit.tree;
|
final tree = commit.tree;
|
||||||
final peeledCommit = ref.peel(GitObject.commit) as Commit;
|
final peeledCommit = ref.peel(GitObject.commit) as Commit;
|
||||||
final peeledTree = ref.peel(GitObject.tree) as Tree;
|
final peeledTree = ref.peel(GitObject.tree) as Tree;
|
||||||
|
@ -511,12 +500,12 @@ void main() {
|
||||||
test('successfully compresses references', () {
|
test('successfully compresses references', () {
|
||||||
final packedRefsFile = File('${tmpDir.path}/.git/packed-refs');
|
final packedRefsFile = File('${tmpDir.path}/.git/packed-refs');
|
||||||
expect(packedRefsFile.existsSync(), false);
|
expect(packedRefsFile.existsSync(), false);
|
||||||
final oldRefs = repo.references.list;
|
final oldRefs = repo.references;
|
||||||
|
|
||||||
repo.references.compress();
|
Reference.compress(repo);
|
||||||
|
|
||||||
expect(packedRefsFile.existsSync(), true);
|
expect(packedRefsFile.existsSync(), true);
|
||||||
final newRefs = repo.references.list;
|
final newRefs = repo.references;
|
||||||
expect(newRefs, oldRefs);
|
expect(newRefs, oldRefs);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -9,18 +9,18 @@ void main() {
|
||||||
late Reference head;
|
late Reference head;
|
||||||
late Directory tmpDir;
|
late Directory tmpDir;
|
||||||
|
|
||||||
setUp(() async {
|
setUp(() {
|
||||||
tmpDir = await setupRepo(Directory('test/assets/testrepo/'));
|
tmpDir = setupRepo(Directory('test/assets/testrepo/'));
|
||||||
repo = Repository.open(tmpDir.path);
|
repo = Repository.open(tmpDir.path);
|
||||||
head = repo.head;
|
head = repo.head;
|
||||||
reflog = RefLog(head);
|
reflog = RefLog(head);
|
||||||
});
|
});
|
||||||
|
|
||||||
tearDown(() async {
|
tearDown(() {
|
||||||
reflog.free();
|
reflog.free();
|
||||||
head.free();
|
head.free();
|
||||||
repo.free();
|
repo.free();
|
||||||
await tmpDir.delete(recursive: true);
|
tmpDir.deleteSync(recursive: true);
|
||||||
});
|
});
|
||||||
|
|
||||||
group('RefLog', () {
|
group('RefLog', () {
|
||||||
|
|
|
@ -10,43 +10,61 @@ void main() {
|
||||||
late Remote remote;
|
late Remote remote;
|
||||||
final cloneDir = Directory('${Directory.systemTemp.path}/cloned');
|
final cloneDir = Directory('${Directory.systemTemp.path}/cloned');
|
||||||
|
|
||||||
setUp(() async {
|
setUp(() {
|
||||||
tmpDir = await setupRepo(Directory('test/assets/testrepo/'));
|
tmpDir = setupRepo(Directory('test/assets/testrepo/'));
|
||||||
if (await cloneDir.exists()) {
|
if (cloneDir.existsSync()) {
|
||||||
cloneDir.delete(recursive: true);
|
cloneDir.deleteSync(recursive: true);
|
||||||
}
|
}
|
||||||
originRepo = Repository.open(tmpDir.path);
|
originRepo = Repository.open(tmpDir.path);
|
||||||
clonedRepo = Repository.clone(
|
clonedRepo = Repository.clone(
|
||||||
url: tmpDir.path,
|
url: tmpDir.path,
|
||||||
localPath: cloneDir.path,
|
localPath: cloneDir.path,
|
||||||
);
|
);
|
||||||
originRepo.branches['feature'].delete();
|
originRepo.deleteBranch('feature');
|
||||||
remote = clonedRepo.remotes['origin'];
|
remote = clonedRepo.lookupRemote('origin');
|
||||||
});
|
});
|
||||||
|
|
||||||
tearDown(() async {
|
tearDown(() {
|
||||||
remote.free();
|
remote.free();
|
||||||
originRepo.free();
|
originRepo.free();
|
||||||
clonedRepo.free();
|
clonedRepo.free();
|
||||||
await tmpDir.delete(recursive: true);
|
tmpDir.deleteSync(recursive: true);
|
||||||
if (await cloneDir.exists()) {
|
if (cloneDir.existsSync()) {
|
||||||
cloneDir.delete(recursive: true);
|
cloneDir.deleteSync(recursive: true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
group('Remote', () {
|
group('Remote', () {
|
||||||
test('fetch() does not prune branch by default', () {
|
test('fetch() does not prune branch by default', () {
|
||||||
remote.fetch();
|
remote.fetch();
|
||||||
expect(clonedRepo.branches.list(), contains('origin/feature'));
|
|
||||||
|
final branches = clonedRepo.branches;
|
||||||
|
expect(branches.any((branch) => branch.name == 'origin/feature'), true);
|
||||||
|
|
||||||
|
for (final branch in branches) {
|
||||||
|
branch.free();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
test('fetch() successfully prunes branch with provided flag', () {
|
test('fetch() successfully prunes branch with provided flag', () {
|
||||||
remote.fetch(prune: GitFetchPrune.prune);
|
remote.fetch(prune: GitFetchPrune.prune);
|
||||||
expect(clonedRepo.branches.list(), isNot(contains('origin/feature')));
|
|
||||||
|
final branches = clonedRepo.branches;
|
||||||
|
expect(branches.any((branch) => branch.name == 'origin/feature'), false);
|
||||||
|
|
||||||
|
for (final branch in branches) {
|
||||||
|
branch.free();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
test('fetch() does not prune branch with provided flag', () {
|
test('fetch() does not prune branch with provided flag', () {
|
||||||
remote.fetch(prune: GitFetchPrune.noPrune);
|
remote.fetch(prune: GitFetchPrune.noPrune);
|
||||||
expect(clonedRepo.branches.list(), contains('origin/feature'));
|
|
||||||
|
final branches = clonedRepo.branches;
|
||||||
|
expect(branches.any((branch) => branch.name == 'origin/feature'), true);
|
||||||
|
|
||||||
|
for (final branch in branches) {
|
||||||
|
branch.free();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
test('prune() successfully prunes branches', () {
|
test('prune() successfully prunes branches', () {
|
||||||
|
@ -58,11 +76,22 @@ void main() {
|
||||||
final callbacks = Callbacks(updateTips: updateTips);
|
final callbacks = Callbacks(updateTips: updateTips);
|
||||||
|
|
||||||
remote.fetch(prune: GitFetchPrune.noPrune);
|
remote.fetch(prune: GitFetchPrune.noPrune);
|
||||||
expect(clonedRepo.branches.list(), contains('origin/feature'));
|
var branches = clonedRepo.branches;
|
||||||
|
expect(branches.any((branch) => branch.name == 'origin/feature'), true);
|
||||||
|
|
||||||
|
for (final branch in branches) {
|
||||||
|
branch.free();
|
||||||
|
}
|
||||||
|
|
||||||
remote.prune(callbacks);
|
remote.prune(callbacks);
|
||||||
|
|
||||||
|
branches = clonedRepo.branches;
|
||||||
expect(pruned, contains('refs/remotes/origin/feature'));
|
expect(pruned, contains('refs/remotes/origin/feature'));
|
||||||
expect(clonedRepo.branches.list(), isNot(contains('origin/feature')));
|
expect(branches.any((branch) => branch.name == 'origin/feature'), false);
|
||||||
|
|
||||||
|
for (final branch in branches) {
|
||||||
|
branch.free();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,23 +9,23 @@ void main() {
|
||||||
const remoteName = 'origin';
|
const remoteName = 'origin';
|
||||||
const remoteUrl = 'git://github.com/SkinnyMind/libgit2dart.git';
|
const remoteUrl = 'git://github.com/SkinnyMind/libgit2dart.git';
|
||||||
|
|
||||||
setUp(() async {
|
setUp(() {
|
||||||
tmpDir = await setupRepo(Directory('test/assets/testrepo/'));
|
tmpDir = setupRepo(Directory('test/assets/testrepo/'));
|
||||||
repo = Repository.open(tmpDir.path);
|
repo = Repository.open(tmpDir.path);
|
||||||
});
|
});
|
||||||
|
|
||||||
tearDown(() async {
|
tearDown(() {
|
||||||
repo.free();
|
repo.free();
|
||||||
await tmpDir.delete(recursive: true);
|
tmpDir.deleteSync(recursive: true);
|
||||||
});
|
});
|
||||||
|
|
||||||
group('Remote', () {
|
group('Remote', () {
|
||||||
test('returns list of remotes', () {
|
test('returns list of remotes', () {
|
||||||
expect(repo.remotes.list, ['origin']);
|
expect(repo.remotes, ['origin']);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('successfully looks up remote for provided name', () {
|
test('successfully looks up remote for provided name', () {
|
||||||
final remote = repo.remotes['origin'];
|
final remote = repo.lookupRemote('origin');
|
||||||
|
|
||||||
expect(remote.name, remoteName);
|
expect(remote.name, remoteName);
|
||||||
expect(remote.url, remoteUrl);
|
expect(remote.url, remoteUrl);
|
||||||
|
@ -35,11 +35,11 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('throws when provided name for lookup is not found', () {
|
test('throws when provided name for lookup is not found', () {
|
||||||
expect(() => repo.remotes['upstream'], throwsA(isA<LibGit2Error>()));
|
expect(() => repo.lookupRemote('upstream'), throwsA(isA<LibGit2Error>()));
|
||||||
});
|
});
|
||||||
|
|
||||||
test('successfully creates without fetchspec', () {
|
test('successfully creates without fetchspec', () {
|
||||||
final remote = repo.remotes.create(name: 'upstream', url: remoteUrl);
|
final remote = repo.createRemote(name: 'upstream', url: remoteUrl);
|
||||||
|
|
||||||
expect(repo.remotes.length, 2);
|
expect(repo.remotes.length, 2);
|
||||||
expect(remote.name, 'upstream');
|
expect(remote.name, 'upstream');
|
||||||
|
@ -51,7 +51,7 @@ void main() {
|
||||||
|
|
||||||
test('successfully creates with provided fetchspec', () {
|
test('successfully creates with provided fetchspec', () {
|
||||||
const spec = '+refs/*:refs/*';
|
const spec = '+refs/*:refs/*';
|
||||||
final remote = repo.remotes.create(
|
final remote = repo.createRemote(
|
||||||
name: 'upstream',
|
name: 'upstream',
|
||||||
url: remoteUrl,
|
url: remoteUrl,
|
||||||
fetch: spec,
|
fetch: spec,
|
||||||
|
@ -67,23 +67,23 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('successfully deletes', () {
|
test('successfully deletes', () {
|
||||||
final remote = repo.remotes.create(name: 'upstream', url: remoteUrl);
|
final remote = repo.createRemote(name: 'upstream', url: remoteUrl);
|
||||||
expect(repo.remotes.length, 2);
|
expect(repo.remotes.length, 2);
|
||||||
|
|
||||||
repo.remotes.delete(remote.name);
|
repo.deleteRemote(remote.name);
|
||||||
expect(repo.remotes.length, 1);
|
expect(repo.remotes.length, 1);
|
||||||
|
|
||||||
remote.free();
|
remote.free();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('successfully renames', () {
|
test('successfully renames', () {
|
||||||
final remote = repo.remotes[remoteName];
|
final remote = repo.lookupRemote(remoteName);
|
||||||
|
|
||||||
final problems = repo.remotes.rename(remote: remoteName, newName: 'new');
|
final problems = repo.renameRemote(oldName: remoteName, newName: 'new');
|
||||||
expect(problems, isEmpty);
|
expect(problems, isEmpty);
|
||||||
expect(remote.name, isNot('new'));
|
expect(remote.name, isNot('new'));
|
||||||
|
|
||||||
final newRemote = repo.remotes['new'];
|
final newRemote = repo.lookupRemote('new');
|
||||||
expect(newRemote.name, 'new');
|
expect(newRemote.name, 'new');
|
||||||
|
|
||||||
newRemote.free();
|
newRemote.free();
|
||||||
|
@ -92,19 +92,19 @@ void main() {
|
||||||
|
|
||||||
test('throws when renaming with invalid names', () {
|
test('throws when renaming with invalid names', () {
|
||||||
expect(
|
expect(
|
||||||
() => repo.remotes.rename(remote: '', newName: ''),
|
() => repo.renameRemote(oldName: '', newName: ''),
|
||||||
throwsA(isA<LibGit2Error>()),
|
throwsA(isA<LibGit2Error>()),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('successfully sets url', () {
|
test('successfully sets url', () {
|
||||||
final remote = repo.remotes[remoteName];
|
final remote = repo.lookupRemote(remoteName);
|
||||||
expect(remote.url, remoteUrl);
|
expect(remote.url, remoteUrl);
|
||||||
|
|
||||||
const newUrl = 'git://new/url.git';
|
const newUrl = 'git://new/url.git';
|
||||||
repo.remotes.setUrl(remote: remoteName, url: newUrl);
|
Remote.setUrl(repo: repo, remote: remoteName, url: newUrl);
|
||||||
|
|
||||||
final newRemote = repo.remotes[remoteName];
|
final newRemote = repo.lookupRemote(remoteName);
|
||||||
expect(newRemote.url, newUrl);
|
expect(newRemote.url, newUrl);
|
||||||
|
|
||||||
newRemote.free();
|
newRemote.free();
|
||||||
|
@ -113,16 +113,16 @@ void main() {
|
||||||
|
|
||||||
test('throws when trying to set invalid url name', () {
|
test('throws when trying to set invalid url name', () {
|
||||||
expect(
|
expect(
|
||||||
() => repo.remotes.setUrl(remote: 'origin', url: ''),
|
() => Remote.setUrl(repo: repo, remote: 'origin', url: ''),
|
||||||
throwsA(isA<LibGit2Error>()),
|
throwsA(isA<LibGit2Error>()),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('successfully sets url for pushing', () {
|
test('successfully sets url for pushing', () {
|
||||||
const newUrl = 'git://new/url.git';
|
const newUrl = 'git://new/url.git';
|
||||||
repo.remotes.setPushUrl(remote: remoteName, url: newUrl);
|
Remote.setPushUrl(repo: repo, remote: remoteName, url: newUrl);
|
||||||
|
|
||||||
final remote = repo.remotes[remoteName];
|
final remote = repo.lookupRemote(remoteName);
|
||||||
expect(remote.pushUrl, newUrl);
|
expect(remote.pushUrl, newUrl);
|
||||||
|
|
||||||
remote.free();
|
remote.free();
|
||||||
|
@ -130,13 +130,13 @@ void main() {
|
||||||
|
|
||||||
test('throws when trying to set invalid push url name', () {
|
test('throws when trying to set invalid push url name', () {
|
||||||
expect(
|
expect(
|
||||||
() => repo.remotes.setPushUrl(remote: 'origin', url: ''),
|
() => Remote.setPushUrl(repo: repo, remote: 'origin', url: ''),
|
||||||
throwsA(isA<LibGit2Error>()),
|
throwsA(isA<LibGit2Error>()),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('returns refspec', () {
|
test('returns refspec', () {
|
||||||
final remote = repo.remotes['origin'];
|
final remote = repo.lookupRemote('origin');
|
||||||
expect(remote.refspecCount, 1);
|
expect(remote.refspecCount, 1);
|
||||||
|
|
||||||
final refspec = remote.getRefspec(0);
|
final refspec = remote.getRefspec(0);
|
||||||
|
@ -162,11 +162,12 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('successfully adds fetch refspec', () {
|
test('successfully adds fetch refspec', () {
|
||||||
repo.remotes.addFetch(
|
Remote.addFetch(
|
||||||
|
repo: repo,
|
||||||
remote: 'origin',
|
remote: 'origin',
|
||||||
refspec: '+refs/test/*:refs/test/remotes/*',
|
refspec: '+refs/test/*:refs/test/remotes/*',
|
||||||
);
|
);
|
||||||
final remote = repo.remotes['origin'];
|
final remote = repo.lookupRemote('origin');
|
||||||
expect(remote.fetchRefspecs.length, 2);
|
expect(remote.fetchRefspecs.length, 2);
|
||||||
expect(
|
expect(
|
||||||
remote.fetchRefspecs,
|
remote.fetchRefspecs,
|
||||||
|
@ -180,11 +181,12 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('successfully adds push refspec', () {
|
test('successfully adds push refspec', () {
|
||||||
repo.remotes.addPush(
|
Remote.addPush(
|
||||||
|
repo: repo,
|
||||||
remote: 'origin',
|
remote: 'origin',
|
||||||
refspec: '+refs/test/*:refs/test/remotes/*',
|
refspec: '+refs/test/*:refs/test/remotes/*',
|
||||||
);
|
);
|
||||||
final remote = repo.remotes['origin'];
|
final remote = repo.lookupRemote('origin');
|
||||||
expect(remote.pushRefspecs.length, 1);
|
expect(remote.pushRefspecs.length, 1);
|
||||||
expect(remote.pushRefspecs, ['+refs/test/*:refs/test/remotes/*']);
|
expect(remote.pushRefspecs, ['+refs/test/*:refs/test/remotes/*']);
|
||||||
|
|
||||||
|
@ -192,11 +194,12 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('successfully returns remote repo\'s reference list', () {
|
test('successfully returns remote repo\'s reference list', () {
|
||||||
repo.remotes.setUrl(
|
Remote.setUrl(
|
||||||
|
repo: repo,
|
||||||
remote: 'libgit2',
|
remote: 'libgit2',
|
||||||
url: 'https://github.com/libgit2/TestGitRepository',
|
url: 'https://github.com/libgit2/TestGitRepository',
|
||||||
);
|
);
|
||||||
final remote = repo.remotes['libgit2'];
|
final remote = repo.lookupRemote('libgit2');
|
||||||
|
|
||||||
final refs = remote.ls();
|
final refs = remote.ls();
|
||||||
expect(refs.first['local'], false);
|
expect(refs.first['local'], false);
|
||||||
|
@ -212,11 +215,12 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('successfully fetches data', () {
|
test('successfully fetches data', () {
|
||||||
repo.remotes.setUrl(
|
Remote.setUrl(
|
||||||
|
repo: repo,
|
||||||
remote: 'libgit2',
|
remote: 'libgit2',
|
||||||
url: 'https://github.com/libgit2/TestGitRepository',
|
url: 'https://github.com/libgit2/TestGitRepository',
|
||||||
);
|
);
|
||||||
final remote = repo.remotes['libgit2'];
|
final remote = repo.lookupRemote('libgit2');
|
||||||
|
|
||||||
final stats = remote.fetch();
|
final stats = remote.fetch();
|
||||||
|
|
||||||
|
@ -233,11 +237,12 @@ void main() {
|
||||||
|
|
||||||
test('successfully fetches data with provided transfer progress callback',
|
test('successfully fetches data with provided transfer progress callback',
|
||||||
() {
|
() {
|
||||||
repo.remotes.setUrl(
|
Remote.setUrl(
|
||||||
|
repo: repo,
|
||||||
remote: 'libgit2',
|
remote: 'libgit2',
|
||||||
url: 'https://github.com/libgit2/TestGitRepository',
|
url: 'https://github.com/libgit2/TestGitRepository',
|
||||||
);
|
);
|
||||||
final remote = repo.remotes['libgit2'];
|
final remote = repo.lookupRemote('libgit2');
|
||||||
|
|
||||||
TransferProgress? callbackStats;
|
TransferProgress? callbackStats;
|
||||||
void tp(TransferProgress stats) => callbackStats = stats;
|
void tp(TransferProgress stats) => callbackStats = stats;
|
||||||
|
@ -263,11 +268,12 @@ Enumerating objects: 69, done.
|
||||||
Counting objects: 100% (1/1)\rCounting objects: 100% (1/1), done.
|
Counting objects: 100% (1/1)\rCounting objects: 100% (1/1), done.
|
||||||
Total 69 (delta 0), reused 1 (delta 0), pack-reused 68
|
Total 69 (delta 0), reused 1 (delta 0), pack-reused 68
|
||||||
""";
|
""";
|
||||||
repo.remotes.setUrl(
|
Remote.setUrl(
|
||||||
|
repo: repo,
|
||||||
remote: 'libgit2',
|
remote: 'libgit2',
|
||||||
url: 'https://github.com/libgit2/TestGitRepository',
|
url: 'https://github.com/libgit2/TestGitRepository',
|
||||||
);
|
);
|
||||||
final remote = repo.remotes['libgit2'];
|
final remote = repo.lookupRemote('libgit2');
|
||||||
|
|
||||||
var sidebandOutput = StringBuffer();
|
var sidebandOutput = StringBuffer();
|
||||||
void sideband(String message) {
|
void sideband(String message) {
|
||||||
|
@ -283,11 +289,12 @@ Total 69 (delta 0), reused 1 (delta 0), pack-reused 68
|
||||||
});
|
});
|
||||||
|
|
||||||
test('successfully fetches data with provided update tips callback', () {
|
test('successfully fetches data with provided update tips callback', () {
|
||||||
repo.remotes.setUrl(
|
Remote.setUrl(
|
||||||
|
repo: repo,
|
||||||
remote: 'libgit2',
|
remote: 'libgit2',
|
||||||
url: 'https://github.com/libgit2/TestGitRepository',
|
url: 'https://github.com/libgit2/TestGitRepository',
|
||||||
);
|
);
|
||||||
final remote = repo.remotes['libgit2'];
|
final remote = repo.lookupRemote('libgit2');
|
||||||
const tipsExpected = [
|
const tipsExpected = [
|
||||||
{
|
{
|
||||||
'refname': 'refs/tags/annotated_tag',
|
'refname': 'refs/tags/annotated_tag',
|
||||||
|
@ -323,21 +330,22 @@ Total 69 (delta 0), reused 1 (delta 0), pack-reused 68
|
||||||
remote.free();
|
remote.free();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('successfully pushes with update reference callback', () async {
|
test('successfully pushes with update reference callback', () {
|
||||||
final originDir =
|
final originDir =
|
||||||
Directory('${Directory.systemTemp.path}/origin_testrepo');
|
Directory('${Directory.systemTemp.path}/origin_testrepo');
|
||||||
|
|
||||||
if (await originDir.exists()) {
|
if (originDir.existsSync()) {
|
||||||
await originDir.delete(recursive: true);
|
originDir.deleteSync(recursive: true);
|
||||||
}
|
}
|
||||||
await copyRepo(
|
originDir.createSync();
|
||||||
|
copyRepo(
|
||||||
from: Directory('test/assets/empty_bare.git/'),
|
from: Directory('test/assets/empty_bare.git/'),
|
||||||
to: await originDir.create(),
|
to: originDir,
|
||||||
);
|
);
|
||||||
final originRepo = Repository.open(originDir.path);
|
final originRepo = Repository.open(originDir.path);
|
||||||
|
|
||||||
repo.remotes.create(name: 'local', url: originDir.path);
|
repo.createRemote(name: 'local', url: originDir.path);
|
||||||
final remote = repo.remotes['local'];
|
final remote = repo.lookupRemote('local');
|
||||||
|
|
||||||
var updateRefOutput = <String, String>{};
|
var updateRefOutput = <String, String>{};
|
||||||
void updateRef(String refname, String message) {
|
void updateRef(String refname, String message) {
|
||||||
|
@ -348,7 +356,7 @@ Total 69 (delta 0), reused 1 (delta 0), pack-reused 68
|
||||||
|
|
||||||
remote.push(refspecs: ['refs/heads/master'], callbacks: callbacks);
|
remote.push(refspecs: ['refs/heads/master'], callbacks: callbacks);
|
||||||
expect(
|
expect(
|
||||||
(originRepo[originRepo.head.target.sha] as Commit).id.sha,
|
originRepo.lookupCommit(originRepo.head.target).id.sha,
|
||||||
'821ed6e80627b8769d170a293862f9fc60825226',
|
'821ed6e80627b8769d170a293862f9fc60825226',
|
||||||
);
|
);
|
||||||
expect(updateRefOutput, {'refs/heads/master': ''});
|
expect(updateRefOutput, {'refs/heads/master': ''});
|
||||||
|
|
|
@ -8,20 +8,19 @@ void main() {
|
||||||
late Directory tmpDir;
|
late Directory tmpDir;
|
||||||
final cloneDir = Directory('${Directory.systemTemp.path}/cloned');
|
final cloneDir = Directory('${Directory.systemTemp.path}/cloned');
|
||||||
|
|
||||||
setUp(() async {
|
setUp(() {
|
||||||
tmpDir = await setupRepo(Directory('test/assets/testrepo/'));
|
tmpDir = setupRepo(Directory('test/assets/testrepo/'));
|
||||||
repo = Repository.open(tmpDir.path);
|
repo = Repository.open(tmpDir.path);
|
||||||
|
if (cloneDir.existsSync()) {
|
||||||
if (await cloneDir.exists()) {
|
|
||||||
cloneDir.delete(recursive: true);
|
cloneDir.delete(recursive: true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
tearDown(() async {
|
tearDown(() {
|
||||||
repo.free();
|
repo.free();
|
||||||
await tmpDir.delete(recursive: true);
|
tmpDir.deleteSync(recursive: true);
|
||||||
if (await cloneDir.exists()) {
|
if (cloneDir.existsSync()) {
|
||||||
cloneDir.delete(recursive: true);
|
cloneDir.deleteSync(recursive: true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -69,7 +68,7 @@ void main() {
|
||||||
|
|
||||||
test('successfully clones repository with provided remote callback', () {
|
test('successfully clones repository with provided remote callback', () {
|
||||||
Remote remote(Repository repo, String name, String url) =>
|
Remote remote(Repository repo, String name, String url) =>
|
||||||
repo.remotes.create(name: 'test', url: tmpDir.path);
|
repo.createRemote(name: 'test', url: tmpDir.path);
|
||||||
|
|
||||||
final clonedRepo = Repository.clone(
|
final clonedRepo = Repository.clone(
|
||||||
url: tmpDir.path,
|
url: tmpDir.path,
|
||||||
|
@ -79,15 +78,15 @@ void main() {
|
||||||
|
|
||||||
expect(clonedRepo.isEmpty, false);
|
expect(clonedRepo.isEmpty, false);
|
||||||
expect(clonedRepo.isBare, false);
|
expect(clonedRepo.isBare, false);
|
||||||
expect(clonedRepo.remotes.list, ['test']);
|
expect(clonedRepo.remotes, ['test']);
|
||||||
expect(clonedRepo.references.list, contains('refs/remotes/test/master'));
|
expect(clonedRepo.references, contains('refs/remotes/test/master'));
|
||||||
|
|
||||||
clonedRepo.free();
|
clonedRepo.free();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('throws when cloning repository with invalid remote callback', () {
|
test('throws when cloning repository with invalid remote callback', () {
|
||||||
Remote remote(Repository repo, String name, String url) =>
|
Remote remote(Repository repo, String name, String url) =>
|
||||||
repo.remotes.create(name: '', url: '');
|
repo.createRemote(name: '', url: '');
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
() => Repository.clone(
|
() => Repository.clone(
|
||||||
|
|
|
@ -6,17 +6,17 @@ void main() {
|
||||||
late Repository repo;
|
late Repository repo;
|
||||||
final initDir = Directory('${Directory.systemTemp.path}/init_repo');
|
final initDir = Directory('${Directory.systemTemp.path}/init_repo');
|
||||||
|
|
||||||
setUp(() async {
|
setUp(() {
|
||||||
if (await initDir.exists()) {
|
if (initDir.existsSync()) {
|
||||||
await initDir.delete(recursive: true);
|
initDir.deleteSync(recursive: true);
|
||||||
} else {
|
} else {
|
||||||
await initDir.create();
|
initDir.createSync();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
tearDown(() async {
|
tearDown(() {
|
||||||
repo.free();
|
repo.free();
|
||||||
await initDir.delete(recursive: true);
|
initDir.deleteSync(recursive: true);
|
||||||
});
|
});
|
||||||
group('Repository.init', () {
|
group('Repository.init', () {
|
||||||
test('successfully creates new bare repo at provided path', () {
|
test('successfully creates new bare repo at provided path', () {
|
||||||
|
@ -49,7 +49,7 @@ void main() {
|
||||||
File('${initDir.path}/.git/description').readAsStringSync(),
|
File('${initDir.path}/.git/description').readAsStringSync(),
|
||||||
'test repo',
|
'test repo',
|
||||||
);
|
);
|
||||||
expect(repo.remotes['origin'].url, 'test.url');
|
expect(repo.lookupRemote('origin').url, 'test.url');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,14 +9,14 @@ void main() {
|
||||||
const lastCommit = '821ed6e80627b8769d170a293862f9fc60825226';
|
const lastCommit = '821ed6e80627b8769d170a293862f9fc60825226';
|
||||||
const featureCommit = '5aecfa0fb97eadaac050ccb99f03c3fb65460ad4';
|
const featureCommit = '5aecfa0fb97eadaac050ccb99f03c3fb65460ad4';
|
||||||
|
|
||||||
setUp(() async {
|
setUp(() {
|
||||||
tmpDir = await setupRepo(Directory('test/assets/testrepo/'));
|
tmpDir = setupRepo(Directory('test/assets/testrepo/'));
|
||||||
repo = Repository.open(tmpDir.path);
|
repo = Repository.open(tmpDir.path);
|
||||||
});
|
});
|
||||||
|
|
||||||
tearDown(() async {
|
tearDown(() {
|
||||||
repo.free();
|
repo.free();
|
||||||
await tmpDir.delete(recursive: true);
|
tmpDir.deleteSync(recursive: true);
|
||||||
});
|
});
|
||||||
|
|
||||||
group('Repository', () {
|
group('Repository', () {
|
||||||
|
@ -125,7 +125,7 @@ void main() {
|
||||||
|
|
||||||
test('successfully creates new blob', () {
|
test('successfully creates new blob', () {
|
||||||
final oid = repo.createBlob(newBlobContent);
|
final oid = repo.createBlob(newBlobContent);
|
||||||
final newBlob = repo[oid.sha] as Blob;
|
final newBlob = repo.lookupBlob(oid);
|
||||||
|
|
||||||
expect(newBlob, isA<Blob>());
|
expect(newBlob, isA<Blob>());
|
||||||
|
|
||||||
|
@ -135,7 +135,7 @@ void main() {
|
||||||
test('successfully creates new blob from file at provided relative path',
|
test('successfully creates new blob from file at provided relative path',
|
||||||
() {
|
() {
|
||||||
final oid = repo.createBlobFromWorkdir('feature_file');
|
final oid = repo.createBlobFromWorkdir('feature_file');
|
||||||
final newBlob = repo[oid.sha] as Blob;
|
final newBlob = repo.lookupBlob(oid);
|
||||||
|
|
||||||
expect(newBlob, isA<Blob>());
|
expect(newBlob, isA<Blob>());
|
||||||
|
|
||||||
|
@ -146,7 +146,7 @@ void main() {
|
||||||
final outsideFile =
|
final outsideFile =
|
||||||
File('${Directory.current.absolute.path}/test/blob_test.dart');
|
File('${Directory.current.absolute.path}/test/blob_test.dart');
|
||||||
final oid = repo.createBlobFromDisk(outsideFile.path);
|
final oid = repo.createBlobFromDisk(outsideFile.path);
|
||||||
final newBlob = repo[oid.sha] as Blob;
|
final newBlob = repo.lookupBlob(oid);
|
||||||
|
|
||||||
expect(newBlob, isA<Blob>());
|
expect(newBlob, isA<Blob>());
|
||||||
|
|
||||||
|
@ -161,11 +161,10 @@ void main() {
|
||||||
time: 1234,
|
time: 1234,
|
||||||
);
|
);
|
||||||
const tagName = 'tag';
|
const tagName = 'tag';
|
||||||
const target = 'f17d0d48eae3aa08cecf29128a35e310c97b3521';
|
final target = repo['f17d0d48eae3aa08cecf29128a35e310c97b3521'];
|
||||||
const message = 'init tag\n';
|
const message = 'init tag\n';
|
||||||
|
|
||||||
final oid = Tag.create(
|
final oid = repo.createTag(
|
||||||
repo: repo,
|
|
||||||
tagName: tagName,
|
tagName: tagName,
|
||||||
target: target,
|
target: target,
|
||||||
targetType: GitObject.commit,
|
targetType: GitObject.commit,
|
||||||
|
@ -173,7 +172,7 @@ void main() {
|
||||||
message: message,
|
message: message,
|
||||||
);
|
);
|
||||||
|
|
||||||
final newTag = repo[oid.sha] as Tag;
|
final newTag = repo.lookupTag(oid);
|
||||||
final tagger = newTag.tagger;
|
final tagger = newTag.tagger;
|
||||||
final newTagTarget = newTag.target as Commit;
|
final newTagTarget = newTag.target as Commit;
|
||||||
|
|
||||||
|
@ -181,7 +180,7 @@ void main() {
|
||||||
expect(newTag.name, tagName);
|
expect(newTag.name, tagName);
|
||||||
expect(newTag.message, message);
|
expect(newTag.message, message);
|
||||||
expect(tagger, signature);
|
expect(tagger, signature);
|
||||||
expect(newTagTarget.id.sha, target);
|
expect(newTagTarget.id, target);
|
||||||
|
|
||||||
newTag.free();
|
newTag.free();
|
||||||
newTagTarget.free();
|
newTagTarget.free();
|
||||||
|
@ -252,8 +251,8 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('checks if commit is a descendant of another commit', () {
|
test('checks if commit is a descendant of another commit', () {
|
||||||
final commit1 = repo['821ed6e8'] as Commit;
|
final commit1 = repo.lookupCommit(repo['821ed6e8']);
|
||||||
final commit2 = repo['78b8bf12'] as Commit;
|
final commit2 = repo.lookupCommit(repo['78b8bf12']);
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
repo.descendantOf(
|
repo.descendantOf(
|
||||||
|
@ -284,8 +283,8 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('returns number of ahead behind commits', () {
|
test('returns number of ahead behind commits', () {
|
||||||
final commit1 = repo['821ed6e8'] as Commit;
|
final commit1 = repo.lookupCommit(repo['821ed6e8']);
|
||||||
final commit2 = repo['c68ff54a'] as Commit;
|
final commit2 = repo.lookupCommit(repo['c68ff54a']);
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
repo.aheadBehind(localSHA: commit1.id.sha, upstreamSHA: commit2.id.sha),
|
repo.aheadBehind(localSHA: commit1.id.sha, upstreamSHA: commit2.id.sha),
|
||||||
|
|
|
@ -9,15 +9,15 @@ void main() {
|
||||||
late File file;
|
late File file;
|
||||||
const sha = '6cbc22e509d72758ab4c8d9f287ea846b90c448b';
|
const sha = '6cbc22e509d72758ab4c8d9f287ea846b90c448b';
|
||||||
|
|
||||||
setUp(() async {
|
setUp(() {
|
||||||
tmpDir = await setupRepo(Directory('test/assets/testrepo/'));
|
tmpDir = setupRepo(Directory('test/assets/testrepo/'));
|
||||||
file = File('${tmpDir.path}/feature_file');
|
file = File('${tmpDir.path}/feature_file');
|
||||||
repo = Repository.open(tmpDir.path);
|
repo = Repository.open(tmpDir.path);
|
||||||
});
|
});
|
||||||
|
|
||||||
tearDown(() async {
|
tearDown(() {
|
||||||
repo.free();
|
repo.free();
|
||||||
await tmpDir.delete(recursive: true);
|
tmpDir.deleteSync(recursive: true);
|
||||||
});
|
});
|
||||||
|
|
||||||
group('Reset', () {
|
group('Reset', () {
|
||||||
|
|
|
@ -9,14 +9,14 @@ void main() {
|
||||||
const headSHA = '821ed6e80627b8769d170a293862f9fc60825226';
|
const headSHA = '821ed6e80627b8769d170a293862f9fc60825226';
|
||||||
const parentSHA = '78b8bf123e3952c970ae5c1ce0a3ea1d1336f6e8';
|
const parentSHA = '78b8bf123e3952c970ae5c1ce0a3ea1d1336f6e8';
|
||||||
|
|
||||||
setUp(() async {
|
setUp(() {
|
||||||
tmpDir = await setupRepo(Directory('test/assets/testrepo/'));
|
tmpDir = setupRepo(Directory('test/assets/testrepo/'));
|
||||||
repo = Repository.open(tmpDir.path);
|
repo = Repository.open(tmpDir.path);
|
||||||
});
|
});
|
||||||
|
|
||||||
tearDown(() async {
|
tearDown(() {
|
||||||
repo.free();
|
repo.free();
|
||||||
await tmpDir.delete(recursive: true);
|
tmpDir.deleteSync(recursive: true);
|
||||||
});
|
});
|
||||||
|
|
||||||
group('revParse', () {
|
group('revParse', () {
|
||||||
|
@ -36,7 +36,7 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('.ext() returns commit and reference', () {
|
test('.ext() returns commit and reference', () {
|
||||||
final masterRef = repo.references['refs/heads/master'];
|
final masterRef = repo.lookupReference('refs/heads/master');
|
||||||
var headParse = repo.revParseExt('master');
|
var headParse = repo.revParseExt('master');
|
||||||
|
|
||||||
expect(headParse.object.id.sha, headSHA);
|
expect(headParse.object.id.sha, headSHA);
|
||||||
|
@ -46,7 +46,7 @@ void main() {
|
||||||
headParse.object.free();
|
headParse.object.free();
|
||||||
headParse.reference?.free();
|
headParse.reference?.free();
|
||||||
|
|
||||||
final featureRef = repo.references['refs/heads/feature'];
|
final featureRef = repo.lookupReference('refs/heads/feature');
|
||||||
headParse = repo.revParseExt('feature');
|
headParse = repo.revParseExt('feature');
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
|
|
|
@ -14,14 +14,14 @@ void main() {
|
||||||
'f17d0d48eae3aa08cecf29128a35e310c97b3521',
|
'f17d0d48eae3aa08cecf29128a35e310c97b3521',
|
||||||
];
|
];
|
||||||
|
|
||||||
setUp(() async {
|
setUp(() {
|
||||||
tmpDir = await setupRepo(Directory('test/assets/testrepo/'));
|
tmpDir = setupRepo(Directory('test/assets/testrepo/'));
|
||||||
repo = Repository.open(tmpDir.path);
|
repo = Repository.open(tmpDir.path);
|
||||||
});
|
});
|
||||||
|
|
||||||
tearDown(() async {
|
tearDown(() {
|
||||||
repo.free();
|
repo.free();
|
||||||
await tmpDir.delete(recursive: true);
|
tmpDir.deleteSync(recursive: true);
|
||||||
});
|
});
|
||||||
|
|
||||||
group('RevWalk', () {
|
group('RevWalk', () {
|
||||||
|
|
|
@ -8,8 +8,8 @@ void main() {
|
||||||
late Directory tmpDir;
|
late Directory tmpDir;
|
||||||
late Signature stasher;
|
late Signature stasher;
|
||||||
|
|
||||||
setUp(() async {
|
setUp(() {
|
||||||
tmpDir = await setupRepo(Directory('test/assets/testrepo/'));
|
tmpDir = setupRepo(Directory('test/assets/testrepo/'));
|
||||||
repo = Repository.open(tmpDir.path);
|
repo = Repository.open(tmpDir.path);
|
||||||
stasher = Signature.create(
|
stasher = Signature.create(
|
||||||
name: 'Stasher',
|
name: 'Stasher',
|
||||||
|
@ -17,10 +17,10 @@ void main() {
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
tearDown(() async {
|
tearDown(() {
|
||||||
stasher.free();
|
stasher.free();
|
||||||
repo.free();
|
repo.free();
|
||||||
await tmpDir.delete(recursive: true);
|
tmpDir.deleteSync(recursive: true);
|
||||||
});
|
});
|
||||||
|
|
||||||
group('Stash', () {
|
group('Stash', () {
|
||||||
|
|
|
@ -10,14 +10,14 @@ void main() {
|
||||||
const submoduleUrl = 'https://github.com/libgit2/TestGitRepository';
|
const submoduleUrl = 'https://github.com/libgit2/TestGitRepository';
|
||||||
const submoduleHeadSha = '49322bb17d3acc9146f98c97d078513228bbf3c0';
|
const submoduleHeadSha = '49322bb17d3acc9146f98c97d078513228bbf3c0';
|
||||||
|
|
||||||
setUp(() async {
|
setUp(() {
|
||||||
tmpDir = await setupRepo(Directory('test/assets/submodulerepo/'));
|
tmpDir = setupRepo(Directory('test/assets/submodulerepo/'));
|
||||||
repo = Repository.open(tmpDir.path);
|
repo = Repository.open(tmpDir.path);
|
||||||
});
|
});
|
||||||
|
|
||||||
tearDown(() async {
|
tearDown(() {
|
||||||
repo.free();
|
repo.free();
|
||||||
await tmpDir.delete(recursive: true);
|
tmpDir.deleteSync(recursive: true);
|
||||||
});
|
});
|
||||||
|
|
||||||
group('Submodule', () {
|
group('Submodule', () {
|
||||||
|
|
|
@ -7,18 +7,19 @@ void main() {
|
||||||
late Repository repo;
|
late Repository repo;
|
||||||
late Tag tag;
|
late Tag tag;
|
||||||
late Directory tmpDir;
|
late Directory tmpDir;
|
||||||
const tagSHA = 'f0fdbf506397e9f58c59b88dfdd72778ec06cc0c';
|
late Oid tagID;
|
||||||
|
|
||||||
setUp(() async {
|
setUp(() {
|
||||||
tmpDir = await setupRepo(Directory('test/assets/testrepo/'));
|
tmpDir = setupRepo(Directory('test/assets/testrepo/'));
|
||||||
repo = Repository.open(tmpDir.path);
|
repo = Repository.open(tmpDir.path);
|
||||||
tag = Tag.lookup(repo: repo, sha: tagSHA);
|
tagID = repo['f0fdbf506397e9f58c59b88dfdd72778ec06cc0c'];
|
||||||
|
tag = repo.lookupTag(tagID);
|
||||||
});
|
});
|
||||||
|
|
||||||
tearDown(() async {
|
tearDown(() {
|
||||||
tag.free();
|
tag.free();
|
||||||
repo.free();
|
repo.free();
|
||||||
await tmpDir.delete(recursive: true);
|
tmpDir.deleteSync(recursive: true);
|
||||||
});
|
});
|
||||||
|
|
||||||
group('Tag', () {
|
group('Tag', () {
|
||||||
|
@ -36,7 +37,7 @@ void main() {
|
||||||
final target = tag.target as Commit;
|
final target = tag.target as Commit;
|
||||||
final tagger = tag.tagger;
|
final tagger = tag.tagger;
|
||||||
|
|
||||||
expect(tag.id.sha, tagSHA);
|
expect(tag.id, tagID);
|
||||||
expect(tag.name, 'v0.2');
|
expect(tag.name, 'v0.2');
|
||||||
expect(tag.message, 'annotated tag\n');
|
expect(tag.message, 'annotated tag\n');
|
||||||
expect(target.message, 'add subdirectory file\n');
|
expect(target.message, 'add subdirectory file\n');
|
||||||
|
@ -53,11 +54,10 @@ void main() {
|
||||||
time: 1234,
|
time: 1234,
|
||||||
);
|
);
|
||||||
const tagName = 'tag';
|
const tagName = 'tag';
|
||||||
final target = 'f17d0d48eae3aa08cecf29128a35e310c97b3521';
|
final target = repo['f17d0d48eae3aa08cecf29128a35e310c97b3521'];
|
||||||
const message = 'init tag\n';
|
const message = 'init tag\n';
|
||||||
|
|
||||||
final oid = Tag.create(
|
final oid = repo.createTag(
|
||||||
repo: repo,
|
|
||||||
tagName: tagName,
|
tagName: tagName,
|
||||||
target: target,
|
target: target,
|
||||||
targetType: GitObject.commit,
|
targetType: GitObject.commit,
|
||||||
|
@ -65,7 +65,7 @@ void main() {
|
||||||
message: message,
|
message: message,
|
||||||
);
|
);
|
||||||
|
|
||||||
final newTag = Tag.lookup(repo: repo, sha: oid.sha);
|
final newTag = repo.lookupTag(oid);
|
||||||
final tagger = newTag.tagger;
|
final tagger = newTag.tagger;
|
||||||
final newTagTarget = newTag.target as Commit;
|
final newTagTarget = newTag.target as Commit;
|
||||||
|
|
||||||
|
@ -73,7 +73,7 @@ void main() {
|
||||||
expect(newTag.name, tagName);
|
expect(newTag.name, tagName);
|
||||||
expect(newTag.message, message);
|
expect(newTag.message, message);
|
||||||
expect(tagger, signature);
|
expect(tagger, signature);
|
||||||
expect(newTagTarget.id.sha, target);
|
expect(newTagTarget.id, target);
|
||||||
|
|
||||||
newTag.free();
|
newTag.free();
|
||||||
newTagTarget.free();
|
newTagTarget.free();
|
||||||
|
@ -87,7 +87,7 @@ void main() {
|
||||||
test('successfully deletes tag', () {
|
test('successfully deletes tag', () {
|
||||||
expect(repo.tags, ['v0.1', 'v0.2']);
|
expect(repo.tags, ['v0.1', 'v0.2']);
|
||||||
|
|
||||||
tag.delete();
|
repo.deleteTag('v0.2');
|
||||||
expect(repo.tags, ['v0.1']);
|
expect(repo.tags, ['v0.1']);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -7,19 +7,20 @@ void main() {
|
||||||
late Repository repo;
|
late Repository repo;
|
||||||
late Tree tree;
|
late Tree tree;
|
||||||
late Directory tmpDir;
|
late Directory tmpDir;
|
||||||
const treeSHA = 'a8ae3dd59e6e1802c6f78e05e301bfd57c9f334f';
|
|
||||||
const fileSHA = '1377554ebea6f98a2c748183bc5a96852af12ac2';
|
const fileSHA = '1377554ebea6f98a2c748183bc5a96852af12ac2';
|
||||||
|
|
||||||
setUp(() async {
|
setUp(() {
|
||||||
tmpDir = await setupRepo(Directory('test/assets/testrepo/'));
|
tmpDir = setupRepo(Directory('test/assets/testrepo/'));
|
||||||
repo = Repository.open(tmpDir.path);
|
repo = Repository.open(tmpDir.path);
|
||||||
tree = Tree.lookup(repo: repo, sha: treeSHA);
|
tree = repo.lookupTree(
|
||||||
|
repo['a8ae3dd59e6e1802c6f78e05e301bfd57c9f334f'],
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
tearDown(() async {
|
tearDown(() {
|
||||||
tree.free();
|
tree.free();
|
||||||
repo.free();
|
repo.free();
|
||||||
await tmpDir.delete(recursive: true);
|
tmpDir.deleteSync(recursive: true);
|
||||||
});
|
});
|
||||||
|
|
||||||
group('Tree', () {
|
group('Tree', () {
|
||||||
|
@ -70,7 +71,7 @@ void main() {
|
||||||
oid: fileOid,
|
oid: fileOid,
|
||||||
filemode: GitFilemode.blob,
|
filemode: GitFilemode.blob,
|
||||||
);
|
);
|
||||||
final newTree = Tree.lookup(repo: repo, sha: builder.write().sha);
|
final newTree = repo.lookupTree(builder.write());
|
||||||
|
|
||||||
final entry = newTree['filename'];
|
final entry = newTree['filename'];
|
||||||
expect(newTree.length, 1);
|
expect(newTree.length, 1);
|
||||||
|
|
|
@ -7,18 +7,17 @@ void main() {
|
||||||
late Repository repo;
|
late Repository repo;
|
||||||
late Tree tree;
|
late Tree tree;
|
||||||
late Directory tmpDir;
|
late Directory tmpDir;
|
||||||
const treeSHA = 'a8ae3dd59e6e1802c6f78e05e301bfd57c9f334f';
|
|
||||||
|
|
||||||
setUp(() async {
|
setUp(() {
|
||||||
tmpDir = await setupRepo(Directory('test/assets/testrepo/'));
|
tmpDir = setupRepo(Directory('test/assets/testrepo/'));
|
||||||
repo = Repository.open(tmpDir.path);
|
repo = Repository.open(tmpDir.path);
|
||||||
tree = Tree.lookup(repo: repo, sha: treeSHA);
|
tree = repo.lookupTree(repo['a8ae3dd59e6e1802c6f78e05e301bfd57c9f334f']);
|
||||||
});
|
});
|
||||||
|
|
||||||
tearDown(() async {
|
tearDown(() {
|
||||||
tree.free();
|
tree.free();
|
||||||
repo.free();
|
repo.free();
|
||||||
await tmpDir.delete(recursive: true);
|
tmpDir.deleteSync(recursive: true);
|
||||||
});
|
});
|
||||||
|
|
||||||
group('TreeBuilder', () {
|
group('TreeBuilder', () {
|
||||||
|
@ -56,11 +55,13 @@ void main() {
|
||||||
expect(() => builder[entry.name], throwsA(isA<ArgumentError>()));
|
expect(() => builder[entry.name], throwsA(isA<ArgumentError>()));
|
||||||
|
|
||||||
builder.add(
|
builder.add(
|
||||||
filename: entry.name, oid: entry.id, filemode: entry.filemode);
|
filename: entry.name,
|
||||||
|
oid: entry.id,
|
||||||
|
filemode: entry.filemode,
|
||||||
|
);
|
||||||
expect(builder[entry.name].name, entry.name);
|
expect(builder[entry.name].name, entry.name);
|
||||||
|
|
||||||
builder.free();
|
builder.free();
|
||||||
entry.free();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('successfully removes an entry', () {
|
test('successfully removes an entry', () {
|
||||||
|
|
|
@ -7,91 +7,98 @@ void main() {
|
||||||
late Repository repo;
|
late Repository repo;
|
||||||
late Directory tmpDir;
|
late Directory tmpDir;
|
||||||
final worktreeDir = Directory('${Directory.systemTemp.path}/worktree');
|
final worktreeDir = Directory('${Directory.systemTemp.path}/worktree');
|
||||||
|
const worktreeName = 'worktree';
|
||||||
|
|
||||||
setUp(() async {
|
setUp(() {
|
||||||
if (await worktreeDir.exists()) {
|
if (worktreeDir.existsSync()) {
|
||||||
await worktreeDir.delete(recursive: true);
|
worktreeDir.deleteSync(recursive: true);
|
||||||
}
|
}
|
||||||
tmpDir = await setupRepo(Directory('test/assets/testrepo/'));
|
tmpDir = setupRepo(Directory('test/assets/testrepo/'));
|
||||||
repo = Repository.open(tmpDir.path);
|
repo = Repository.open(tmpDir.path);
|
||||||
});
|
});
|
||||||
|
|
||||||
tearDown(() async {
|
tearDown(() {
|
||||||
repo.free();
|
repo.free();
|
||||||
await tmpDir.delete(recursive: true);
|
tmpDir.deleteSync(recursive: true);
|
||||||
if (await worktreeDir.exists()) {
|
if (worktreeDir.existsSync()) {
|
||||||
await worktreeDir.delete(recursive: true);
|
worktreeDir.deleteSync(recursive: true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
group('Worktree', () {
|
group('Worktree', () {
|
||||||
test('successfully creates worktree at provided path', () {
|
test('successfully creates worktree at provided path', () {
|
||||||
const worktreeName = 'worktree';
|
expect(repo.worktrees, []);
|
||||||
expect(Worktree.list(repo), []);
|
|
||||||
|
|
||||||
final worktree = Worktree.create(
|
final worktree = repo.createWorktree(
|
||||||
repo: repo,
|
|
||||||
name: worktreeName,
|
name: worktreeName,
|
||||||
path: worktreeDir.path,
|
path: worktreeDir.path,
|
||||||
);
|
);
|
||||||
|
final lookedupWorktree = repo.lookupWorktree(worktreeName);
|
||||||
|
final branches = repo.branches;
|
||||||
|
|
||||||
expect(Worktree.list(repo), [worktreeName]);
|
expect(repo.worktrees, [worktreeName]);
|
||||||
expect(repo.branches.list(), contains(worktreeName));
|
expect(branches.any((branch) => branch.name == worktreeName), true);
|
||||||
expect(worktree.name, worktreeName);
|
expect(worktree.name, worktreeName);
|
||||||
|
expect(lookedupWorktree.name, worktreeName);
|
||||||
expect(worktree.path, worktreeDir.path);
|
expect(worktree.path, worktreeDir.path);
|
||||||
|
expect(lookedupWorktree.path, worktreeDir.path);
|
||||||
expect(File('${worktreeDir.path}/.git').existsSync(), true);
|
expect(File('${worktreeDir.path}/.git').existsSync(), true);
|
||||||
|
|
||||||
|
for (final branch in branches) {
|
||||||
|
branch.free();
|
||||||
|
}
|
||||||
|
lookedupWorktree.free();
|
||||||
worktree.free();
|
worktree.free();
|
||||||
});
|
});
|
||||||
|
|
||||||
test(
|
test(
|
||||||
'successfully creates worktree at provided path from provided reference',
|
'successfully creates worktree at provided path from provided reference',
|
||||||
() {
|
() {
|
||||||
const worktreeName = 'worktree';
|
|
||||||
final head = repo.revParseSingle('HEAD');
|
final head = repo.revParseSingle('HEAD');
|
||||||
final worktreeRef = repo.branches.create(name: 'v1', target: head);
|
final worktreeBranch = repo.createBranch(name: 'v1', target: head);
|
||||||
final worktreeBranch = repo.branches['v1'];
|
final ref = repo.lookupReference('refs/heads/v1');
|
||||||
expect(Worktree.list(repo), []);
|
expect(repo.worktrees, []);
|
||||||
|
|
||||||
final worktree = Worktree.create(
|
final worktree = repo.createWorktree(
|
||||||
repo: repo,
|
|
||||||
name: worktreeName,
|
name: worktreeName,
|
||||||
path: worktreeDir.path,
|
path: worktreeDir.path,
|
||||||
ref: worktreeRef,
|
ref: ref,
|
||||||
);
|
);
|
||||||
|
final branches = repo.branches;
|
||||||
|
|
||||||
expect(Worktree.list(repo), [worktreeName]);
|
expect(repo.worktrees, [worktreeName]);
|
||||||
expect(repo.branches.list(), contains('v1'));
|
expect(branches.any((branch) => branch.name == 'v1'), true);
|
||||||
expect(repo.branches.list(), isNot(contains(worktreeName)));
|
expect(branches.any((branch) => branch.name == worktreeName), false);
|
||||||
expect(worktreeBranch.isCheckedOut, true);
|
expect(worktreeBranch.isCheckedOut, true);
|
||||||
|
|
||||||
worktreeDir.deleteSync(recursive: true);
|
worktreeDir.deleteSync(recursive: true);
|
||||||
worktree.prune();
|
worktree.prune();
|
||||||
|
|
||||||
expect(Worktree.list(repo), []);
|
expect(repo.worktrees, []);
|
||||||
expect(worktreeBranch.isCheckedOut, false);
|
expect(worktreeBranch.isCheckedOut, false);
|
||||||
expect(repo.branches.list(), contains('v1'));
|
expect(branches.any((branch) => branch.name == 'v1'), true);
|
||||||
|
|
||||||
|
for (final branch in branches) {
|
||||||
|
branch.free();
|
||||||
|
}
|
||||||
worktreeBranch.free();
|
worktreeBranch.free();
|
||||||
worktreeRef.free();
|
ref.free();
|
||||||
head.free();
|
head.free();
|
||||||
worktree.free();
|
worktree.free();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('successfully prunes worktree', () {
|
test('successfully prunes worktree', () {
|
||||||
const worktreeName = 'worktree';
|
expect(repo.worktrees, []);
|
||||||
expect(Worktree.list(repo), []);
|
|
||||||
|
|
||||||
final worktree = Worktree.create(
|
final worktree = repo.createWorktree(
|
||||||
repo: repo,
|
|
||||||
name: worktreeName,
|
name: worktreeName,
|
||||||
path: worktreeDir.path,
|
path: worktreeDir.path,
|
||||||
);
|
);
|
||||||
expect(Worktree.list(repo), [worktreeName]);
|
expect(repo.worktrees, [worktreeName]);
|
||||||
|
|
||||||
worktreeDir.deleteSync(recursive: true);
|
worktreeDir.deleteSync(recursive: true);
|
||||||
worktree.prune();
|
worktree.prune();
|
||||||
expect(Worktree.list(repo), []);
|
expect(repo.worktrees, []);
|
||||||
|
|
||||||
worktree.free();
|
worktree.free();
|
||||||
});
|
});
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue