mirror of
https://github.com/SkinnyMind/libgit2dart.git
synced 2025-05-05 04:39:07 -04:00
feat(graph): add bindings and api
This commit is contained in:
parent
618b4e7f05
commit
0ed5e7c797
4 changed files with 143 additions and 2 deletions
53
lib/src/bindings/graph.dart
Normal file
53
lib/src/bindings/graph.dart
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
import 'dart:ffi';
|
||||||
|
import 'package:ffi/ffi.dart';
|
||||||
|
import 'libgit2_bindings.dart';
|
||||||
|
import '../error.dart';
|
||||||
|
import '../util.dart';
|
||||||
|
|
||||||
|
/// Determine if a commit is the descendant of another commit.
|
||||||
|
///
|
||||||
|
/// Note that a commit is not considered a descendant of itself, in contrast to
|
||||||
|
/// `git merge-base --is-ancestor`.
|
||||||
|
///
|
||||||
|
/// Throws a [LibGit2Error] if error occured.
|
||||||
|
bool descendantOf({
|
||||||
|
required Pointer<git_repository> repoPointer,
|
||||||
|
required Pointer<git_oid> commitPointer,
|
||||||
|
required Pointer<git_oid> ancestorPointer,
|
||||||
|
}) {
|
||||||
|
final result = libgit2.git_graph_descendant_of(
|
||||||
|
repoPointer,
|
||||||
|
commitPointer,
|
||||||
|
ancestorPointer,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (result < 0) {
|
||||||
|
throw LibGit2Error(libgit2.git_error_last());
|
||||||
|
} else {
|
||||||
|
return result == 1 ? true : false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Count the number of unique commits between two commit objects.
|
||||||
|
///
|
||||||
|
/// There is no need for branches containing the commits to have any upstream relationship,
|
||||||
|
/// but it helps to think of one as a branch and the other as its upstream, the ahead and
|
||||||
|
/// behind values will be what git would report for the branches.
|
||||||
|
List<int> aheadBehind({
|
||||||
|
required Pointer<git_repository> repoPointer,
|
||||||
|
required Pointer<git_oid> localPointer,
|
||||||
|
required Pointer<git_oid> upstreamPointer,
|
||||||
|
}) {
|
||||||
|
final ahead = calloc<Uint64>();
|
||||||
|
final behind = calloc<Uint64>();
|
||||||
|
|
||||||
|
libgit2.git_graph_ahead_behind(
|
||||||
|
ahead,
|
||||||
|
behind,
|
||||||
|
repoPointer,
|
||||||
|
localPointer,
|
||||||
|
upstreamPointer,
|
||||||
|
);
|
||||||
|
|
||||||
|
return [ahead.value, behind.value];
|
||||||
|
}
|
|
@ -1,7 +1,5 @@
|
||||||
import 'dart:ffi';
|
import 'dart:ffi';
|
||||||
import 'package:libgit2dart/libgit2dart.dart';
|
import 'package:libgit2dart/libgit2dart.dart';
|
||||||
import 'package:libgit2dart/src/git_types.dart';
|
|
||||||
|
|
||||||
import 'bindings/libgit2_bindings.dart';
|
import 'bindings/libgit2_bindings.dart';
|
||||||
import 'bindings/odb.dart' as bindings;
|
import 'bindings/odb.dart' as bindings;
|
||||||
import 'oid.dart';
|
import 'oid.dart';
|
||||||
|
|
|
@ -12,6 +12,7 @@ import 'bindings/reset.dart' as reset_bindings;
|
||||||
import 'bindings/diff.dart' as diff_bindings;
|
import 'bindings/diff.dart' as diff_bindings;
|
||||||
import 'bindings/stash.dart' as stash_bindings;
|
import 'bindings/stash.dart' as stash_bindings;
|
||||||
import 'bindings/attr.dart' as attr_bindings;
|
import 'bindings/attr.dart' as attr_bindings;
|
||||||
|
import 'bindings/graph.dart' as graph_bindings;
|
||||||
import 'branch.dart';
|
import 'branch.dart';
|
||||||
import 'commit.dart';
|
import 'commit.dart';
|
||||||
import 'config.dart';
|
import 'config.dart';
|
||||||
|
@ -1181,4 +1182,40 @@ class Repository {
|
||||||
force: force,
|
force: force,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Checks if a commit is the descendant of another commit.
|
||||||
|
///
|
||||||
|
/// Note that a commit is not considered a descendant of itself, in contrast to
|
||||||
|
/// `git merge-base --is-ancestor`.
|
||||||
|
///
|
||||||
|
/// Throws a [LibGit2Error] if error occured.
|
||||||
|
bool descendantOf({required String commitSHA, required String ancestorSHA}) {
|
||||||
|
final commit = Oid.fromSHA(repo: this, sha: commitSHA);
|
||||||
|
final ancestor = Oid.fromSHA(repo: this, sha: ancestorSHA);
|
||||||
|
|
||||||
|
return graph_bindings.descendantOf(
|
||||||
|
repoPointer: _repoPointer,
|
||||||
|
commitPointer: commit.pointer,
|
||||||
|
ancestorPointer: ancestor.pointer,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns list with the `ahead` and `behind` number of unique commits respectively.
|
||||||
|
///
|
||||||
|
/// There is no need for branches containing the commits to have any upstream relationship,
|
||||||
|
/// but it helps to think of one as a branch and the other as its upstream, the ahead and
|
||||||
|
/// behind values will be what git would report for the branches.
|
||||||
|
List<int> aheadBehind({
|
||||||
|
required String localSHA,
|
||||||
|
required String upstreamSHA,
|
||||||
|
}) {
|
||||||
|
final local = Oid.fromSHA(repo: this, sha: localSHA);
|
||||||
|
final upstream = Oid.fromSHA(repo: this, sha: upstreamSHA);
|
||||||
|
|
||||||
|
return graph_bindings.aheadBehind(
|
||||||
|
repoPointer: _repoPointer,
|
||||||
|
localPointer: local.pointer,
|
||||||
|
upstreamPointer: upstream.pointer,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -251,5 +251,58 @@ void main() {
|
||||||
expect(repo.getAttribute(path: 'file.jpg', name: 'text'), false);
|
expect(repo.getAttribute(path: 'file.jpg', name: 'text'), false);
|
||||||
expect(repo.getAttribute(path: 'file.sh', name: 'eol'), 'lf');
|
expect(repo.getAttribute(path: 'file.sh', name: 'eol'), 'lf');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('checks if commit is a descendant of another commit', () {
|
||||||
|
final commit1 = repo['821ed6e8'] as Commit;
|
||||||
|
final commit2 = repo['78b8bf12'] as Commit;
|
||||||
|
|
||||||
|
expect(
|
||||||
|
repo.descendantOf(
|
||||||
|
commitSHA: commit1.id.sha,
|
||||||
|
ancestorSHA: commit2.id.sha,
|
||||||
|
),
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(
|
||||||
|
repo.descendantOf(
|
||||||
|
commitSHA: commit1.id.sha,
|
||||||
|
ancestorSHA: commit1.id.sha,
|
||||||
|
),
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(
|
||||||
|
repo.descendantOf(
|
||||||
|
commitSHA: commit2.id.sha,
|
||||||
|
ancestorSHA: commit1.id.sha,
|
||||||
|
),
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
|
||||||
|
commit1.free();
|
||||||
|
commit2.free();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('returns number of ahead behind commits', () {
|
||||||
|
final commit1 = repo['821ed6e8'] as Commit;
|
||||||
|
final commit2 = repo['c68ff54a'] as Commit;
|
||||||
|
|
||||||
|
expect(
|
||||||
|
repo.aheadBehind(localSHA: commit1.id.sha, upstreamSHA: commit2.id.sha),
|
||||||
|
[4, 0],
|
||||||
|
);
|
||||||
|
expect(
|
||||||
|
repo.aheadBehind(localSHA: commit2.id.sha, upstreamSHA: commit1.id.sha),
|
||||||
|
[0, 4],
|
||||||
|
);
|
||||||
|
expect(
|
||||||
|
repo.aheadBehind(localSHA: commit1.id.sha, upstreamSHA: commit1.id.sha),
|
||||||
|
[0, 0],
|
||||||
|
);
|
||||||
|
|
||||||
|
commit1.free();
|
||||||
|
commit2.free();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue