Compare commits

...

34 commits

Author SHA1 Message Date
Aleksey Kulikov
b66662f33c chore: v1.2.2 2023-02-03 12:54:44 +03:00
Aleksey Kulikov
e1ca7e81a2 chore: remove coverage badge 2023-02-02 16:20:28 +03:00
Aleksey Kulikov
7c6060b02c
test(credentials): enable some of the previously disabled tests for Linux (#82) 2023-02-02 16:15:24 +03:00
Aleksey Kulikov
ed67a4e307
fix: lookup package in correct location of Dart/Flutter cached packages (#81) 2023-02-02 15:29:31 +03:00
Aleksey Kulikov
675872c3ef chore: v1.2.1 2022-12-24 19:09:16 +03:00
Aleksey Kulikov
fa946c5ce3
fix: use default location of Flutter's '.pub_cache' folder (#79) 2022-12-24 19:01:37 +03:00
Aleksey Kulikov
34d492a9b6 docs: update README with troubleshooting instructions for Windows 2022-11-22 15:27:25 +03:00
Aleksey Kulikov
ef9390d08b
chore: bump minimum dart and flutter versions (#76) 2022-09-16 16:45:31 +03:00
Dillon Nys
d55742d6d7
chore: Lookup library in system path (#75) 2022-08-10 19:43:28 +03:00
Aleksey Kulikov
07e83a1f41 chore: v1.2.0 2022-07-15 13:23:22 +03:00
Aleksey Kulikov
a41fc55099
feat: upgrade libgit2 to 1.5.0 (#74) 2022-07-15 13:10:42 +03:00
Aleksey Kulikov
016370625b style: stricter linting 2022-07-05 18:00:35 +03:00
Aleksey Kulikov
4a36922129
feat(reset): add ability to pass checkout options to reset(...) API method (#72) 2022-06-23 18:37:27 +03:00
Aleksey Kulikov
5f829dd1ca
feat(worktree): add ability to pass options to prune(...) API method (#71) 2022-06-18 11:54:46 +03:00
Aleksey Kulikov
2daadaa9a4
style: annotate declarations for internal use (#70) 2022-06-18 11:17:14 +03:00
Aleksey Kulikov
d71e00947e
feat(merge): add ability to pass options to fileFromIndex(...) API method (#69) 2022-06-17 15:40:19 +03:00
Aleksey Kulikov
aa073c531e
feat(index): add ability to pass options to addAll(...) API method (#68) 2022-06-17 14:52:46 +03:00
Aleksey Kulikov
d113af44b5
feat(commit): add ability to pass options to revert(...) and revertTo(...) API methods (#67)
- select parent to revert to for merge commits
- merge options
- checkout options
2022-06-17 12:43:54 +03:00
Aleksey Kulikov
75687c469c chore: upgrade dependencies 2022-06-17 10:16:43 +03:00
Aleksey Kulikov
aa74c46a12 chore: v1.1.2 2022-06-09 18:02:49 +03:00
Aleksey Kulikov
6be34fe9a0
fix: lookup library in Flutter's .pub_cache folder (#66) 2022-06-09 17:56:27 +03:00
Aleksey Kulikov
48e2240c73
feat(revwalk): add ability to limit number of commits to walk (#65) 2022-06-09 17:15:55 +03:00
Aleksey Kulikov
a708d54b0a chore: v1.1.1 2022-06-08 15:39:19 +03:00
Aleksey Kulikov
b0b8067203
fix: lookup library in correct locations (#64) 2022-06-08 15:31:27 +03:00
Aleksey Kulikov
5739de545b
feat(note): add ability to pass notes location (#63)
Add ability to pass optional notes location to `Note.list(...)` method (defaults to "refs/notes/commits").
2022-05-30 15:29:40 +03:00
Aleksey Kulikov
3d235f5ce4
refactor: use extensions (#62) 2022-05-30 13:58:08 +03:00
Aleksey Kulikov
4aea9a306a chore: v1.1.0 2022-05-25 13:22:15 +03:00
Aleksey Kulikov
ae2aef5e2e
refactor: use loops inside list literals (#60) 2022-05-25 12:16:40 +03:00
Aleksey Kulikov
c35d336a56
feat: add ability to get and set libgit2 global options (#59) 2022-05-24 16:07:57 +03:00
Aleksey Kulikov
3900ec92cc
chore: upgrade dependencies (#58) 2022-05-23 13:50:15 +03:00
Aleksey Kulikov
faddaa52e2
feat(reset): add ability to remove entries in index (#57) 2022-05-18 15:49:08 +03:00
Aleksey Kulikov
16c42b9b2d
feat(repository): add ability to compare Identity objects (#56) 2022-05-10 20:50:52 +03:00
Aleksey Kulikov
d231164775
feat(repository): add ability to compare objects (#55)
Add naive objects comparison based on repository path. Use with caution,
previously loaded into memory index, odb, etc. might be different.
2022-05-10 19:57:24 +03:00
Aleksey Kulikov
bad40bdb61
feat: add ability to compare objects (#54) 2022-05-10 16:18:55 +03:00
118 changed files with 5889 additions and 3748 deletions

View file

@ -19,7 +19,7 @@ jobs:
- uses: actions/checkout@v3.0.1
- uses: subosito/flutter-action@v2
with:
channel: master
channel: stable
- name: Install dependencies
run: flutter pub get
@ -47,7 +47,7 @@ jobs:
- uses: actions/checkout@v3.0.1
- uses: subosito/flutter-action@v2
with:
channel: master
channel: stable
- name: Install dependencies
run: flutter pub get

View file

@ -1,3 +1,61 @@
## 1.2.2
- fix: lookup package in correct location of Dart/Flutter cached packages
## 1.2.1
- fix: use default location of Flutter's '.pub_cache' folder
- docs: update README with troubleshooting instructions for Windows
- chore: bump minimum dart and flutter versions
- chore: Lookup library in system path (thanks @dnys1)
## 1.2.0
- feat: upgrade libgit2 to 1.5.0
- feat: add ability to pass checkout options to `reset(...)` API method
- feat: add ability to pass options to `prune(...)` Worktree API method
- feat: add ability to pass options to `Merge.fileFromIndex(...)` API method
- feat: add ability to pass options to `addAll(...)` Index API method
- feat: add ability to pass options to `revert(...)` and `revertTo(...)` Commit API methods:
- select parent to revert to for merge commits
- merge options
- checkout options
- chore: upgrade dependencies
## 1.1.2
- fix: lookup library in Flutter's .pub_cache folder
- feat: add ability to limit number of commits to walk in revision walk
## 1.1.1
- fix: lookup library in correct locations
- feat: add ability to pass optional notes location to `Note.list(...)` method
## 1.1.0
- feat: add ability to get and set libgit2 global options
- feat: upgrade Flutter version constraints to `>=3.0.0`
- feat: add ability to remove entries in index with `resetDefault(...)` method
- feat: add ability to compare objects (value based equality)
Note: comparison of Repository objects have naive implementation. Comparison is based on repository path, and previously loaded into memory index, odb, etc. might be different. Use with caution.
## 1.0.0
- Initial release.

View file

@ -1,7 +1,5 @@
# libgit2dart
![Coverage](coverage_badge.svg)
**Dart bindings to libgit2**
libgit2dart package provides ability to use [libgit2](https://github.com/libgit2/libgit2) in Dart/Flutter.
@ -49,13 +47,13 @@ print(Libgit2.version);
**Note**: The following steps only required if you are using package in Dart application (Flutter application will have libgit2 library bundled automatically when you build for release).
After compiling the application you should run:
After adding the package as dependency you should run:
```shell
dart run libgit2dart:setup
```
That'll copy the prebuilt libgit2 library for your platform into `.dart_tool/libgit2/<platform>/` which you'll need to add to the same folder as your executable.
That'll copy the prebuilt libgit2 library for your platform into `.dart_tool/libgit2/<platform>/` which you'll need to add to the same folder as your executable after compilation.
If you upgrade the version of libgit2dart package in your dependencies you should run the following commands to have the latest libgit2 library for your platform to provide with your application:
@ -665,6 +663,8 @@ Fork libgit2dart, improve libgit2dart, send a pull request.
### Troubleshooting
#### Linux:
If you are developing on Linux using non-Debian based distrib you might encounter these errors:
- Failed to load dynamic library: libpcre.so.3: cannot open shared object file: No such file or directory
@ -679,6 +679,16 @@ sudo ln -s /usr/lib64/libpcre.so /usr/lib64/libpcre.so.3
sudo ln -s /usr/lib64/libpcreposix.so /usr/lib64/libpcreposix.so.3
```
#### Windows:
If you are developing on Windows you might encounter:
- Failed to load dynamic library: error code 126
That happens because libgit2 dynamic library bundled with libgit2dart package is precompiled with ssh support, and it fails to find the `libssh2.dll`.
To fix that error you should [build](https://github.com/libssh2/libssh2/blob/master/docs/INSTALL_CMAKE.md) libssh2, and place resulting `libssh2.dll` somewhere in system path (e.g. "Windows\System32").
### Ffigen
To generate bindings with ffigen use (adjust paths to yours):
@ -693,7 +703,6 @@ To run all tests and generate coverage report make sure to have activated packag
```sh
$ dart pub global activate coverage
$ dart pub global activate flutter_coverage_badge
```
And run:

View file

@ -4,9 +4,11 @@ analyzer:
language:
strict-casts: true
strict-raw-types: true
strict-inference: true
exclude:
- lib/src/bindings/libgit2_bindings.dart
- lib/src/bindings/libgit2_opts_bindings.dart
linter:
rules:

View file

@ -1,48 +1,45 @@
import 'dart:io';
import 'package:args/command_runner.dart';
import 'package:cli_util/cli_logging.dart' show Ansi, Logger;
import 'package:libgit2dart/libgit2dart.dart';
import 'package:libgit2dart/src/libgit2.dart';
import 'package:libgit2dart/src/util.dart';
import 'package:path/path.dart' as path;
import 'package:pub_cache/pub_cache.dart';
/// Copies prebuilt libgit2 library from package in '.pub_cache' into correct
/// directory for [platform].
Future<void> copyLibrary(String platform) async {
final logger = Logger.standard();
final ansi = Ansi(Ansi.terminalSupportsAnsi);
if (File(path.join(Directory.current.path, libDir, platform, getLibName()))
.existsSync()) {
if (libgit2Version == Libgit2.version) {
logger.stdout('${ansi.green}libgit2 for $platform is already available.');
stdout.writeln('libgit2 for $platform is already available.');
} else {
logger.stdout(
'${ansi.red}libgit2 for $platform is outdated.\n'
stdout.writeln(
'libgit2 for $platform is outdated.\n'
'Please run following commands: \n'
'dart run libgit2dart:setup clean\n'
'dart run libgit2dart:setup\n\n',
);
}
} else {
final pubCache = PubCache();
final pubCacheDir =
pubCache.getLatestVersion('libgit2dart')!.resolve()!.location;
final libPath = checkCache();
final libName = getLibName();
logger.stdout('Copying libgit2 for $platform');
final destination = path.join(libDir, platform);
Directory(destination).createSync(recursive: true);
File(path.join(pubCacheDir.path, platform, libName)).copySync(
path.join(destination, libName),
);
stdout.writeln('Copying libgit2 for $platform');
if (libPath == null) {
stdout.writeln(
"Couldn't find libgit2dart package.\n"
"Make sure to run 'dart pub get' to resolve dependencies.",
);
} else {
final destination = path.join(libDir, platform);
Directory(destination).createSync(recursive: true);
File(path.join(libPath, platform, libName)).copySync(
path.join(destination, libName),
);
logger.stdout(
'${ansi.green}Done! libgit2 for $platform is now available!'
'${ansi.none}',
);
stdout.writeln('Done! libgit2 for $platform is now available!');
}
}
}
@ -55,9 +52,10 @@ class CleanCommand extends Command<void> {
@override
void run() {
final logger = Logger.standard();
logger.stdout('Cleaning...');
Directory(libDir).deleteSync(recursive: true);
stdout.writeln('Cleaning...');
if (Directory(libDir).existsSync()) {
Directory(libDir).deleteSync(recursive: true);
}
}
}

View file

@ -1,2 +1,2 @@
#!/bin/bash
dart test --coverage="coverage" --test-randomize-ordering-seed random && format_coverage --lcov --check-ignore --in=coverage --out=coverage/lcov.info --packages=.packages --report-on=lib && genhtml coverage/lcov.info -o coverage/ && dart pub global run flutter_coverage_badge
dart test --coverage=coverage --test-randomize-ordering-seed random && dart pub global run coverage:format_coverage --lcov --check-ignore --in=coverage --out=coverage/lcov.info --report-on=lib && genhtml coverage/lcov.info -o coverage/

View file

@ -1,20 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="102" height="20">
<linearGradient id="b" x2="0" y2="100%">
<stop offset="0" stop-color="#bbb" stop-opacity=".1"/>
<stop offset="1" stop-opacity=".1"/>
</linearGradient>
<clipPath id="a">
<rect width="102" height="20" rx="3" fill="#fff"/>
</clipPath>
<g clip-path="url(#a)">
<path fill="#555" d="M0 0h59v20H0z"/>
<path fill="#44cc11" d="M59 0h43v20H59z"/>
<path fill="url(#b)" d="M0 0h102v20H0z"/>
</g>
<g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="110">
<text x="305" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="490">coverage</text>
<text x="305" y="140" transform="scale(.1)" textLength="490">coverage</text>
<text x="795" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="330">100%</text>
<text x="795" y="140" transform="scale(.1)" textLength="330">100%</text>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1 KiB

View file

@ -1,10 +1,13 @@
import 'dart:ffi';
import 'package:equatable/equatable.dart';
import 'package:libgit2dart/libgit2dart.dart';
import 'package:libgit2dart/src/bindings/annotated.dart' as bindings;
import 'package:libgit2dart/src/bindings/libgit2_bindings.dart';
import 'package:meta/meta.dart';
class AnnotatedCommit {
@immutable
class AnnotatedCommit extends Equatable {
/// Lookups an annotated commit from the given commit [oid].
///
/// It is preferable to use [AnnotatedCommit.fromReference] instead of this
@ -81,6 +84,7 @@ class AnnotatedCommit {
/// Pointer to pointer to memory address for allocated commit object.
///
/// Note: For internal use.
@internal
Pointer<git_annotated_commit> get pointer => _annotatedCommitPointer;
/// Commit oid that the given annotated commit refers to.
@ -96,6 +100,9 @@ class AnnotatedCommit {
bindings.free(_annotatedCommitPointer);
_finalizer.detach(this);
}
@override
List<Object?> get props => [oid];
}
// coverage:ignore-start

View file

@ -3,6 +3,7 @@ import 'dart:ffi';
import 'package:ffi/ffi.dart';
import 'package:libgit2dart/src/bindings/libgit2_bindings.dart';
import 'package:libgit2dart/src/error.dart';
import 'package:libgit2dart/src/extensions.dart';
import 'package:libgit2dart/src/util.dart';
/// Creates an annotated commit from the given commit id. The returned
@ -76,7 +77,7 @@ Pointer<git_annotated_commit> fromRevSpec({
required String revspec,
}) {
final out = calloc<Pointer<git_annotated_commit>>();
final revspecC = revspec.toNativeUtf8().cast<Int8>();
final revspecC = revspec.toChar();
final error = libgit2.git_annotated_commit_from_revspec(
out,
repoPointer,
@ -106,8 +107,8 @@ Pointer<git_annotated_commit> fromFetchHead({
required Pointer<git_oid> oid,
}) {
final out = calloc<Pointer<git_annotated_commit>>();
final branchNameC = branchName.toNativeUtf8().cast<Int8>();
final remoteUrlC = remoteUrl.toNativeUtf8().cast<Int8>();
final branchNameC = branchName.toChar();
final remoteUrlC = remoteUrl.toChar();
final error = libgit2.git_annotated_commit_from_fetchhead(
out,
repoPointer,
@ -136,7 +137,7 @@ Pointer<git_oid> oid(Pointer<git_annotated_commit> commit) =>
/// Get the refname that the given annotated commit refers to.
String refName(Pointer<git_annotated_commit> commit) {
final result = libgit2.git_annotated_commit_ref(commit);
return result == nullptr ? '' : result.cast<Utf8>().toDartString();
return result == nullptr ? '' : result.toDartString();
}
/// Frees an annotated commit.

View file

@ -1,6 +1,7 @@
import 'dart:ffi';
import 'package:ffi/ffi.dart';
import 'package:libgit2dart/src/bindings/libgit2_bindings.dart';
import 'package:libgit2dart/src/extensions.dart';
import 'package:libgit2dart/src/util.dart';
/// Look up the value of one git attribute for path.
@ -14,9 +15,9 @@ Object? getAttribute({
required String path,
required String name,
}) {
final out = calloc<Pointer<Int8>>();
final pathC = path.toNativeUtf8().cast<Int8>();
final nameC = name.toNativeUtf8().cast<Int8>();
final out = calloc<Pointer<Char>>();
final pathC = path.toChar();
final nameC = name.toChar();
libgit2.git_attr_get(out, repoPointer, flags, pathC, nameC);
final result = out.value;
@ -37,7 +38,7 @@ Object? getAttribute({
return false;
}
if (attributeValue == git_attr_value_t.GIT_ATTR_VALUE_STRING) {
return result.cast<Utf8>().toDartString();
return result.toDartString();
}
return null;
}

View file

@ -2,6 +2,7 @@ import 'dart:ffi';
import 'package:ffi/ffi.dart';
import 'package:libgit2dart/src/bindings/libgit2_bindings.dart';
import 'package:libgit2dart/src/error.dart';
import 'package:libgit2dart/src/extensions.dart';
import 'package:libgit2dart/src/oid.dart';
import 'package:libgit2dart/src/util.dart';
@ -20,7 +21,7 @@ Pointer<git_blame> file({
int? maxLine,
}) {
final out = calloc<Pointer<git_blame>>();
final pathC = path.toNativeUtf8().cast<Int8>();
final pathC = path.toChar();
final options = calloc<git_blame_options>();
libgit2.git_blame_options_init(options, GIT_BLAME_OPTIONS_VERSION);
@ -77,7 +78,7 @@ Pointer<git_blame> buffer({
required String buffer,
}) {
final out = calloc<Pointer<git_blame>>();
final bufferC = buffer.toNativeUtf8().cast<Int8>();
final bufferC = buffer.toChar();
final error = libgit2.git_blame_buffer(
out,
reference,

View file

@ -4,6 +4,7 @@ import 'package:ffi/ffi.dart';
import 'package:libgit2dart/src/bindings/libgit2_bindings.dart';
import 'package:libgit2dart/src/error.dart';
import 'package:libgit2dart/src/extensions.dart';
import 'package:libgit2dart/src/util.dart';
/// Lookup a blob object from a repository. The returned blob must be freed
@ -84,7 +85,7 @@ Pointer<git_oid> createFromWorkdir({
required String relativePath,
}) {
final out = calloc<git_oid>();
final relativePathC = relativePath.toNativeUtf8().cast<Int8>();
final relativePathC = relativePath.toChar();
final error = libgit2.git_blob_create_from_workdir(
out,
repoPointer,
@ -110,7 +111,7 @@ Pointer<git_oid> createFromDisk({
required String path,
}) {
final out = calloc<git_oid>();
final pathC = path.toNativeUtf8().cast<Int8>();
final pathC = path.toChar();
final error = libgit2.git_blob_create_from_disk(out, repoPointer, pathC);
calloc.free(pathC);
@ -150,7 +151,7 @@ String filterContent({
git_oid? attributesCommit,
}) {
final out = calloc<git_buf>();
final asPathC = asPath.toNativeUtf8().cast<Int8>();
final asPathC = asPath.toChar();
final opts = calloc<git_blob_filter_options>();
libgit2.git_blob_filter_options_init(opts, GIT_BLOB_FILTER_OPTIONS_VERSION);
opts.ref.flags = flags;
@ -162,7 +163,7 @@ String filterContent({
late final String result;
if (out.ref.ptr != nullptr) {
result = out.ref.ptr.cast<Utf8>().toDartString(length: out.ref.size);
result = out.ref.ptr.toDartString(length: out.ref.size);
}
libgit2.git_buf_dispose(out);

View file

@ -5,6 +5,7 @@ import 'package:libgit2dart/libgit2dart.dart';
import 'package:libgit2dart/src/bindings/libgit2_bindings.dart';
import 'package:libgit2dart/src/bindings/reference.dart' as reference_bindings;
import 'package:libgit2dart/src/error.dart';
import 'package:libgit2dart/src/extensions.dart';
import 'package:libgit2dart/src/util.dart';
/// Return a list of branches. The returned references must be freed with
@ -60,7 +61,7 @@ Pointer<git_reference> lookup({
required int branchType,
}) {
final out = calloc<Pointer<git_reference>>();
final branchNameC = branchName.toNativeUtf8().cast<Int8>();
final branchNameC = branchName.toChar();
final error = libgit2.git_branch_lookup(
out,
repoPointer,
@ -97,7 +98,7 @@ Pointer<git_reference> create({
required bool force,
}) {
final out = calloc<Pointer<git_reference>>();
final branchNameC = branchName.toNativeUtf8().cast<Int8>();
final branchNameC = branchName.toChar();
final forceC = force ? 1 : 0;
final error = libgit2.git_branch_create(
out,
@ -147,7 +148,7 @@ void rename({
required bool force,
}) {
final out = calloc<Pointer<git_reference>>();
final newBranchNameC = newBranchName.toNativeUtf8().cast<Int8>();
final newBranchNameC = newBranchName.toChar();
final forceC = force ? 1 : 0;
final error = libgit2.git_branch_move(
out,
@ -202,7 +203,7 @@ bool isCheckedOut(Pointer<git_reference> branch) {
///
/// Throws a [LibGit2Error] if error occured.
String name(Pointer<git_reference> ref) {
final out = calloc<Pointer<Int8>>();
final out = calloc<Pointer<Char>>();
final error = libgit2.git_branch_name(out, ref);
final result = out.value;
@ -212,7 +213,7 @@ String name(Pointer<git_reference> ref) {
if (error < 0) {
throw LibGit2Error(libgit2.git_error_last());
} else {
return result.cast<Utf8>().toDartString();
return result.toDartString();
}
}
@ -229,10 +230,10 @@ String remoteName({
required String branchName,
}) {
final out = calloc<git_buf>();
final branchNameC = branchName.toNativeUtf8().cast<Int8>();
final branchNameC = branchName.toChar();
final error = libgit2.git_branch_remote_name(out, repoPointer, branchNameC);
final result = out.ref.ptr.cast<Utf8>().toDartString(length: out.ref.size);
final result = out.ref.ptr.toDartString(length: out.ref.size);
libgit2.git_buf_dispose(out);
calloc.free(out);
@ -281,7 +282,7 @@ void setUpstream({
required Pointer<git_reference> branchPointer,
required String? branchName,
}) {
final branchNameC = branchName?.toNativeUtf8().cast<Int8>() ?? nullptr;
final branchNameC = branchName?.toChar() ?? nullptr;
final error = libgit2.git_branch_set_upstream(branchPointer, branchNameC);
calloc.free(branchNameC);
@ -303,10 +304,10 @@ String upstreamName({
required String branchName,
}) {
final out = calloc<git_buf>();
final branchNameC = branchName.toNativeUtf8().cast<Int8>();
final branchNameC = branchName.toChar();
final error = libgit2.git_branch_upstream_name(out, repoPointer, branchNameC);
final result = out.ref.ptr.cast<Utf8>().toDartString(length: out.ref.size);
final result = out.ref.ptr.toDartString(length: out.ref.size);
libgit2.git_buf_dispose(out);
calloc.free(out);
@ -330,14 +331,14 @@ String upstreamRemote({
required String branchName,
}) {
final out = calloc<git_buf>();
final branchNameC = branchName.toNativeUtf8().cast<Int8>();
final branchNameC = branchName.toChar();
final error = libgit2.git_branch_upstream_remote(
out,
repoPointer,
branchNameC,
);
final result = out.ref.ptr.cast<Utf8>().toDartString(length: out.ref.size);
final result = out.ref.ptr.toDartString(length: out.ref.size);
libgit2.git_buf_dispose(out);
calloc.free(out);
@ -361,14 +362,14 @@ String upstreamMerge({
required String branchName,
}) {
final out = calloc<git_buf>();
final branchNameC = branchName.toNativeUtf8().cast<Int8>();
final branchNameC = branchName.toChar();
final error = libgit2.git_branch_upstream_merge(
out,
repoPointer,
branchNameC,
);
final result = out.ref.ptr.cast<Utf8>().toDartString(length: out.ref.size);
final result = out.ref.ptr.toDartString(length: out.ref.size);
libgit2.git_buf_dispose(out);
calloc.free(out);

View file

@ -3,6 +3,7 @@ import 'dart:ffi';
import 'package:ffi/ffi.dart';
import 'package:libgit2dart/src/bindings/libgit2_bindings.dart';
import 'package:libgit2dart/src/error.dart';
import 'package:libgit2dart/src/extensions.dart';
import 'package:libgit2dart/src/util.dart';
/// Updates files in the index and the working tree to match the content of the
@ -127,13 +128,13 @@ List<Object> initOptions({
optsC.ref.checkout_strategy = strategy;
if (directory != null) {
optsC.ref.target_directory = directory.toNativeUtf8().cast<Int8>();
optsC.ref.target_directory = directory.toChar();
}
var pathPointers = <Pointer<Int8>>[];
Pointer<Pointer<Int8>> strArray = nullptr;
var pathPointers = <Pointer<Char>>[];
Pointer<Pointer<Char>> strArray = nullptr;
if (paths != null) {
pathPointers = paths.map((e) => e.toNativeUtf8().cast<Int8>()).toList();
pathPointers = paths.map((e) => e.toChar()).toList();
strArray = calloc(paths.length);
for (var i = 0; i < paths.length; i++) {
strArray[i] = pathPointers[i];

View file

@ -3,6 +3,7 @@ import 'dart:ffi';
import 'package:ffi/ffi.dart';
import 'package:libgit2dart/src/bindings/libgit2_bindings.dart';
import 'package:libgit2dart/src/error.dart';
import 'package:libgit2dart/src/extensions.dart';
import 'package:libgit2dart/src/util.dart';
/// Lookup a commit object from a repository. The returned commit must be
@ -45,10 +46,9 @@ Pointer<git_oid> create({
required List<Pointer<git_commit>> parents,
}) {
final out = calloc<git_oid>();
final updateRefC = updateRef.toNativeUtf8().cast<Int8>();
final messageEncodingC =
messageEncoding?.toNativeUtf8().cast<Int8>() ?? nullptr;
final messageC = message.toNativeUtf8().cast<Int8>();
final updateRefC = updateRef.toChar();
final messageEncodingC = messageEncoding?.toChar() ?? nullptr;
final messageC = message.toChar();
final parentsC = calloc<Pointer<git_commit>>(parentCount);
if (parents.isNotEmpty) {
@ -103,10 +103,9 @@ String createBuffer({
required List<Pointer<git_commit>> parents,
}) {
final out = calloc<git_buf>();
final updateRefC = updateRef.toNativeUtf8().cast<Int8>();
final messageEncodingC =
messageEncoding?.toNativeUtf8().cast<Int8>() ?? nullptr;
final messageC = message.toNativeUtf8().cast<Int8>();
final updateRefC = updateRef.toChar();
final messageEncodingC = messageEncoding?.toChar() ?? nullptr;
final messageC = message.toChar();
final parentsC = calloc<Pointer<git_commit>>(parentCount);
if (parents.isNotEmpty) {
@ -129,7 +128,7 @@ String createBuffer({
parentsC,
);
final result = out.ref.ptr.cast<Utf8>().toDartString(length: out.ref.size);
final result = out.ref.ptr.toDartString(length: out.ref.size);
libgit2.git_buf_dispose(out);
calloc.free(out);
@ -169,10 +168,9 @@ Pointer<git_oid> amend({
required Pointer<git_tree>? treePointer,
}) {
final out = calloc<git_oid>();
final updateRefC = updateRef?.toNativeUtf8().cast<Int8>() ?? nullptr;
final messageEncodingC =
messageEncoding?.toNativeUtf8().cast<Int8>() ?? nullptr;
final messageC = message?.toNativeUtf8().cast<Int8>() ?? nullptr;
final updateRefC = updateRef?.toChar() ?? nullptr;
final messageEncodingC = messageEncoding?.toChar() ?? nullptr;
final messageC = message?.toChar() ?? nullptr;
final error = libgit2.git_commit_amend(
out,
@ -216,7 +214,7 @@ Pointer<git_commit> duplicate(Pointer<git_commit> source) {
/// If the encoding header in the commit is missing UTF-8 is assumed.
String messageEncoding(Pointer<git_commit> commit) {
final result = libgit2.git_commit_message_encoding(commit);
return result == nullptr ? 'utf-8' : result.cast<Utf8>().toDartString();
return result == nullptr ? 'utf-8' : result.toDartString();
}
/// Get the full message of a commit.
@ -224,7 +222,7 @@ String messageEncoding(Pointer<git_commit> commit) {
/// The returned message will be slightly prettified by removing any potential
/// leading newlines.
String message(Pointer<git_commit> commit) {
return libgit2.git_commit_message(commit).cast<Utf8>().toDartString();
return libgit2.git_commit_message(commit).toDartString();
}
/// Get the short "summary" of the git commit message.
@ -239,7 +237,7 @@ String summary(Pointer<git_commit> commit) {
if (result == nullptr) {
throw LibGit2Error(libgit2.git_error_last());
} else {
return result.cast<Utf8>().toDartString();
return result.toDartString();
}
}
@ -250,7 +248,7 @@ String summary(Pointer<git_commit> commit) {
/// trimmed.
String body(Pointer<git_commit> commit) {
final result = libgit2.git_commit_body(commit);
return result == nullptr ? '' : result.cast<Utf8>().toDartString();
return result == nullptr ? '' : result.toDartString();
}
/// Get an arbitrary header field.
@ -261,10 +259,10 @@ String headerField({
required String field,
}) {
final out = calloc<git_buf>();
final fieldC = field.toNativeUtf8().cast<Int8>();
final fieldC = field.toChar();
final error = libgit2.git_commit_header_field(out, commitPointer, fieldC);
final result = out.ref.ptr.cast<Utf8>().toDartString(length: out.ref.size);
final result = out.ref.ptr.toDartString(length: out.ref.size);
libgit2.git_buf_dispose(out);
calloc.free(out);
@ -386,8 +384,48 @@ Pointer<git_tree> tree(Pointer<git_commit> commit) {
void revert({
required Pointer<git_repository> repoPointer,
required Pointer<git_commit> commitPointer,
required int mainline,
int? mergeFavor,
int? mergeFlags,
int? mergeFileFlags,
int? checkoutStrategy,
String? checkoutDirectory,
List<String>? checkoutPaths,
}) {
final error = libgit2.git_revert(repoPointer, commitPointer, nullptr);
final opts = calloc<git_revert_options>();
libgit2.git_revert_options_init(opts, GIT_REVERT_OPTIONS_VERSION);
opts.ref.mainline = mainline;
if (mergeFavor != null) opts.ref.merge_opts.file_favor = mergeFavor;
if (mergeFlags != null) opts.ref.merge_opts.flags = mergeFlags;
if (mergeFileFlags != null) opts.ref.merge_opts.file_flags = mergeFileFlags;
if (checkoutStrategy != null) {
opts.ref.checkout_opts.checkout_strategy = checkoutStrategy;
}
if (checkoutDirectory != null) {
opts.ref.checkout_opts.target_directory = checkoutDirectory.toChar();
}
var pathPointers = <Pointer<Char>>[];
Pointer<Pointer<Char>> strArray = nullptr;
if (checkoutPaths != null) {
pathPointers = checkoutPaths.map((e) => e.toChar()).toList();
strArray = calloc(checkoutPaths.length);
for (var i = 0; i < checkoutPaths.length; i++) {
strArray[i] = pathPointers[i];
}
opts.ref.checkout_opts.paths.strings = strArray;
opts.ref.checkout_opts.paths.count = checkoutPaths.length;
}
final error = libgit2.git_revert(repoPointer, commitPointer, opts);
for (final p in pathPointers) {
calloc.free(p);
}
calloc.free(strArray);
calloc.free(opts);
if (error < 0) {
throw LibGit2Error(libgit2.git_error_last());
@ -405,11 +443,18 @@ Pointer<git_index> revertCommit({
required Pointer<git_commit> revertCommitPointer,
required Pointer<git_commit> ourCommitPointer,
required int mainline,
int? mergeFavor,
int? mergeFlags,
int? mergeFileFlags,
}) {
final out = calloc<Pointer<git_index>>();
final opts = calloc<git_merge_options>();
libgit2.git_merge_options_init(opts, GIT_MERGE_OPTIONS_VERSION);
if (mergeFavor != null) opts.ref.file_favor = mergeFavor;
if (mergeFlags != null) opts.ref.flags = mergeFlags;
if (mergeFileFlags != null) opts.ref.file_flags = mergeFileFlags;
final error = libgit2.git_revert_commit(
out,
repoPointer,

View file

@ -5,13 +5,14 @@ import 'dart:ffi';
import 'package:ffi/ffi.dart';
import 'package:libgit2dart/src/bindings/libgit2_bindings.dart';
import 'package:libgit2dart/src/error.dart';
import 'package:libgit2dart/src/extensions.dart';
import 'package:libgit2dart/src/util.dart';
/// Create a new config instance containing a single on-disk file. The returned
/// config must be freed with [free].
Pointer<git_config> open(String path) {
final out = calloc<Pointer<git_config>>();
final pathC = path.toNativeUtf8().cast<Int8>();
final pathC = path.toChar();
libgit2.git_config_open_ondisk(out, pathC);
calloc.free(pathC);
@ -59,7 +60,7 @@ String findGlobal() {
final out = calloc<git_buf>();
final error = libgit2.git_config_find_global(out);
final result = out.ref.ptr.cast<Utf8>().toDartString(length: out.ref.size);
final result = out.ref.ptr.toDartString(length: out.ref.size);
libgit2.git_buf_dispose(out);
calloc.free(out);
@ -81,7 +82,7 @@ String findSystem() {
final out = calloc<git_buf>();
final error = libgit2.git_config_find_system(out);
final result = out.ref.ptr.cast<Utf8>().toDartString(length: out.ref.size);
final result = out.ref.ptr.toDartString(length: out.ref.size);
libgit2.git_buf_dispose(out);
calloc.free(out);
@ -107,7 +108,7 @@ String findXdg() {
final out = calloc<git_buf>();
final error = libgit2.git_config_find_xdg(out);
final result = out.ref.ptr.cast<Utf8>().toDartString(length: out.ref.size);
final result = out.ref.ptr.toDartString(length: out.ref.size);
libgit2.git_buf_dispose(out);
calloc.free(out);
@ -145,7 +146,7 @@ Pointer<git_config_entry> getEntry({
required String variable,
}) {
final out = calloc<Pointer<git_config_entry>>();
final nameC = variable.toNativeUtf8().cast<Int8>();
final nameC = variable.toChar();
final error = libgit2.git_config_get_entry(out, configPointer, nameC);
final result = out.value;
@ -167,7 +168,7 @@ void setBool({
required String variable,
required bool value,
}) {
final nameC = variable.toNativeUtf8().cast<Int8>();
final nameC = variable.toChar();
final valueC = value ? 1 : 0;
libgit2.git_config_set_bool(configPointer, nameC, valueC);
calloc.free(nameC);
@ -180,7 +181,7 @@ void setInt({
required String variable,
required int value,
}) {
final nameC = variable.toNativeUtf8().cast<Int8>();
final nameC = variable.toChar();
libgit2.git_config_set_int64(configPointer, nameC, value);
calloc.free(nameC);
}
@ -192,8 +193,8 @@ void setString({
required String variable,
required String value,
}) {
final nameC = variable.toNativeUtf8().cast<Int8>();
final valueC = value.toNativeUtf8().cast<Int8>();
final nameC = variable.toChar();
final valueC = value.toChar();
libgit2.git_config_set_string(configPointer, nameC, valueC);
calloc.free(nameC);
calloc.free(valueC);
@ -220,7 +221,7 @@ void delete({
required Pointer<git_config> configPointer,
required String variable,
}) {
final nameC = variable.toNativeUtf8().cast<Int8>();
final nameC = variable.toChar();
final error = libgit2.git_config_delete_entry(configPointer, nameC);
calloc.free(nameC);
@ -243,8 +244,8 @@ List<String> multivarValues({
required String variable,
String? regexp,
}) {
final nameC = variable.toNativeUtf8().cast<Int8>();
final regexpC = regexp?.toNativeUtf8().cast<Int8>() ?? nullptr;
final nameC = variable.toChar();
final regexpC = regexp?.toChar() ?? nullptr;
final iterator = calloc<Pointer<git_config_iterator>>();
final entry = calloc<Pointer<git_config_entry>>();
@ -261,7 +262,7 @@ List<String> multivarValues({
while (error == 0) {
error = libgit2.git_config_next(entry, iterator.value);
if (error != -31) {
entries.add(entry.value.ref.value.cast<Utf8>().toDartString());
entries.add(entry.value.ref.value.toDartString());
} else {
break;
}
@ -286,9 +287,9 @@ void setMultivar({
required String regexp,
required String value,
}) {
final nameC = variable.toNativeUtf8().cast<Int8>();
final regexpC = regexp.toNativeUtf8().cast<Int8>();
final valueC = value.toNativeUtf8().cast<Int8>();
final nameC = variable.toChar();
final regexpC = regexp.toChar();
final valueC = value.toChar();
libgit2.git_config_set_multivar(configPointer, nameC, regexpC, valueC);
@ -306,8 +307,8 @@ void deleteMultivar({
required String variable,
required String regexp,
}) {
final nameC = variable.toNativeUtf8().cast<Int8>();
final regexpC = regexp.toNativeUtf8().cast<Int8>();
final nameC = variable.toChar();
final regexpC = regexp.toChar();
libgit2.git_config_delete_multivar(configPointer, nameC, regexpC);

View file

@ -2,6 +2,7 @@ import 'dart:ffi';
import 'package:ffi/ffi.dart';
import 'package:libgit2dart/src/bindings/libgit2_bindings.dart';
import 'package:libgit2dart/src/extensions.dart';
import 'package:libgit2dart/src/util.dart';
/// Create a new plain-text username and password credential object.
@ -10,8 +11,8 @@ Pointer<git_credential> userPass({
required String password,
}) {
final out = calloc<Pointer<git_credential>>();
final usernameC = username.toNativeUtf8().cast<Int8>();
final passwordC = password.toNativeUtf8().cast<Int8>();
final usernameC = username.toChar();
final passwordC = password.toChar();
libgit2.git_credential_userpass_plaintext_new(out, usernameC, passwordC);
@ -32,10 +33,10 @@ Pointer<git_credential> sshKey({
required String passPhrase,
}) {
final out = calloc<Pointer<git_credential>>();
final usernameC = username.toNativeUtf8().cast<Int8>();
final publicKeyC = publicKey.toNativeUtf8().cast<Int8>();
final privateKeyC = privateKey.toNativeUtf8().cast<Int8>();
final passPhraseC = passPhrase.toNativeUtf8().cast<Int8>();
final usernameC = username.toChar();
final publicKeyC = publicKey.toChar();
final privateKeyC = privateKey.toChar();
final passPhraseC = passPhrase.toChar();
libgit2.git_credential_ssh_key_new(
out,
@ -59,7 +60,7 @@ Pointer<git_credential> sshKey({
/// Create a new ssh key credential object used for querying an ssh-agent.
Pointer<git_credential> sshKeyFromAgent(String username) {
final out = calloc<Pointer<git_credential>>();
final usernameC = username.toNativeUtf8().cast<Int8>();
final usernameC = username.toChar();
libgit2.git_credential_ssh_key_from_agent(out, usernameC);
@ -79,10 +80,10 @@ Pointer<git_credential> sshKeyFromMemory({
required String passPhrase,
}) {
final out = calloc<Pointer<git_credential>>();
final usernameC = username.toNativeUtf8().cast<Int8>();
final publicKeyC = publicKey.toNativeUtf8().cast<Int8>();
final privateKeyC = privateKey.toNativeUtf8().cast<Int8>();
final passPhraseC = passPhrase.toNativeUtf8().cast<Int8>();
final usernameC = username.toChar();
final publicKeyC = publicKey.toChar();
final privateKeyC = privateKey.toChar();
final passPhraseC = passPhrase.toChar();
libgit2.git_credential_ssh_key_memory_new(
out,

View file

@ -3,6 +3,7 @@ import 'dart:ffi';
import 'package:ffi/ffi.dart';
import 'package:libgit2dart/src/bindings/libgit2_bindings.dart';
import 'package:libgit2dart/src/error.dart';
import 'package:libgit2dart/src/extensions.dart';
import 'package:libgit2dart/src/util.dart';
/// Describe a commit. The returned describe result must be freed with [free].
@ -100,12 +101,12 @@ String format({
opts.ref.always_use_long_format = alwaysUseLongFormat ? 1 : 0;
}
if (dirtySuffix != null) {
opts.ref.dirty_suffix = dirtySuffix.toNativeUtf8().cast<Int8>();
opts.ref.dirty_suffix = dirtySuffix.toChar();
}
libgit2.git_describe_format(out, describeResultPointer, opts);
final result = out.ref.ptr.cast<Utf8>().toDartString(length: out.ref.size);
final result = out.ref.ptr.toDartString(length: out.ref.size);
libgit2.git_buf_dispose(out);
calloc.free(out);
@ -140,7 +141,7 @@ Pointer<git_describe_options> _initOpts({
opts.ref.describe_strategy = describeStrategy;
}
if (pattern != null) {
opts.ref.pattern = pattern.toNativeUtf8().cast<Int8>();
opts.ref.pattern = pattern.toChar();
}
if (onlyFollowFirstParent != null) {
opts.ref.only_follow_first_parent = onlyFollowFirstParent ? 1 : 0;

View file

@ -3,6 +3,7 @@ import 'dart:ffi';
import 'package:ffi/ffi.dart';
import 'package:libgit2dart/src/bindings/libgit2_bindings.dart';
import 'package:libgit2dart/src/error.dart';
import 'package:libgit2dart/src/extensions.dart';
import 'package:libgit2dart/src/util.dart';
/// Create a diff with the difference between two index objects. The returned
@ -253,7 +254,7 @@ void merge({
/// other types of patch files.
Pointer<git_diff> parse(String content) {
final out = calloc<Pointer<git_diff>>();
final contentC = content.toNativeUtf8().cast<Int8>();
final contentC = content.toChar();
libgit2.git_diff_from_buffer(out, contentC, content.length);
final result = out.value;
@ -383,7 +384,7 @@ String statsPrint({
final out = calloc<git_buf>();
final error = libgit2.git_diff_stats_to_buf(out, statsPointer, format, width);
final result = out.ref.ptr.cast<Utf8>().toDartString(length: out.ref.size);
final result = out.ref.ptr.toDartString(length: out.ref.size);
libgit2.git_buf_dispose(out);
calloc.free(out);
@ -402,7 +403,7 @@ String addToBuf(Pointer<git_diff> diff) {
final result = out.ref.ptr == nullptr
? ''
: out.ref.ptr.cast<Utf8>().toDartString(length: out.ref.size);
: out.ref.ptr.toDartString(length: out.ref.size);
libgit2.git_buf_dispose(out);
calloc.free(out);

View file

@ -33,8 +33,8 @@ List<int> aheadBehind({
required Pointer<git_oid> localPointer,
required Pointer<git_oid> upstreamPointer,
}) {
final ahead = calloc<Uint64>();
final behind = calloc<Uint64>();
final ahead = calloc<Size>();
final behind = calloc<Size>();
libgit2.git_graph_ahead_behind(
ahead,

View file

@ -3,6 +3,7 @@ import 'dart:ffi';
import 'package:ffi/ffi.dart';
import 'package:libgit2dart/src/bindings/libgit2_bindings.dart';
import 'package:libgit2dart/src/error.dart';
import 'package:libgit2dart/src/extensions.dart';
import 'package:libgit2dart/src/util.dart';
/// Create an in-memory index object.
@ -45,7 +46,7 @@ void setCapabilities({
/// Get the full path to the index file on disk.
String path(Pointer<git_index> index) {
return libgit2.git_index_path(index).cast<Utf8>().toDartString();
return libgit2.git_index_path(index).toDartString();
}
/// Update the contents of an existing index object in memory by reading from
@ -125,7 +126,7 @@ Pointer<git_oid> writeTreeTo({
/// Find the first position of any entries which point to given path in the Git
/// index.
bool find({required Pointer<git_index> indexPointer, required String path}) {
final pathC = path.toNativeUtf8().cast<Int8>();
final pathC = path.toChar();
final result = libgit2.git_index_find(nullptr, indexPointer, pathC);
calloc.free(pathC);
@ -164,7 +165,7 @@ Pointer<git_index_entry> getByPath({
required String path,
required int stage,
}) {
final pathC = path.toNativeUtf8().cast<Int8>();
final pathC = path.toChar();
final result = libgit2.git_index_get_bypath(indexPointer, pathC, stage);
calloc.free(pathC);
@ -231,7 +232,7 @@ void addByPath({
required Pointer<git_index> indexPointer,
required String path,
}) {
final pathC = path.toNativeUtf8().cast<Int8>();
final pathC = path.toChar();
final error = libgit2.git_index_add_bypath(indexPointer, pathC);
calloc.free(pathC);
@ -263,7 +264,7 @@ void addFromBuffer({
required Pointer<git_index_entry> entryPointer,
required String buffer,
}) {
final bufferC = buffer.toNativeUtf8().cast<Int8>();
final bufferC = buffer.toChar();
final error = libgit2.git_index_add_from_buffer(
indexPointer,
entryPointer,
@ -291,11 +292,11 @@ void addFromBuffer({
void addAll({
required Pointer<git_index> indexPointer,
required List<String> pathspec,
required int flags,
}) {
final pathspecC = calloc<git_strarray>();
final pathPointers =
pathspec.map((e) => e.toNativeUtf8().cast<Int8>()).toList();
final strArray = calloc<Pointer<Int8>>(pathspec.length);
final pathPointers = pathspec.map((e) => e.toChar()).toList();
final strArray = calloc<Pointer<Char>>(pathspec.length);
for (var i = 0; i < pathspec.length; i++) {
strArray[i] = pathPointers[i];
@ -307,7 +308,7 @@ void addAll({
final error = libgit2.git_index_add_all(
indexPointer,
pathspecC,
0,
flags,
nullptr,
nullptr,
);
@ -338,9 +339,8 @@ void updateAll({
required List<String> pathspec,
}) {
final pathspecC = calloc<git_strarray>();
final pathPointers =
pathspec.map((e) => e.toNativeUtf8().cast<Int8>()).toList();
final strArray = calloc<Pointer<Int8>>(pathspec.length);
final pathPointers = pathspec.map((e) => e.toChar()).toList();
final strArray = calloc<Pointer<Char>>(pathspec.length);
for (var i = 0; i < pathspec.length; i++) {
strArray[i] = pathPointers[i];
@ -379,7 +379,7 @@ void remove({
required String path,
required int stage,
}) {
final pathC = path.toNativeUtf8().cast<Int8>();
final pathC = path.toChar();
final error = libgit2.git_index_remove(indexPointer, pathC, stage);
calloc.free(pathC);
@ -395,7 +395,7 @@ void removeDirectory({
required String dir,
required int stage,
}) {
final dirC = dir.toNativeUtf8().cast<Int8>();
final dirC = dir.toChar();
libgit2.git_index_remove_directory(indexPointer, dirC, stage);
calloc.free(dirC);
}
@ -406,9 +406,8 @@ void removeAll({
required List<String> pathspec,
}) {
final pathspecC = calloc<git_strarray>();
final pathPointers =
pathspec.map((e) => e.toNativeUtf8().cast<Int8>()).toList();
final strArray = calloc<Pointer<Int8>>(pathspec.length);
final pathPointers = pathspec.map((e) => e.toChar()).toList();
final strArray = calloc<Pointer<Char>>(pathspec.length);
for (var i = 0; i < pathspec.length; i++) {
strArray[i] = pathPointers[i];
@ -511,7 +510,7 @@ void conflictRemove({
required Pointer<git_index> indexPointer,
required String path,
}) {
final pathC = path.toNativeUtf8().cast<Int8>();
final pathC = path.toChar();
final error = libgit2.git_index_conflict_remove(indexPointer, pathC);
calloc.free(pathC);

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,468 @@
// coverage:ignore-file
import 'dart:ffi' as ffi;
import 'package:libgit2dart/src/bindings/libgit2_bindings.dart';
/// Bindings to libgit2 global options
class Libgit2Opts {
/// Holds the symbol lookup function.
final ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
_lookup;
/// The symbols are looked up in [dynamicLibrary].
Libgit2Opts(ffi.DynamicLibrary dynamicLibrary)
: _lookup = dynamicLibrary.lookup;
/// Get the maximum mmap window size.
int git_libgit2_opts_get_mwindow_size(ffi.Pointer<ffi.Int> out) {
return _git_libgit2_opts_get_int(
git_libgit2_opt_t.GIT_OPT_GET_MWINDOW_SIZE,
out,
);
}
/// Set the maximum mmap window size.
int git_libgit2_opts_set_mwindow_size(int value) {
return _git_libgit2_opts_set_int(
git_libgit2_opt_t.GIT_OPT_SET_MWINDOW_SIZE,
value,
);
}
/// Get the maximum memory that will be mapped in total by the library.
///
/// The default (0) is unlimited.
int git_libgit2_opts_get_mwindow_mapped_limit(ffi.Pointer<ffi.Int> out) {
return _git_libgit2_opts_get_int(
git_libgit2_opt_t.GIT_OPT_GET_MWINDOW_MAPPED_LIMIT,
out,
);
}
/// Set the maximum amount of memory that can be mapped at any time by the
/// library.
int git_libgit2_opts_set_mwindow_mapped_limit(int value) {
return _git_libgit2_opts_set_int(
git_libgit2_opt_t.GIT_OPT_SET_MWINDOW_MAPPED_LIMIT,
value,
);
}
/// Get the maximum number of files that will be mapped at any time by the
/// library.
///
/// The default (0) is unlimited.
int git_libgit2_opts_get_mwindow_file_limit(ffi.Pointer<ffi.Int> out) {
return _git_libgit2_opts_get_int(
git_libgit2_opt_t.GIT_OPT_GET_MWINDOW_FILE_LIMIT,
out,
);
}
/// Set the maximum number of files that can be mapped at any time by the
/// library.
int git_libgit2_opts_set_mwindow_file_limit(int value) {
return _git_libgit2_opts_set_int(
git_libgit2_opt_t.GIT_OPT_SET_MWINDOW_FILE_LIMIT,
value,
);
}
/// Get the search path for a given level of config data.
///
/// [level] must be one of `GIT_CONFIG_LEVEL_SYSTEM`,
/// `GIT_CONFIG_LEVEL_GLOBAL`, `GIT_CONFIG_LEVEL_XDG`, or
/// `GIT_CONFIG_LEVEL_PROGRAMDATA`.
///
/// The search path is written to the [out] buffer.
int git_libgit2_opts_get_search_path(int level, ffi.Pointer<git_buf> out) {
return _git_libgit2_opts_get_search_path(
git_libgit2_opt_t.GIT_OPT_GET_SEARCH_PATH,
level,
out,
);
}
/// Set the search path for a level of config data. The search path applied
/// to shared attributes and ignore files, too.
///
/// [path] lists directories delimited by GIT_PATH_LIST_SEPARATOR.
/// Pass NULL to reset to the default (generally based on environment
/// variables). Use magic path `$PATH` to include the old value of the path
/// (if you want to prepend or append, for instance).
///
/// [level] must be one of `GIT_CONFIG_LEVEL_SYSTEM`,
/// `GIT_CONFIG_LEVEL_GLOBAL`, `GIT_CONFIG_LEVEL_XDG`, or
/// `GIT_CONFIG_LEVEL_PROGRAMDATA`.
int git_libgit2_opts_set_search_path(int level, ffi.Pointer<ffi.Char> path) {
return _git_libgit2_opts_set_search_path(
git_libgit2_opt_t.GIT_OPT_SET_SEARCH_PATH,
level,
path,
);
}
/// Set the maximum data size for the given [type] of object to be
/// considered eligible for caching in memory. Setting the [value] to
/// zero means that that type of object will not be cached.
///
/// Defaults to 0 for GIT_OBJECT_BLOB (i.e. won't cache blobs) and 4k
/// for GIT_OBJECT_COMMIT, GIT_OBJECT_TREE, and GIT_OBJECT_TAG.
int git_libgit2_opts_set_cache_object_limit(int type, int value) {
return _git_libgit2_opts_set_cache_object_limit(
git_libgit2_opt_t.GIT_OPT_SET_CACHE_OBJECT_LIMIT,
type,
value,
);
}
/// Set the maximum total data size that will be cached in memory
/// across all repositories before libgit2 starts evicting objects
/// from the cache. This is a soft limit, in that the library might
/// briefly exceed it, but will start aggressively evicting objects
/// from cache when that happens.
///
/// The default cache size is 256MB.
int git_libgit2_opts_set_cache_max_size(int bytes) {
return _git_libgit2_opts_set_int(
git_libgit2_opt_t.GIT_OPT_SET_CACHE_MAX_SIZE,
bytes,
);
}
/// Get the current bytes in cache and the maximum that would be
/// allowed in the cache.
int git_libgit2_opts_get_cached_memory(
ffi.Pointer<ffi.Int> current,
ffi.Pointer<ffi.Int> allowed,
) {
return _git_libgit2_opts_get_cached_memory(
git_libgit2_opt_t.GIT_OPT_GET_CACHED_MEMORY,
current,
allowed,
);
}
/// Enable or disable caching completely.
///
/// Because caches are repository-specific, disabling the cache
/// cannot immediately clear all cached objects, but each cache will
/// be cleared on the next attempt to update anything in it.
int git_libgit2_opts_enable_caching(int enabled) {
return _git_libgit2_opts_set_int(
git_libgit2_opt_t.GIT_OPT_ENABLE_CACHING,
enabled,
);
}
/// Get the default template path.
/// The path is written to the `out` buffer.
int git_libgit2_opts_get_template_path(ffi.Pointer<git_buf> out) {
return _git_libgit2_opts_get_buf(
git_libgit2_opt_t.GIT_OPT_GET_TEMPLATE_PATH,
out,
);
}
/// Set the default template [path].
int git_libgit2_opts_set_template_path(ffi.Pointer<ffi.Char> path) {
return _git_libgit2_opts_set_char(
git_libgit2_opt_t.GIT_OPT_SET_TEMPLATE_PATH,
path,
);
}
/// Set the SSL certificate-authority locations.
///
/// - [file] is the location of a file containing several
/// certificates concatenated together.
/// - [path] is the location of a directory holding several
/// certificates, one per file.
///
/// Either parameter may be `NULL`, but not both.
int git_libgit2_opts_set_ssl_cert_locations(
ffi.Pointer<ffi.Char> file,
ffi.Pointer<ffi.Char> path,
) {
return _git_libgit2_opts_set_ssl_cert_locations(
git_libgit2_opt_t.GIT_OPT_SET_SSL_CERT_LOCATIONS,
file,
path,
);
}
/// Get the value of the User-Agent header.
///
/// The User-Agent is written to the `out` buffer.
int git_libgit2_opts_get_user_agent(ffi.Pointer<git_buf> out) {
return _git_libgit2_opts_get_buf(
git_libgit2_opt_t.GIT_OPT_GET_USER_AGENT,
out,
);
}
/// Set the value of the User-Agent header. This value will be
/// appended to "git/1.0", for compatibility with other git clients.
///
/// - [user_agent] is the value that will be delivered as the
/// User-Agent header on HTTP requests.
int git_libgit2_opts_set_user_agent(ffi.Pointer<ffi.Char> user_agent) {
return _git_libgit2_opts_set_char(
git_libgit2_opt_t.GIT_OPT_SET_USER_AGENT,
user_agent,
);
}
/// Enable strict input validation when creating new objects
/// to ensure that all inputs to the new objects are valid.
///
/// For example, when this is enabled, the parent(s) and tree inputs
/// will be validated when creating a new commit.
///
/// This defaults to enabled.
int git_libgit2_opts_enable_strict_object_creation(int enabled) {
return _git_libgit2_opts_set_int(
git_libgit2_opt_t.GIT_OPT_ENABLE_STRICT_OBJECT_CREATION,
enabled,
);
}
/// Validate the target of a symbolic ref when creating it.
///
/// For example, `foobar` is not a valid ref, therefore `foobar` is
/// not a valid target for a symbolic ref by default, whereas
/// `refs/heads/foobar` is.
///
/// Disabling this bypasses validation so that an arbitrary strings
/// such as `foobar` can be used for a symbolic ref target.
///
/// This defaults to enabled.
int git_libgit2_opts_enable_strict_symbolic_ref_creation(int enabled) {
return _git_libgit2_opts_set_int(
git_libgit2_opt_t.GIT_OPT_ENABLE_STRICT_SYMBOLIC_REF_CREATION,
enabled,
);
}
/// Enable or disable the use of "offset deltas" when creating packfiles,
/// and the negotiation of them when talking to a remote server.
///
/// Offset deltas store a delta base location as an offset into the
/// packfile from the current location, which provides a shorter encoding
/// and thus smaller resultant packfiles.
///
/// Packfiles containing offset deltas can still be read.
///
/// This defaults to enabled.
int git_libgit2_opts_enable_offset_delta(int enabled) {
return _git_libgit2_opts_set_int(
git_libgit2_opt_t.GIT_OPT_ENABLE_OFS_DELTA,
enabled,
);
}
/// Enable synchronized writes of files in the gitdir using `fsync`
/// (or the platform equivalent) to ensure that new object data
/// is written to permanent storage, not simply cached.
///
/// This defaults to disabled.
int git_libgit2_opts_enable_fsync_gitdir(int enabled) {
return _git_libgit2_opts_set_int(
git_libgit2_opt_t.GIT_OPT_ENABLE_FSYNC_GITDIR,
enabled,
);
}
/// Enable strict verification of object hashsums when reading
/// objects from disk.
///
/// This may impact performance due to an additional checksum calculation
/// on each object.
///
/// This defaults to enabled.
int git_libgit2_opts_enable_strict_hash_verification(int enabled) {
return _git_libgit2_opts_set_int(
git_libgit2_opt_t.GIT_OPT_ENABLE_STRICT_HASH_VERIFICATION,
enabled,
);
}
/// Ensure that there are no unsaved changes in the index before
/// beginning any operation that reloads the index from disk (e.g.,
/// checkout).
///
/// If there are unsaved changes, the instruction will fail (using
/// the FORCE flag to checkout will still overwrite these changes).
int git_libgit2_opts_enable_unsaved_index_safety(int enabled) {
return _git_libgit2_opts_set_int(
git_libgit2_opt_t.GIT_OPT_ENABLE_UNSAVED_INDEX_SAFETY,
enabled,
);
}
/// Get the maximum number of objects libgit2 will allow in a pack
/// file when downloading a pack file from a remote. This can be
/// used to limit maximum memory usage when fetching from an untrusted
/// remote.
int git_libgit2_opts_get_pack_max_objects(ffi.Pointer<ffi.Int> out) {
return _git_libgit2_opts_get_int(
git_libgit2_opt_t.GIT_OPT_GET_PACK_MAX_OBJECTS,
out,
);
}
/// Set the maximum number of objects libgit2 will allow in a pack
/// file when downloading a pack file from a remote.
int git_libgit2_opts_set_pack_max_objects(int value) {
return _git_libgit2_opts_set_int(
git_libgit2_opt_t.GIT_OPT_SET_PACK_MAX_OBJECTS,
value,
);
}
/// This will cause .keep file existence checks to be skipped when
/// accessing packfiles, which can help performance with remote filesystems.
int git_libgit2_opts_disable_pack_keep_file_checks(int enabled) {
return _git_libgit2_opts_set_int(
git_libgit2_opt_t.GIT_OPT_DISABLE_PACK_KEEP_FILE_CHECKS,
enabled,
);
}
/// When connecting to a server using NTLM or Negotiate
/// authentication, use expect/continue when POSTing data.
///
/// This option is not available on Windows.
int git_libgit2_opts_enable_http_expect_continue(int enabled) {
return _git_libgit2_opts_set_int(
git_libgit2_opt_t.GIT_OPT_ENABLE_HTTP_EXPECT_CONTINUE,
enabled,
);
}
/// Gets the owner validation setting for repository directories.
int git_libgit2_opts_get_owner_validation(ffi.Pointer<ffi.Int> out) {
return _git_libgit2_opts_get_int(
git_libgit2_opt_t.GIT_OPT_GET_OWNER_VALIDATION,
out,
);
}
/// Set that repository directories should be owned by the current
/// user. The default is to validate ownership.
int git_libgit2_opts_set_owner_validation(int enabled) {
return _git_libgit2_opts_set_int(
git_libgit2_opt_t.GIT_OPT_SET_OWNER_VALIDATION,
enabled,
);
}
/// Returns the list of git extensions that are supported.
/// This is the list of built-in extensions supported by libgit2 and
/// custom extensions that have been added with [git_libgit2_opts_set_extensions].
///
/// Extensions that have been negated will not be returned.
int git_libgit2_opts_get_extensions(ffi.Pointer<git_strarray> out) {
return _git_libgit2_opts_get_extensions(
git_libgit2_opt_t.GIT_OPT_GET_EXTENSIONS,
out,
);
}
/// Set that the given git extensions are supported by the caller.
///
/// Extensions supported by libgit2 may be negated by prefixing
/// them with a `!`. For example: setting extensions to
/// { "!noop", "newext" } indicates that the caller does not want
/// to support repositories with the `noop` extension but does want
/// to support repositories with the `newext` extension.
int git_libgit2_opts_set_extensions(
ffi.Pointer<ffi.Pointer<ffi.Char>> extensions,
int len,
) {
return _git_libgit2_opts_set_extensions(
git_libgit2_opt_t.GIT_OPT_SET_EXTENSIONS,
extensions,
len,
);
}
late final _git_libgit2_opts_get_intPtr = _lookup<
ffi.NativeFunction<ffi.Int Function(ffi.Int, ffi.Pointer<ffi.Int>)>>(
'git_libgit2_opts');
late final _git_libgit2_opts_get_int = _git_libgit2_opts_get_intPtr
.asFunction<int Function(int, ffi.Pointer<ffi.Int>)>();
late final _git_libgit2_opts_set_intPtr =
_lookup<ffi.NativeFunction<ffi.Int Function(ffi.Int, ffi.Int)>>(
'git_libgit2_opts');
late final _git_libgit2_opts_set_int =
_git_libgit2_opts_set_intPtr.asFunction<int Function(int, int)>();
late final _git_libgit2_opts_get_bufPtr = _lookup<
ffi.NativeFunction<ffi.Int Function(ffi.Int, ffi.Pointer<git_buf>)>>(
'git_libgit2_opts');
late final _git_libgit2_opts_get_buf = _git_libgit2_opts_get_bufPtr
.asFunction<int Function(int, ffi.Pointer<git_buf>)>();
late final _git_libgit2_opts_set_charPtr = _lookup<
ffi.NativeFunction<ffi.Int Function(ffi.Int, ffi.Pointer<ffi.Char>)>>(
'git_libgit2_opts');
late final _git_libgit2_opts_set_char = _git_libgit2_opts_set_charPtr
.asFunction<int Function(int, ffi.Pointer<ffi.Char>)>();
late final _git_libgit2_opts_get_search_pathPtr = _lookup<
ffi.NativeFunction<
ffi.Int Function(
ffi.Int, ffi.Int, ffi.Pointer<git_buf>)>>('git_libgit2_opts');
late final _git_libgit2_opts_get_search_path =
_git_libgit2_opts_get_search_pathPtr
.asFunction<int Function(int, int, ffi.Pointer<git_buf>)>();
late final _git_libgit2_opts_set_search_pathPtr = _lookup<
ffi.NativeFunction<
ffi.Int Function(
ffi.Int, ffi.Int, ffi.Pointer<ffi.Char>)>>('git_libgit2_opts');
late final _git_libgit2_opts_set_search_path =
_git_libgit2_opts_set_search_pathPtr
.asFunction<int Function(int, int, ffi.Pointer<ffi.Char>)>();
late final _git_libgit2_opts_set_cache_object_limitPtr =
_lookup<ffi.NativeFunction<ffi.Int Function(ffi.Int, ffi.Int, ffi.Int)>>(
'git_libgit2_opts');
late final _git_libgit2_opts_set_cache_object_limit =
_git_libgit2_opts_set_cache_object_limitPtr
.asFunction<int Function(int, int, int)>();
late final _git_libgit2_opts_get_cached_memoryPtr = _lookup<
ffi.NativeFunction<
ffi.Int Function(ffi.Int, ffi.Pointer<ffi.Int>,
ffi.Pointer<ffi.Int>)>>('git_libgit2_opts');
late final _git_libgit2_opts_get_cached_memory =
_git_libgit2_opts_get_cached_memoryPtr.asFunction<
int Function(int, ffi.Pointer<ffi.Int>, ffi.Pointer<ffi.Int>)>();
late final _git_libgit2_opts_set_ssl_cert_locationsPtr = _lookup<
ffi.NativeFunction<
ffi.Int Function(ffi.Int, ffi.Pointer<ffi.Char>,
ffi.Pointer<ffi.Char>)>>('git_libgit2_opts');
late final _git_libgit2_opts_set_ssl_cert_locations =
_git_libgit2_opts_set_ssl_cert_locationsPtr.asFunction<
int Function(int, ffi.Pointer<ffi.Char>, ffi.Pointer<ffi.Char>)>();
late final _git_libgit2_opts_get_extensionsPtr = _lookup<
ffi.NativeFunction<
ffi.Int Function(
ffi.Int, ffi.Pointer<git_strarray>)>>('git_libgit2_opts');
late final _git_libgit2_opts_get_extensions =
_git_libgit2_opts_get_extensionsPtr
.asFunction<int Function(int, ffi.Pointer<git_strarray>)>();
late final _git_libgit2_opts_set_extensionsPtr = _lookup<
ffi.NativeFunction<
ffi.Int Function(ffi.Int, ffi.Pointer<ffi.Pointer<ffi.Char>>,
ffi.Int)>>('git_libgit2_opts');
late final _git_libgit2_opts_set_extensions =
_git_libgit2_opts_set_extensionsPtr.asFunction<
int Function(int, ffi.Pointer<ffi.Pointer<ffi.Char>>, int)>();
}

View file

@ -3,6 +3,7 @@ import 'dart:ffi';
import 'package:ffi/ffi.dart';
import 'package:libgit2dart/src/bindings/libgit2_bindings.dart';
import 'package:libgit2dart/src/error.dart';
import 'package:libgit2dart/src/extensions.dart';
import 'package:libgit2dart/src/util.dart';
/// Allocate a new mailmap object. The returned mailmap must be freed with
@ -25,7 +26,7 @@ Pointer<git_mailmap> init() {
/// returned mailmap must be freed with [free].
Pointer<git_mailmap> fromBuffer(String buffer) {
final out = calloc<Pointer<git_mailmap>>();
final bufferC = buffer.toNativeUtf8().cast<Int8>();
final bufferC = buffer.toChar();
libgit2.git_mailmap_from_buffer(out, bufferC, buffer.length);
@ -70,10 +71,10 @@ List<String> resolve({
required String name,
required String email,
}) {
final outRealName = calloc<Pointer<Int8>>();
final outRealEmail = calloc<Pointer<Int8>>();
final nameC = name.toNativeUtf8().cast<Int8>();
final emailC = email.toNativeUtf8().cast<Int8>();
final outRealName = calloc<Pointer<Char>>();
final outRealEmail = calloc<Pointer<Char>>();
final nameC = name.toChar();
final emailC = email.toChar();
libgit2.git_mailmap_resolve(
outRealName,
outRealEmail,
@ -82,8 +83,8 @@ List<String> resolve({
emailC,
);
final realName = outRealName.value.cast<Utf8>().toDartString();
final realEmail = outRealEmail.value.cast<Utf8>().toDartString();
final realName = outRealName.value.toDartString();
final realEmail = outRealEmail.value.toDartString();
calloc.free(outRealName);
calloc.free(outRealEmail);
calloc.free(nameC);
@ -119,10 +120,10 @@ void addEntry({
String? replaceName,
required String replaceEmail,
}) {
final realNameC = realName?.toNativeUtf8().cast<Int8>() ?? nullptr;
final realEmailC = realEmail?.toNativeUtf8().cast<Int8>() ?? nullptr;
final replaceNameC = replaceName?.toNativeUtf8().cast<Int8>() ?? nullptr;
final replaceEmailC = replaceEmail.toNativeUtf8().cast<Int8>();
final realNameC = realName?.toChar() ?? nullptr;
final realEmailC = realEmail?.toChar() ?? nullptr;
final replaceNameC = replaceName?.toChar() ?? nullptr;
final replaceEmailC = replaceEmail.toChar();
libgit2.git_mailmap_add_entry(
mailmapPointer,

View file

@ -3,6 +3,7 @@ import 'dart:ffi';
import 'package:ffi/ffi.dart';
import 'package:libgit2dart/src/bindings/libgit2_bindings.dart';
import 'package:libgit2dart/src/error.dart';
import 'package:libgit2dart/src/extensions.dart';
import 'package:libgit2dart/src/util.dart';
/// Find a merge base between two commits.
@ -183,35 +184,44 @@ String mergeFile({
libgit2.git_merge_file_input_init(ancestorC, GIT_MERGE_FILE_INPUT_VERSION);
libgit2.git_merge_file_input_init(oursC, GIT_MERGE_FILE_INPUT_VERSION);
libgit2.git_merge_file_input_init(theirsC, GIT_MERGE_FILE_INPUT_VERSION);
ancestorC.ref.ptr = ancestor.toNativeUtf8().cast<Int8>();
ancestorC.ref.ptr = ancestor.toChar();
ancestorC.ref.size = ancestor.length;
oursC.ref.ptr = ours.toNativeUtf8().cast<Int8>();
Pointer<Char> ancestorLabelC = nullptr;
oursC.ref.ptr = ours.toChar();
oursC.ref.size = ours.length;
theirsC.ref.ptr = theirs.toNativeUtf8().cast<Int8>();
Pointer<Char> oursLabelC = nullptr;
theirsC.ref.ptr = theirs.toChar();
theirsC.ref.size = theirs.length;
Pointer<Char> theirsLabelC = nullptr;
final opts = calloc<git_merge_file_options>();
libgit2.git_merge_file_options_init(opts, GIT_MERGE_FILE_OPTIONS_VERSION);
opts.ref.favor = favor;
opts.ref.flags = flags;
if (ancestorLabel.isNotEmpty) {
opts.ref.ancestor_label = ancestorLabel.toNativeUtf8().cast<Int8>();
ancestorLabelC = ancestorLabel.toChar();
opts.ref.ancestor_label = ancestorLabelC;
}
if (oursLabel.isNotEmpty) {
opts.ref.our_label = oursLabel.toNativeUtf8().cast<Int8>();
oursLabelC = oursLabel.toChar();
opts.ref.our_label = oursLabelC;
}
if (theirsLabel.isNotEmpty) {
opts.ref.their_label = theirsLabel.toNativeUtf8().cast<Int8>();
theirsLabelC = theirsLabel.toChar();
opts.ref.their_label = theirsLabelC;
}
libgit2.git_merge_file(out, ancestorC, oursC, theirsC, opts);
calloc.free(ancestorC);
calloc.free(ancestorLabelC);
calloc.free(oursC);
calloc.free(oursLabelC);
calloc.free(theirsC);
calloc.free(theirsLabelC);
calloc.free(opts);
final result = out.ref.ptr.cast<Utf8>().toDartString(length: out.ref.len);
final result = out.ref.ptr.toDartString(length: out.ref.len);
calloc.free(out);
return result;
@ -225,24 +235,54 @@ String mergeFile({
String mergeFileFromIndex({
required Pointer<git_repository> repoPointer,
required Pointer<git_index_entry>? ancestorPointer,
required String ancestorLabel,
required Pointer<git_index_entry> oursPointer,
required String oursLabel,
required Pointer<git_index_entry> theirsPointer,
required String theirsLabel,
required int favor,
required int flags,
}) {
final out = calloc<git_merge_file_result>();
final opts = calloc<git_merge_file_options>();
Pointer<Char> ancestorLabelC = nullptr;
Pointer<Char> oursLabelC = nullptr;
Pointer<Char> theirsLabelC = nullptr;
libgit2.git_merge_file_options_init(opts, GIT_MERGE_FILE_OPTIONS_VERSION);
opts.ref.favor = favor;
opts.ref.flags = flags;
if (ancestorLabel.isNotEmpty) {
ancestorLabelC = ancestorLabel.toChar();
opts.ref.ancestor_label = ancestorLabelC;
}
if (oursLabel.isNotEmpty) {
oursLabelC = oursLabel.toChar();
opts.ref.our_label = oursLabelC;
}
if (theirsLabel.isNotEmpty) {
theirsLabelC = theirsLabel.toChar();
opts.ref.their_label = theirsLabelC;
}
final error = libgit2.git_merge_file_from_index(
out,
repoPointer,
ancestorPointer ?? nullptr,
oursPointer,
theirsPointer,
nullptr,
opts,
);
late final String result;
if (out.ref.ptr != nullptr) {
result = out.ref.ptr.cast<Utf8>().toDartString(length: out.ref.len);
result = out.ref.ptr.toDartString(length: out.ref.len);
}
calloc.free(ancestorLabelC);
calloc.free(oursLabelC);
calloc.free(theirsLabelC);
calloc.free(opts);
calloc.free(out);
if (error < 0) {

View file

@ -3,16 +3,24 @@ import 'dart:ffi';
import 'package:ffi/ffi.dart';
import 'package:libgit2dart/src/bindings/libgit2_bindings.dart';
import 'package:libgit2dart/src/error.dart';
import 'package:libgit2dart/src/extensions.dart';
import 'package:libgit2dart/src/util.dart';
/// Returns list of notes for repository. The returned notes must be freed with
/// [free].
///
/// Throws a [LibGit2Error] if error occured.
List<Map<String, Pointer>> list(Pointer<git_repository> repo) {
final notesRef = 'refs/notes/commits'.toNativeUtf8().cast<Int8>();
List<Map<String, Pointer>> list({
required Pointer<git_repository> repoPointer,
required String notesRef,
}) {
final notesRefC = notesRef.toChar();
final iterator = calloc<Pointer<git_iterator>>();
final iteratorError = libgit2.git_note_iterator_new(iterator, repo, notesRef);
final iteratorError = libgit2.git_note_iterator_new(
iterator,
repoPointer,
notesRefC,
);
if (iteratorError < 0) {
calloc.free(iterator);
@ -28,7 +36,7 @@ List<Map<String, Pointer>> list(Pointer<git_repository> repo) {
nextError = libgit2.git_note_next(noteOid, annotatedOid, iterator.value);
if (nextError >= 0) {
final out = calloc<Pointer<git_note>>();
libgit2.git_note_read(out, repo, notesRef, annotatedOid);
libgit2.git_note_read(out, repoPointer, notesRefC, annotatedOid);
final note = out.value;
@ -41,7 +49,7 @@ List<Map<String, Pointer>> list(Pointer<git_repository> repo) {
calloc.free(noteOid);
}
calloc.free(notesRef);
calloc.free(notesRefC);
libgit2.git_note_iterator_free(iterator.value);
calloc.free(iterator);
@ -54,10 +62,10 @@ List<Map<String, Pointer>> list(Pointer<git_repository> repo) {
Pointer<git_note> lookup({
required Pointer<git_repository> repoPointer,
required Pointer<git_oid> oidPointer,
String notesRef = 'refs/notes/commits',
required String notesRef,
}) {
final out = calloc<Pointer<git_note>>();
final notesRefC = notesRef.toNativeUtf8().cast<Int8>();
final notesRefC = notesRef.toChar();
final error = libgit2.git_note_read(out, repoPointer, notesRefC, oidPointer);
final result = out.value;
@ -85,8 +93,8 @@ Pointer<git_oid> create({
bool force = false,
}) {
final out = calloc<git_oid>();
final notesRefC = notesRef.toNativeUtf8().cast<Int8>();
final noteC = note.toNativeUtf8().cast<Int8>();
final notesRefC = notesRef.toChar();
final noteC = note.toChar();
final forceC = force ? 1 : 0;
final error = libgit2.git_note_create(
out,
@ -120,7 +128,7 @@ void delete({
required Pointer<git_signature> committerPointer,
required Pointer<git_oid> oidPointer,
}) {
final notesRefC = notesRef.toNativeUtf8().cast<Int8>();
final notesRefC = notesRef.toChar();
final error = libgit2.git_note_remove(
repoPointer,
@ -142,7 +150,7 @@ Pointer<git_oid> id(Pointer<git_note> note) => libgit2.git_note_id(note);
/// Get the note message.
String message(Pointer<git_note> note) {
return libgit2.git_note_message(note).cast<Utf8>().toDartString();
return libgit2.git_note_message(note).toDartString();
}
/// Free memory allocated for note object.

View file

@ -4,6 +4,7 @@ import 'package:ffi/ffi.dart';
import 'package:libgit2dart/src/bindings/libgit2_bindings.dart';
import 'package:libgit2dart/src/bindings/oid.dart' as oid_bindings;
import 'package:libgit2dart/src/error.dart';
import 'package:libgit2dart/src/extensions.dart';
import 'package:libgit2dart/src/oid.dart';
import 'package:libgit2dart/src/util.dart';
@ -36,7 +37,7 @@ void addDiskAlternate({
required Pointer<git_odb> odbPointer,
required String path,
}) {
final pathC = path.toNativeUtf8().cast<Int8>();
final pathC = path.toChar();
libgit2.git_odb_add_disk_alternate(odbPointer, pathC);
calloc.free(pathC);
}
@ -94,7 +95,7 @@ int _forEachCb(
List<Oid> objects(Pointer<git_odb> odb) {
const except = -1;
final cb =
Pointer.fromFunction<Int32 Function(Pointer<git_oid>, Pointer<Void>)>(
Pointer.fromFunction<Int Function(Pointer<git_oid>, Pointer<Void>)>(
_forEachCb,
except,
);
@ -184,7 +185,7 @@ Pointer<git_oid> write({
throw LibGit2Error(libgit2.git_error_last());
}
final bufferC = data.toNativeUtf8().cast<Int8>();
final bufferC = data.toChar();
libgit2.git_odb_stream_write(stream.value, bufferC, data.length);
final out = calloc<git_oid>();

View file

@ -2,12 +2,13 @@ import 'dart:ffi';
import 'package:ffi/ffi.dart';
import 'package:libgit2dart/src/bindings/libgit2_bindings.dart';
import 'package:libgit2dart/src/extensions.dart';
import 'package:libgit2dart/src/util.dart';
/// Parse N characters of a hex formatted object id into a git_oid.
Pointer<git_oid> fromStrN(String hex) {
final out = calloc<git_oid>();
final hexC = hex.toNativeUtf8().cast<Int8>();
final hexC = hex.toChar();
libgit2.git_oid_fromstrn(out, hexC, hex.length);
calloc.free(hexC);
@ -18,7 +19,7 @@ Pointer<git_oid> fromStrN(String hex) {
/// Parse a hex formatted object id into a git_oid.
Pointer<git_oid> fromSHA(String hex) {
final out = calloc<git_oid>();
final hexC = hex.toNativeUtf8().cast<Int8>();
final hexC = hex.toChar();
libgit2.git_oid_fromstr(out, hexC);
calloc.free(hexC);
@ -27,9 +28,9 @@ Pointer<git_oid> fromSHA(String hex) {
}
/// Copy an already raw oid into a git_oid structure.
Pointer<git_oid> fromRaw(Array<Uint8> raw) {
Pointer<git_oid> fromRaw(Array<UnsignedChar> raw) {
final out = calloc<git_oid>();
final rawC = calloc<Uint8>(20);
final rawC = calloc<UnsignedChar>(20);
for (var i = 0; i < 20; i++) {
rawC[i] = raw[i];
@ -44,10 +45,10 @@ Pointer<git_oid> fromRaw(Array<Uint8> raw) {
/// Format a git_oid into a hex string.
String toSHA(Pointer<git_oid> id) {
final out = calloc<Int8>(40);
final out = calloc<Char>(40);
libgit2.git_oid_fmt(out, id);
final result = out.cast<Utf8>().toDartString(length: 40);
final result = out.toDartString(length: 40);
calloc.free(out);
return result;
}

View file

@ -3,6 +3,7 @@ import 'dart:ffi';
import 'package:ffi/ffi.dart';
import 'package:libgit2dart/src/bindings/libgit2_bindings.dart';
import 'package:libgit2dart/src/error.dart';
import 'package:libgit2dart/src/extensions.dart';
import 'package:libgit2dart/src/util.dart';
/// Initialize a new packbuilder. The returned packbuilder must be freed with
@ -121,7 +122,7 @@ void write({
required Pointer<git_packbuilder> packbuilderPointer,
String? path,
}) {
final pathC = path?.toNativeUtf8().cast<Int8>() ?? nullptr;
final pathC = path?.toChar() ?? nullptr;
final error = libgit2.git_packbuilder_write(
packbuilderPointer,
pathC,
@ -153,7 +154,7 @@ int writtenCount(Pointer<git_packbuilder> pb) {
/// correct after the packfile has been written.
String name(Pointer<git_packbuilder> pb) {
final result = libgit2.git_packbuilder_name(pb);
return result == nullptr ? '' : result.cast<Utf8>().toDartString();
return result == nullptr ? '' : result.toDartString();
}
/// Set number of threads to spawn.

View file

@ -3,6 +3,7 @@ import 'dart:ffi';
import 'package:ffi/ffi.dart';
import 'package:libgit2dart/src/bindings/libgit2_bindings.dart';
import 'package:libgit2dart/src/error.dart';
import 'package:libgit2dart/src/extensions.dart';
import 'package:libgit2dart/src/util.dart';
/// Directly generate a patch from the difference between two buffers. The
@ -17,11 +18,11 @@ Pointer<git_patch> fromBuffers({
required int interhunkLines,
}) {
final out = calloc<Pointer<git_patch>>();
final oldBufferC = oldBuffer?.toNativeUtf8().cast<Int8>() ?? nullptr;
final oldAsPathC = oldAsPath?.toNativeUtf8().cast<Int8>() ?? nullptr;
final oldBufferC = oldBuffer?.toChar() ?? nullptr;
final oldAsPathC = oldAsPath?.toChar() ?? nullptr;
final oldLen = oldBuffer?.length ?? 0;
final newBufferC = newBuffer?.toNativeUtf8().cast<Int8>() ?? nullptr;
final newAsPathC = oldAsPath?.toNativeUtf8().cast<Int8>() ?? nullptr;
final newBufferC = newBuffer?.toChar() ?? nullptr;
final newAsPathC = oldAsPath?.toChar() ?? nullptr;
final newLen = newBuffer?.length ?? 0;
final opts = _diffOptionsInit(
flags: flags,
@ -65,8 +66,8 @@ Pointer<git_patch> fromBlobs({
required int interhunkLines,
}) {
final out = calloc<Pointer<git_patch>>();
final oldAsPathC = oldAsPath?.toNativeUtf8().cast<Int8>() ?? nullptr;
final newAsPathC = oldAsPath?.toNativeUtf8().cast<Int8>() ?? nullptr;
final oldAsPathC = oldAsPath?.toChar() ?? nullptr;
final newAsPathC = oldAsPath?.toChar() ?? nullptr;
final opts = _diffOptionsInit(
flags: flags,
contextLines: contextLines,
@ -104,9 +105,9 @@ Pointer<git_patch> fromBlobAndBuffer({
required int interhunkLines,
}) {
final out = calloc<Pointer<git_patch>>();
final oldAsPathC = oldAsPath?.toNativeUtf8().cast<Int8>() ?? nullptr;
final bufferC = buffer?.toNativeUtf8().cast<Int8>() ?? nullptr;
final bufferAsPathC = oldAsPath?.toNativeUtf8().cast<Int8>() ?? nullptr;
final oldAsPathC = oldAsPath?.toChar() ?? nullptr;
final bufferC = buffer?.toChar() ?? nullptr;
final bufferAsPathC = oldAsPath?.toChar() ?? nullptr;
final bufferLen = buffer?.length ?? 0;
final opts = _diffOptionsInit(
flags: flags,
@ -175,8 +176,8 @@ Map<String, Object> hunk({
required int hunkIndex,
}) {
final out = calloc<Pointer<git_diff_hunk>>();
final linesInHunk = calloc<Int64>();
libgit2.git_patch_get_hunk(out, linesInHunk.cast(), patchPointer, hunkIndex);
final linesInHunk = calloc<Size>();
libgit2.git_patch_get_hunk(out, linesInHunk, patchPointer, hunkIndex);
final hunk = out.value;
final linesN = linesInHunk.value;
@ -189,9 +190,9 @@ Map<String, Object> hunk({
/// Get line counts of each type in a patch.
Map<String, int> lineStats(Pointer<git_patch> patch) {
final context = calloc<Uint64>();
final insertions = calloc<Uint64>();
final deletions = calloc<Uint64>();
final context = calloc<Size>();
final insertions = calloc<Size>();
final deletions = calloc<Size>();
libgit2.git_patch_line_stats(
context,
insertions,
@ -235,7 +236,7 @@ String text(Pointer<git_patch> patch) {
final out = calloc<git_buf>();
final error = libgit2.git_patch_to_buf(out, patch);
final result = out.ref.ptr.cast<Utf8>().toDartString(length: out.ref.size);
final result = out.ref.ptr.toDartString(length: out.ref.size);
libgit2.git_buf_dispose(out);
calloc.free(out);

View file

@ -3,6 +3,7 @@ import 'dart:ffi';
import 'package:ffi/ffi.dart';
import 'package:libgit2dart/src/bindings/libgit2_bindings.dart';
import 'package:libgit2dart/src/error.dart';
import 'package:libgit2dart/src/extensions.dart';
import 'package:libgit2dart/src/util.dart';
/// Initializes a rebase operation to rebase the changes in [branchPointer]
@ -128,7 +129,7 @@ void commit({
required String? message,
}) {
final out = calloc<git_oid>();
final messageC = message?.toNativeUtf8().cast<Int8>() ?? nullptr;
final messageC = message?.toChar() ?? nullptr;
final error = libgit2.git_rebase_commit(
out,
@ -163,7 +164,7 @@ Pointer<git_oid> origHeadOid(Pointer<git_rebase> rebase) =>
/// Gets the original HEAD ref name for merge rebases.
String origHeadName(Pointer<git_rebase> rebase) {
final result = libgit2.git_rebase_orig_head_name(rebase);
return result == nullptr ? '' : result.cast<Utf8>().toDartString();
return result == nullptr ? '' : result.toDartString();
}
/// Gets the onto id for merge rebases.
@ -172,7 +173,7 @@ Pointer<git_oid> ontoOid(Pointer<git_rebase> rebase) =>
/// Gets the onto ref name for merge rebases.
String ontoName(Pointer<git_rebase> rebase) {
return libgit2.git_rebase_onto_name(rebase).cast<Utf8>().toDartString();
return libgit2.git_rebase_onto_name(rebase).toDartString();
}
/// Free memory allocated for rebase object.

View file

@ -3,6 +3,7 @@ import 'dart:ffi';
import 'package:ffi/ffi.dart';
import 'package:libgit2dart/src/bindings/libgit2_bindings.dart';
import 'package:libgit2dart/src/error.dart';
import 'package:libgit2dart/src/extensions.dart';
import 'package:libgit2dart/src/util.dart';
/// Get the type of a reference.
@ -55,7 +56,7 @@ Pointer<git_reference> lookup({
required String name,
}) {
final out = calloc<Pointer<git_reference>>();
final nameC = name.toNativeUtf8().cast<Int8>();
final nameC = name.toChar();
final error = libgit2.git_reference_lookup(out, repoPointer, nameC);
final result = out.value;
@ -72,7 +73,7 @@ Pointer<git_reference> lookup({
/// Get the full name of a reference.
String name(Pointer<git_reference> ref) {
return libgit2.git_reference_name(ref).cast<Utf8>().toDartString();
return libgit2.git_reference_name(ref).toDartString();
}
/// Get the reference's short name.
@ -80,7 +81,7 @@ String name(Pointer<git_reference> ref) {
/// This will transform the reference name into a name "human-readable" version.
/// If no shortname is appropriate, it will return the full name.
String shorthand(Pointer<git_reference> ref) {
return libgit2.git_reference_shorthand(ref).cast<Utf8>().toDartString();
return libgit2.git_reference_shorthand(ref).toDartString();
}
/// Rename an existing reference. The returned reference must be freed with
@ -104,9 +105,9 @@ Pointer<git_reference> rename({
String? logMessage,
}) {
final out = calloc<Pointer<git_reference>>();
final newNameC = newName.toNativeUtf8().cast<Int8>();
final newNameC = newName.toChar();
final forceC = force == true ? 1 : 0;
final logMessageC = logMessage?.toNativeUtf8().cast<Int8>() ?? nullptr;
final logMessageC = logMessage?.toChar() ?? nullptr;
final error = libgit2.git_reference_rename(
out,
refPointer,
@ -140,9 +141,7 @@ List<String> list(Pointer<git_repository> repo) {
throw LibGit2Error(libgit2.git_error_last());
} else {
for (var i = 0; i < array.ref.count; i++) {
result.add(
array.ref.strings.elementAt(i).value.cast<Utf8>().toDartString(),
);
result.add(array.ref.strings.elementAt(i).value.toDartString());
}
}
@ -156,7 +155,7 @@ bool hasLog({
required Pointer<git_repository> repoPointer,
required String name,
}) {
final nameC = name.toNativeUtf8().cast<Int8>();
final nameC = name.toChar();
final result = libgit2.git_reference_has_log(repoPointer, nameC);
calloc.free(nameC);
@ -173,7 +172,7 @@ void ensureLog({
required Pointer<git_repository> repoPointer,
required String refName,
}) {
final refNameC = refName.toNativeUtf8().cast<Int8>();
final refNameC = refName.toChar();
final error = libgit2.git_reference_ensure_log(repoPointer, refNameC);
calloc.free(refNameC);
@ -237,9 +236,9 @@ Pointer<git_reference> createDirect({
String? logMessage,
}) {
final out = calloc<Pointer<git_reference>>();
final nameC = name.toNativeUtf8().cast<Int8>();
final nameC = name.toChar();
final forceC = force == true ? 1 : 0;
final logMessageC = logMessage?.toNativeUtf8().cast<Int8>() ?? nullptr;
final logMessageC = logMessage?.toChar() ?? nullptr;
final error = libgit2.git_reference_create(
out,
repoPointer,
@ -295,10 +294,10 @@ Pointer<git_reference> createSymbolic({
String? logMessage,
}) {
final out = calloc<Pointer<git_reference>>();
final nameC = name.toNativeUtf8().cast<Int8>();
final targetC = target.toNativeUtf8().cast<Int8>();
final nameC = name.toChar();
final targetC = target.toChar();
final forceC = force == true ? 1 : 0;
final logMessageC = logMessage?.toNativeUtf8().cast<Int8>() ?? nullptr;
final logMessageC = logMessage?.toChar() ?? nullptr;
final error = libgit2.git_reference_symbolic_create(
out,
repoPointer,
@ -348,7 +347,7 @@ Pointer<git_reference> setTarget({
String? logMessage,
}) {
final out = calloc<Pointer<git_reference>>();
final logMessageC = logMessage?.toNativeUtf8().cast<Int8>() ?? nullptr;
final logMessageC = logMessage?.toChar() ?? nullptr;
final error = libgit2.git_reference_set_target(
out,
refPointer,
@ -388,8 +387,8 @@ Pointer<git_reference> setTargetSymbolic({
String? logMessage,
}) {
final out = calloc<Pointer<git_reference>>();
final targetC = target.toNativeUtf8().cast<Int8>();
final logMessageC = logMessage?.toNativeUtf8().cast<Int8>() ?? nullptr;
final targetC = target.toChar();
final logMessageC = logMessage?.toChar() ?? nullptr;
final error = libgit2.git_reference_symbolic_set_target(
out,
refPointer,
@ -410,14 +409,6 @@ Pointer<git_reference> setTargetSymbolic({
}
}
/// Compare two references.
bool compare({
required Pointer<git_reference> ref1Pointer,
required Pointer<git_reference> ref2Pointer,
}) {
return libgit2.git_reference_cmp(ref1Pointer, ref2Pointer) == 0 || false;
}
/// Recursively peel reference until object of the specified type is found.
///
/// The retrieved peeled object is owned by the repository and should be closed

View file

@ -3,6 +3,7 @@ import 'dart:ffi';
import 'package:ffi/ffi.dart';
import 'package:libgit2dart/src/bindings/libgit2_bindings.dart';
import 'package:libgit2dart/src/error.dart';
import 'package:libgit2dart/src/extensions.dart';
import 'package:libgit2dart/src/util.dart';
/// Read the reflog for the given reference. The returned reflog must be
@ -15,7 +16,7 @@ Pointer<git_reflog> read({
required String name,
}) {
final out = calloc<Pointer<git_reflog>>();
final nameC = name.toNativeUtf8().cast<Int8>();
final nameC = name.toChar();
libgit2.git_reflog_read(out, repoPointer, nameC);
final result = out.value;
@ -43,7 +44,7 @@ void delete({
required Pointer<git_repository> repoPointer,
required String name,
}) {
final nameC = name.toNativeUtf8().cast<Int8>();
final nameC = name.toChar();
libgit2.git_reflog_delete(repoPointer, nameC);
calloc.free(nameC);
}
@ -60,8 +61,8 @@ void rename({
required String oldName,
required String newName,
}) {
final oldNameC = oldName.toNativeUtf8().cast<Int8>();
final newNameC = newName.toNativeUtf8().cast<Int8>();
final oldNameC = oldName.toChar();
final newNameC = newName.toChar();
final error = libgit2.git_reflog_rename(repoPointer, oldNameC, newNameC);
calloc.free(oldNameC);
@ -81,8 +82,7 @@ void add({
required Pointer<git_signature> committerPointer,
required String message,
}) {
final messageC =
message.isEmpty ? nullptr : message.toNativeUtf8().cast<Int8>();
final messageC = message.isEmpty ? nullptr : message.toChar();
final error = libgit2.git_reflog_append(
reflogPointer,
@ -130,7 +130,7 @@ Pointer<git_reflog_entry> getByIndex({
/// Get the log message.
String entryMessage(Pointer<git_reflog_entry> entry) {
final result = libgit2.git_reflog_entry_message(entry);
return result == nullptr ? '' : result.cast<Utf8>().toDartString();
return result == nullptr ? '' : result.toDartString();
}
/// Get the committer of this entry. The returned signature must be freed.

View file

@ -3,16 +3,17 @@ import 'dart:ffi';
import 'package:ffi/ffi.dart';
import 'package:libgit2dart/src/bindings/libgit2_bindings.dart';
import 'package:libgit2dart/src/error.dart';
import 'package:libgit2dart/src/extensions.dart';
import 'package:libgit2dart/src/util.dart';
/// Get the source specifier.
String source(Pointer<git_refspec> refspec) {
return libgit2.git_refspec_src(refspec).cast<Utf8>().toDartString();
return libgit2.git_refspec_src(refspec).toDartString();
}
/// Get the destination specifier.
String destination(Pointer<git_refspec> refspec) {
return libgit2.git_refspec_dst(refspec).cast<Utf8>().toDartString();
return libgit2.git_refspec_dst(refspec).toDartString();
}
/// Get the force update setting.
@ -22,7 +23,7 @@ bool force(Pointer<git_refspec> refspec) {
/// Get the refspec's string.
String string(Pointer<git_refspec> refspec) {
return libgit2.git_refspec_string(refspec).cast<Utf8>().toDartString();
return libgit2.git_refspec_string(refspec).toDartString();
}
/// Get the refspec's direction.
@ -34,7 +35,7 @@ bool matchesSource({
required Pointer<git_refspec> refspecPointer,
required String refname,
}) {
final refnameC = refname.toNativeUtf8().cast<Int8>();
final refnameC = refname.toChar();
final result = libgit2.git_refspec_src_matches(refspecPointer, refnameC);
calloc.free(refnameC);
@ -47,7 +48,7 @@ bool matchesDestination({
required Pointer<git_refspec> refspecPointer,
required String refname,
}) {
final refnameC = refname.toNativeUtf8().cast<Int8>();
final refnameC = refname.toChar();
final result = libgit2.git_refspec_dst_matches(refspecPointer, refnameC);
calloc.free(refnameC);
@ -63,10 +64,10 @@ String transform({
required String name,
}) {
final out = calloc<git_buf>();
final nameC = name.toNativeUtf8().cast<Int8>();
final nameC = name.toChar();
final error = libgit2.git_refspec_transform(out, refspecPointer, nameC);
final result = out.ref.ptr.cast<Utf8>().toDartString(length: out.ref.size);
final result = out.ref.ptr.toDartString(length: out.ref.size);
libgit2.git_buf_dispose(out);
calloc.free(out);
@ -88,10 +89,10 @@ String rTransform({
required String name,
}) {
final out = calloc<git_buf>();
final nameC = name.toNativeUtf8().cast<Int8>();
final nameC = name.toChar();
final error = libgit2.git_refspec_rtransform(out, refspecPointer, nameC);
final result = out.ref.ptr.cast<Utf8>().toDartString(length: out.ref.size);
final result = out.ref.ptr.toDartString(length: out.ref.size);
libgit2.git_buf_dispose(out);
calloc.free(out);

View file

@ -5,6 +5,7 @@ import 'package:libgit2dart/src/bindings/libgit2_bindings.dart';
import 'package:libgit2dart/src/bindings/remote_callbacks.dart';
import 'package:libgit2dart/src/callbacks.dart';
import 'package:libgit2dart/src/error.dart';
import 'package:libgit2dart/src/extensions.dart';
import 'package:libgit2dart/src/oid.dart';
import 'package:libgit2dart/src/util.dart';
@ -13,10 +14,9 @@ List<String> list(Pointer<git_repository> repo) {
final out = calloc<git_strarray>();
libgit2.git_remote_list(out, repo);
final result = <String>[];
for (var i = 0; i < out.ref.count; i++) {
result.add(out.ref.strings[i].cast<Utf8>().toDartString());
}
final result = <String>[
for (var i = 0; i < out.ref.count; i++) out.ref.strings[i].toDartString()
];
calloc.free(out);
@ -34,7 +34,7 @@ Pointer<git_remote> lookup({
required String name,
}) {
final out = calloc<Pointer<git_remote>>();
final nameC = name.toNativeUtf8().cast<Int8>();
final nameC = name.toChar();
final error = libgit2.git_remote_lookup(out, repoPointer, nameC);
final result = out.value;
@ -59,8 +59,8 @@ Pointer<git_remote> create({
required String url,
}) {
final out = calloc<Pointer<git_remote>>();
final nameC = name.toNativeUtf8().cast<Int8>();
final urlC = url.toNativeUtf8().cast<Int8>();
final nameC = name.toChar();
final urlC = url.toChar();
final error = libgit2.git_remote_create(out, repoPointer, nameC, urlC);
final result = out.value;
@ -87,9 +87,9 @@ Pointer<git_remote> createWithFetchSpec({
required String fetch,
}) {
final out = calloc<Pointer<git_remote>>();
final nameC = name.toNativeUtf8().cast<Int8>();
final urlC = url.toNativeUtf8().cast<Int8>();
final fetchC = fetch.toNativeUtf8().cast<Int8>();
final nameC = name.toChar();
final urlC = url.toChar();
final fetchC = fetch.toChar();
final error = libgit2.git_remote_create_with_fetchspec(
out,
repoPointer,
@ -122,7 +122,7 @@ void delete({
required Pointer<git_repository> repoPointer,
required String name,
}) {
final nameC = name.toNativeUtf8().cast<Int8>();
final nameC = name.toChar();
final error = libgit2.git_remote_delete(repoPointer, nameC);
calloc.free(nameC);
@ -151,8 +151,8 @@ List<String> rename({
required String newName,
}) {
final out = calloc<git_strarray>();
final nameC = name.toNativeUtf8().cast<Int8>();
final newNameC = newName.toNativeUtf8().cast<Int8>();
final nameC = name.toChar();
final newNameC = newName.toChar();
final error = libgit2.git_remote_rename(out, repoPointer, nameC, newNameC);
calloc.free(nameC);
@ -162,11 +162,12 @@ List<String> rename({
calloc.free(out);
throw LibGit2Error(libgit2.git_error_last());
} else {
final result = <String>[];
for (var i = 0; i < out.ref.count; i++) {
result.add(out.ref.strings[i].cast<Utf8>().toDartString());
}
final result = <String>[
for (var i = 0; i < out.ref.count; i++) out.ref.strings[i].toDartString()
];
calloc.free(out);
return result;
}
}
@ -182,8 +183,8 @@ void setUrl({
required String remote,
required String url,
}) {
final remoteC = remote.toNativeUtf8().cast<Int8>();
final urlC = url.toNativeUtf8().cast<Int8>();
final remoteC = remote.toChar();
final urlC = url.toChar();
final error = libgit2.git_remote_set_url(repoPointer, remoteC, urlC);
calloc.free(remoteC);
@ -205,8 +206,8 @@ void setPushUrl({
required String remote,
required String url,
}) {
final remoteC = remote.toNativeUtf8().cast<Int8>();
final urlC = url.toNativeUtf8().cast<Int8>();
final remoteC = remote.toChar();
final urlC = url.toChar();
final error = libgit2.git_remote_set_pushurl(repoPointer, remoteC, urlC);
calloc.free(remoteC);
@ -220,12 +221,12 @@ void setPushUrl({
/// Get the remote's name.
String name(Pointer<git_remote> remote) {
final result = libgit2.git_remote_name(remote);
return result == nullptr ? '' : result.cast<Utf8>().toDartString();
return result == nullptr ? '' : result.toDartString();
}
/// Get the remote's url.
String url(Pointer<git_remote> remote) {
return libgit2.git_remote_url(remote).cast<Utf8>().toDartString();
return libgit2.git_remote_url(remote).toDartString();
}
/// Get the remote's url for pushing.
@ -233,7 +234,7 @@ String url(Pointer<git_remote> remote) {
/// Returns empty string if no special url for pushing is set.
String pushUrl(Pointer<git_remote> remote) {
final result = libgit2.git_remote_pushurl(remote);
return result == nullptr ? '' : result.cast<Utf8>().toDartString();
return result == nullptr ? '' : result.toDartString();
}
/// Get the number of refspecs for a remote.
@ -253,11 +254,12 @@ List<String> fetchRefspecs(Pointer<git_remote> remote) {
final out = calloc<git_strarray>();
libgit2.git_remote_get_fetch_refspecs(out, remote);
final result = <String>[];
for (var i = 0; i < out.ref.count; i++) {
result.add(out.ref.strings[i].cast<Utf8>().toDartString());
}
final result = <String>[
for (var i = 0; i < out.ref.count; i++) out.ref.strings[i].toDartString()
];
calloc.free(out);
return result;
}
@ -266,11 +268,12 @@ List<String> pushRefspecs(Pointer<git_remote> remote) {
final out = calloc<git_strarray>();
libgit2.git_remote_get_push_refspecs(out, remote);
final result = <String>[];
for (var i = 0; i < out.ref.count; i++) {
result.add(out.ref.strings[i].cast<Utf8>().toDartString());
}
final result = <String>[
for (var i = 0; i < out.ref.count; i++) out.ref.strings[i].toDartString()
];
calloc.free(out);
return result;
}
@ -285,8 +288,8 @@ void addFetch({
required String remote,
required String refspec,
}) {
final remoteC = remote.toNativeUtf8().cast<Int8>();
final refspecC = refspec.toNativeUtf8().cast<Int8>();
final remoteC = remote.toChar();
final refspecC = refspec.toChar();
final error = libgit2.git_remote_add_fetch(repoPointer, remoteC, refspecC);
calloc.free(remoteC);
@ -308,8 +311,8 @@ void addPush({
required String remote,
required String refspec,
}) {
final remoteC = remote.toNativeUtf8().cast<Int8>();
final refspecC = refspec.toNativeUtf8().cast<Int8>();
final remoteC = remote.toChar();
final refspecC = refspec.toChar();
final error = libgit2.git_remote_add_push(repoPointer, remoteC, refspecC);
calloc.free(remoteC);
@ -375,7 +378,7 @@ void connect({
/// Throws a [LibGit2Error] if error occured.
List<Map<String, Object?>> lsRemotes(Pointer<git_remote> remote) {
final out = calloc<Pointer<Pointer<git_remote_head>>>();
final size = calloc<Uint64>();
final size = calloc<Size>();
libgit2.git_remote_ls(out, size, remote);
final result = <Map<String, Object?>>[];
@ -387,12 +390,11 @@ List<Map<String, Object?>> lsRemotes(Pointer<git_remote> remote) {
remote['local'] = local;
remote['loid'] = local ? Oid.fromRaw(out[0][i].ref.loid) : null;
remote['name'] = out[0][i].ref.name == nullptr
? ''
: out[0][i].ref.name.cast<Utf8>().toDartString();
remote['name'] =
out[0][i].ref.name == nullptr ? '' : out[0][i].ref.name.toDartString();
remote['symref'] = out[0][i].ref.symref_target == nullptr
? ''
: out[0][i].ref.symref_target.cast<Utf8>().toDartString();
: out[0][i].ref.symref_target.toDartString();
remote['oid'] = Oid.fromRaw(out[0][i].ref.oid);
result.add(remote);
@ -419,9 +421,8 @@ void fetch({
String? proxyOption,
}) {
final refspecsC = calloc<git_strarray>();
final refspecsPointers =
refspecs.map((e) => e.toNativeUtf8().cast<Int8>()).toList();
final strArray = calloc<Pointer<Int8>>(refspecs.length);
final refspecsPointers = refspecs.map((e) => e.toChar()).toList();
final strArray = calloc<Pointer<Char>>(refspecs.length);
for (var i = 0; i < refspecs.length; i++) {
strArray[i] = refspecsPointers[i];
@ -429,7 +430,7 @@ void fetch({
refspecsC.ref.count = refspecs.length;
refspecsC.ref.strings = strArray;
final reflogMessageC = reflogMessage?.toNativeUtf8().cast<Int8>() ?? nullptr;
final reflogMessageC = reflogMessage?.toChar() ?? nullptr;
final proxyOptions = _proxyOptionsInit(proxyOption);
@ -475,9 +476,8 @@ void push({
String? proxyOption,
}) {
final refspecsC = calloc<git_strarray>();
final refspecsPointers =
refspecs.map((e) => e.toNativeUtf8().cast<Int8>()).toList();
final strArray = calloc<Pointer<Int8>>(refspecs.length);
final refspecsPointers = refspecs.map((e) => e.toChar()).toList();
final strArray = calloc<Pointer<Char>>(refspecs.length);
for (var i = 0; i < refspecs.length; i++) {
strArray[i] = refspecsPointers[i];
@ -566,7 +566,7 @@ Pointer<git_proxy_options> _proxyOptionsInit(String? proxyOption) {
proxyOptions.ref.type = git_proxy_t.GIT_PROXY_AUTO;
} else {
proxyOptions.ref.type = git_proxy_t.GIT_PROXY_SPECIFIED;
proxyOptions.ref.url = proxyOption.toNativeUtf8().cast<Int8>();
proxyOptions.ref.url = proxyOption.toChar();
}
return proxyOptions;

View file

@ -8,6 +8,7 @@ import 'package:libgit2dart/src/bindings/libgit2_bindings.dart';
import 'package:libgit2dart/src/bindings/remote.dart' as remote_bindings;
import 'package:libgit2dart/src/bindings/repository.dart'
as repository_bindings;
import 'package:libgit2dart/src/extensions.dart';
import 'package:libgit2dart/src/util.dart';
class RemoteCallbacks {
@ -29,11 +30,11 @@ class RemoteCallbacks {
/// Callback for messages received by the transport.
static int sidebandProgressCb(
Pointer<Int8> progressOutput,
Pointer<Char> progressOutput,
int length,
Pointer<Void> payload,
) {
sidebandProgress!(progressOutput.cast<Utf8>().toDartString(length: length));
sidebandProgress!(progressOutput.toDartString(length: length));
return 0;
}
@ -42,12 +43,12 @@ class RemoteCallbacks {
/// A callback that will be called for every reference.
static int updateTipsCb(
Pointer<Int8> refname,
Pointer<Char> refname,
Pointer<git_oid> oldOid,
Pointer<git_oid> newOid,
Pointer<Void> payload,
) {
updateTips!(refname.cast<Utf8>().toDartString(), Oid(oldOid), Oid(newOid));
updateTips!(refname.toDartString(), Oid(oldOid), Oid(newOid));
return 0;
}
@ -58,13 +59,12 @@ class RemoteCallbacks {
/// not empty, the update was rejected by the remote server
/// and [message] contains the reason given.
static int pushUpdateReferenceCb(
Pointer<Int8> refname,
Pointer<Int8> message,
Pointer<Char> refname,
Pointer<Char> message,
Pointer<Void> payload,
) {
final messageResult =
message == nullptr ? '' : message.cast<Utf8>().toDartString();
pushUpdateReference!(refname.cast<Utf8>().toDartString(), messageResult);
final messageResult = message == nullptr ? '' : message.toDartString();
pushUpdateReference!(refname.toDartString(), messageResult);
return 0;
}
@ -77,8 +77,8 @@ class RemoteCallbacks {
static int remoteCb(
Pointer<Pointer<git_remote>> remote,
Pointer<git_repository> repo,
Pointer<Int8> name,
Pointer<Int8> url,
Pointer<Char> name,
Pointer<Char> url,
Pointer<Void> payload,
) {
late final Pointer<git_remote> remotePointer;
@ -110,7 +110,7 @@ class RemoteCallbacks {
/// A callback used to create the new repository into which to clone.
static int repositoryCb(
Pointer<Pointer<git_repository>> repo,
Pointer<Int8> path,
Pointer<Char> path,
int bare,
Pointer<Void> payload,
) {
@ -147,15 +147,15 @@ class RemoteCallbacks {
/// requires authentication in order to connect to it.
static int credentialsCb(
Pointer<Pointer<git_credential>> credPointer,
Pointer<Int8> url,
Pointer<Int8> username,
Pointer<Char> url,
Pointer<Char> username,
int allowedTypes,
Pointer<Void> payload,
) {
if (payload.cast<Int8>().value == 2) {
if (payload.cast<Char>().value == 2) {
libgit2.git_error_set_str(
git_error_t.GIT_ERROR_INVALID,
'Incorrect credentials.'.toNativeUtf8().cast<Int8>(),
'Incorrect credentials.'.toChar(),
);
throw LibGit2Error(libgit2.git_error_last());
}
@ -165,7 +165,7 @@ class RemoteCallbacks {
if (allowedTypes & credentialType.value != credentialType.value) {
libgit2.git_error_set_str(
git_error_t.GIT_ERROR_INVALID,
'Invalid credential type $credentialType'.toNativeUtf8().cast<Int8>(),
'Invalid credential type $credentialType'.toChar(),
);
throw LibGit2Error(libgit2.git_error_last());
}

View file

@ -5,6 +5,7 @@ import 'package:libgit2dart/src/bindings/libgit2_bindings.dart';
import 'package:libgit2dart/src/bindings/remote_callbacks.dart';
import 'package:libgit2dart/src/callbacks.dart';
import 'package:libgit2dart/src/error.dart';
import 'package:libgit2dart/src/extensions.dart';
import 'package:libgit2dart/src/remote.dart';
import 'package:libgit2dart/src/repository.dart';
import 'package:libgit2dart/src/util.dart';
@ -17,7 +18,7 @@ import 'package:libgit2dart/src/util.dart';
/// Throws a [LibGit2Error] if error occured.
Pointer<git_repository> open(String path) {
final out = calloc<Pointer<git_repository>>();
final pathC = path.toNativeUtf8().cast<Int8>();
final pathC = path.toChar();
final error = libgit2.git_repository_open(out, pathC);
final result = out.value;
@ -44,15 +45,15 @@ String discover({
String? ceilingDirs,
}) {
final out = calloc<git_buf>();
final startPathC = startPath.toNativeUtf8().cast<Int8>();
final ceilingDirsC = ceilingDirs?.toNativeUtf8().cast<Int8>() ?? nullptr;
final startPathC = startPath.toChar();
final ceilingDirsC = ceilingDirs?.toChar() ?? nullptr;
libgit2.git_repository_discover(out, startPathC, 0, ceilingDirsC);
calloc.free(startPathC);
calloc.free(ceilingDirsC);
final result = out.ref.ptr.cast<Utf8>().toDartString(length: out.ref.size);
final result = out.ref.ptr.toDartString(length: out.ref.size);
libgit2.git_buf_dispose(out);
calloc.free(out);
@ -75,12 +76,12 @@ Pointer<git_repository> init({
String? originUrl,
}) {
final out = calloc<Pointer<git_repository>>();
final pathC = path.toNativeUtf8().cast<Int8>();
final workdirPathC = workdirPath?.toNativeUtf8().cast<Int8>() ?? nullptr;
final descriptionC = description?.toNativeUtf8().cast<Int8>() ?? nullptr;
final templatePathC = templatePath?.toNativeUtf8().cast<Int8>() ?? nullptr;
final initialHeadC = initialHead?.toNativeUtf8().cast<Int8>() ?? nullptr;
final originUrlC = originUrl?.toNativeUtf8().cast<Int8>() ?? nullptr;
final pathC = path.toChar();
final workdirPathC = workdirPath?.toChar() ?? nullptr;
final descriptionC = description?.toChar() ?? nullptr;
final templatePathC = templatePath?.toChar() ?? nullptr;
final initialHeadC = initialHead?.toChar() ?? nullptr;
final originUrlC = originUrl?.toChar() ?? nullptr;
final opts = calloc<git_repository_init_options>();
libgit2.git_repository_init_options_init(
opts,
@ -124,16 +125,14 @@ Pointer<git_repository> clone({
required String localPath,
required bool bare,
RemoteCallback? remoteCallback,
// Repository Function(String, bool)? repository,
RepositoryCallback? repositoryCallback,
String? checkoutBranch,
required Callbacks callbacks,
}) {
final out = calloc<Pointer<git_repository>>();
final urlC = url.toNativeUtf8().cast<Int8>();
final localPathC = localPath.toNativeUtf8().cast<Int8>();
final checkoutBranchC =
checkoutBranch?.toNativeUtf8().cast<Int8>() ?? nullptr;
final urlC = url.toChar();
final localPathC = localPath.toChar();
final checkoutBranchC = checkoutBranch?.toChar() ?? nullptr;
final cloneOptions = calloc<git_clone_options>();
libgit2.git_clone_options_init(cloneOptions, GIT_CLONE_OPTIONS_VERSION);
@ -188,7 +187,7 @@ Pointer<git_repository> clone({
/// Returns the path to the `.git` folder for normal repositories or the
/// repository itself for bare repositories.
String path(Pointer<git_repository> repo) {
return libgit2.git_repository_path(repo).cast<Utf8>().toDartString();
return libgit2.git_repository_path(repo).toDartString();
}
/// Get the path of the shared common directory for this repository.
@ -197,7 +196,7 @@ String path(Pointer<git_repository> repo) {
/// If the repository is a worktree, it is the parent repo's `.git` folder.
/// Otherwise, it is the `.git` folder.
String commonDir(Pointer<git_repository> repo) {
return libgit2.git_repository_commondir(repo).cast<Utf8>().toDartString();
return libgit2.git_repository_commondir(repo).toDartString();
}
/// Get the currently active namespace for this repository.
@ -206,11 +205,7 @@ String commonDir(Pointer<git_repository> repo) {
/// empty string is returned.
String getNamespace(Pointer<git_repository> repo) {
final result = libgit2.git_repository_get_namespace(repo);
if (result == nullptr) {
return '';
} else {
return result.cast<Utf8>().toDartString();
}
return result == nullptr ? '' : result.toDartString();
}
/// Sets the active namespace for this repository.
@ -224,7 +219,7 @@ void setNamespace({
required Pointer<git_repository> repoPointer,
String? namespace,
}) {
final namespaceC = namespace?.toNativeUtf8().cast<Int8>() ?? nullptr;
final namespaceC = namespace?.toChar() ?? nullptr;
libgit2.git_repository_set_namespace(repoPointer, namespaceC);
calloc.free(namespaceC);
}
@ -311,8 +306,8 @@ void setIdentity({
String? name,
String? email,
}) {
final nameC = name?.toNativeUtf8().cast<Int8>() ?? nullptr;
final emailC = email?.toNativeUtf8().cast<Int8>() ?? nullptr;
final nameC = name?.toChar() ?? nullptr;
final emailC = email?.toChar() ?? nullptr;
libgit2.git_repository_set_ident(repoPointer, nameC, emailC);
@ -324,16 +319,16 @@ void setIdentity({
///
/// Returns list with name and email respectively.
List<String> identity(Pointer<git_repository> repo) {
final name = calloc<Pointer<Int8>>();
final email = calloc<Pointer<Int8>>();
final name = calloc<Pointer<Char>>();
final email = calloc<Pointer<Char>>();
libgit2.git_repository_ident(name, email, repo);
final identity = <String>[];
if (name.value == nullptr && email.value == nullptr) {
return identity;
} else {
identity.add(name.value.cast<Utf8>().toDartString());
identity.add(email.value.cast<Utf8>().toDartString());
identity.add(name.value.toDartString());
identity.add(email.value.toDartString());
}
calloc.free(name);
@ -417,7 +412,7 @@ String message(Pointer<git_repository> repo) {
final out = calloc<git_buf>();
final error = libgit2.git_repository_message(out, repo);
final result = out.ref.ptr.cast<Utf8>().toDartString(length: out.ref.size);
final result = out.ref.ptr.toDartString(length: out.ref.size);
libgit2.git_buf_dispose(out);
calloc.free(out);
@ -495,7 +490,7 @@ void setHead({
required Pointer<git_repository> repoPointer,
required String refname,
}) {
final refnameC = refname.toNativeUtf8().cast<Int8>();
final refnameC = refname.toChar();
final error = libgit2.git_repository_set_head(repoPointer, refnameC);
calloc.free(refnameC);
@ -546,7 +541,7 @@ void setWorkdir({
required String path,
required bool updateGitlink,
}) {
final workdirC = path.toNativeUtf8().cast<Int8>();
final workdirC = path.toChar();
final updateGitlinkC = updateGitlink ? 1 : 0;
final error = libgit2.git_repository_set_workdir(
repoPointer,
@ -582,12 +577,7 @@ void stateCleanup(Pointer<git_repository> repo) {
/// If the repository is bare, this function will always return empty string.
String workdir(Pointer<git_repository> repo) {
final result = libgit2.git_repository_workdir(repo);
if (result == nullptr) {
return '';
} else {
return result.cast<Utf8>().toDartString();
}
return result == nullptr ? '' : result.toDartString();
}
/// Free a previously allocated repository.

View file

@ -3,6 +3,7 @@ import 'dart:ffi';
import 'package:ffi/ffi.dart';
import 'package:libgit2dart/src/bindings/libgit2_bindings.dart';
import 'package:libgit2dart/src/error.dart';
import 'package:libgit2dart/src/extensions.dart';
import 'package:libgit2dart/src/util.dart';
/// Sets the current head to the specified commit oid and optionally resets the
@ -16,30 +17,67 @@ import 'package:libgit2dart/src/util.dart';
/// HARD reset will trigger a MIXED reset and the working directory will be
/// replaced with the content of the index. (Untracked and ignored files will
/// be left alone, however.)
///
/// Throws a [LibGit2Error] if error occured.
void reset({
required Pointer<git_repository> repoPointer,
required Pointer<git_object> targetPointer,
required int resetType,
required Pointer<git_checkout_options> checkoutOptsPointer,
int? strategy,
String? checkoutDirectory,
List<String>? pathspec,
}) {
libgit2.git_reset(repoPointer, targetPointer, resetType, checkoutOptsPointer);
final opts = calloc<git_checkout_options>();
libgit2.git_checkout_options_init(opts, GIT_CHECKOUT_OPTIONS_VERSION);
if (strategy != null) {
opts.ref.checkout_strategy = strategy;
}
if (checkoutDirectory != null) {
opts.ref.target_directory = checkoutDirectory.toChar();
}
var pathPointers = <Pointer<Char>>[];
Pointer<Pointer<Char>> strArray = nullptr;
if (pathspec != null) {
pathPointers = pathspec.map((e) => e.toChar()).toList();
strArray = calloc(pathspec.length);
for (var i = 0; i < pathspec.length; i++) {
strArray[i] = pathPointers[i];
}
opts.ref.paths.strings = strArray;
opts.ref.paths.count = pathspec.length;
}
final error = libgit2.git_reset(repoPointer, targetPointer, resetType, opts);
for (final p in pathPointers) {
calloc.free(p);
}
calloc.free(strArray);
calloc.free(opts);
if (error < 0) {
throw LibGit2Error(libgit2.git_error_last());
}
}
/// Updates some entries in the index from the target commit tree.
///
/// The scope of the updated entries is determined by the paths being passed in
/// the pathspec parameters.
/// the [pathspec] parameters.
///
/// Passing a null [targetPointer] will result in removing entries in the index
/// matching the provided [pathspec]s.
///
/// Throws a [LibGit2Error] if error occured.
void resetDefault({
required Pointer<git_repository> repoPointer,
required Pointer<git_object> targetPointer,
required Pointer<git_object>? targetPointer,
required List<String> pathspec,
}) {
final pathspecC = calloc<git_strarray>();
final pathPointers =
pathspec.map((e) => e.toNativeUtf8().cast<Int8>()).toList();
final strArray = calloc<Pointer<Int8>>(pathspec.length);
final pathPointers = pathspec.map((e) => e.toChar()).toList();
final strArray = calloc<Pointer<Char>>(pathspec.length);
for (var i = 0; i < pathspec.length; i++) {
strArray[i] = pathPointers[i];
@ -50,7 +88,7 @@ void resetDefault({
final error = libgit2.git_reset_default(
repoPointer,
targetPointer,
targetPointer ?? nullptr,
pathspecC,
);

View file

@ -3,6 +3,7 @@ import 'dart:ffi';
import 'package:ffi/ffi.dart';
import 'package:libgit2dart/src/bindings/libgit2_bindings.dart';
import 'package:libgit2dart/src/error.dart';
import 'package:libgit2dart/src/extensions.dart';
import 'package:libgit2dart/src/util.dart';
/// Parse a revision string for from, to, and intent.
@ -16,7 +17,7 @@ Pointer<git_revspec> revParse({
required String spec,
}) {
final out = calloc<git_revspec>();
final specC = spec.toNativeUtf8().cast<Int8>();
final specC = spec.toChar();
final error = libgit2.git_revparse(out, repoPointer, specC);
@ -42,7 +43,7 @@ Pointer<git_object> revParseSingle({
required String spec,
}) {
final out = calloc<Pointer<git_object>>();
final specC = spec.toNativeUtf8().cast<Int8>();
final specC = spec.toChar();
final error = libgit2.git_revparse_single(out, repoPointer, specC);
@ -76,7 +77,7 @@ List<Pointer> revParseExt({
}) {
final objectOut = calloc<Pointer<git_object>>();
final referenceOut = calloc<Pointer<git_reference>>();
final specC = spec.toNativeUtf8().cast<Int8>();
final specC = spec.toChar();
final error = libgit2.git_revparse_ext(
objectOut,
@ -85,8 +86,7 @@ List<Pointer> revParseExt({
specC,
);
final result = <Pointer>[];
result.add(objectOut.value);
final result = <Pointer>[objectOut.value];
if (referenceOut.value != nullptr) {
result.add(referenceOut.value);
}

View file

@ -4,6 +4,7 @@ import 'package:ffi/ffi.dart';
import 'package:libgit2dart/src/bindings/commit.dart' as commit_bindings;
import 'package:libgit2dart/src/bindings/libgit2_bindings.dart';
import 'package:libgit2dart/src/error.dart';
import 'package:libgit2dart/src/extensions.dart';
import 'package:libgit2dart/src/util.dart';
/// Allocate a new revision walker to iterate through a repo. The returned
@ -81,7 +82,7 @@ void pushGlob({
required Pointer<git_revwalk> walkerPointer,
required String glob,
}) {
final globC = glob.toNativeUtf8().cast<Int8>();
final globC = glob.toChar();
libgit2.git_revwalk_push_glob(walkerPointer, globC);
calloc.free(globC);
}
@ -99,7 +100,7 @@ void pushRef({
required Pointer<git_revwalk> walkerPointer,
required String refName,
}) {
final refNameC = refName.toNativeUtf8().cast<Int8>();
final refNameC = refName.toChar();
final error = libgit2.git_revwalk_push_ref(walkerPointer, refNameC);
calloc.free(refNameC);
@ -119,7 +120,7 @@ void pushRange({
required Pointer<git_revwalk> walkerPointer,
required String range,
}) {
final rangeC = range.toNativeUtf8().cast<Int8>();
final rangeC = range.toChar();
final error = libgit2.git_revwalk_push_range(walkerPointer, rangeC);
calloc.free(rangeC);
@ -144,11 +145,12 @@ void pushRange({
List<Pointer<git_commit>> walk({
required Pointer<git_repository> repoPointer,
required Pointer<git_revwalk> walkerPointer,
required int limit,
}) {
final result = <Pointer<git_commit>>[];
var error = 0;
while (error == 0) {
void next() {
final oid = calloc<git_oid>();
error = libgit2.git_revwalk_next(oid, walkerPointer);
if (error == 0) {
@ -157,10 +159,21 @@ List<Pointer<git_commit>> walk({
oidPointer: oid,
);
result.add(commit);
calloc.free(oid);
} else {
break;
calloc.free(oid);
return;
}
}
if (limit == 0) {
while (error == 0) {
next();
}
} else {
for (var i = 0; i < limit; i++) {
next();
}
calloc.free(oid);
}
return result;
@ -199,7 +212,7 @@ void hideGlob({
required Pointer<git_revwalk> walkerPointer,
required String glob,
}) {
final globC = glob.toNativeUtf8().cast<Int8>();
final globC = glob.toChar();
libgit2.git_revwalk_hide_glob(walkerPointer, globC);
calloc.free(globC);
}
@ -217,7 +230,7 @@ void hideRef({
required Pointer<git_revwalk> walkerPointer,
required String refName,
}) {
final refNameC = refName.toNativeUtf8().cast<Int8>();
final refNameC = refName.toChar();
final error = libgit2.git_revwalk_hide_ref(walkerPointer, refNameC);
calloc.free(refNameC);

View file

@ -3,6 +3,7 @@ import 'dart:ffi';
import 'package:ffi/ffi.dart';
import 'package:libgit2dart/src/bindings/libgit2_bindings.dart';
import 'package:libgit2dart/src/error.dart';
import 'package:libgit2dart/src/extensions.dart';
import 'package:libgit2dart/src/util.dart';
/// Create a new action signature. The returned signature must be freed with
@ -19,8 +20,8 @@ Pointer<git_signature> create({
required int offset,
}) {
final out = calloc<Pointer<git_signature>>();
final nameC = name.toNativeUtf8().cast<Int8>();
final emailC = email.toNativeUtf8().cast<Int8>();
final nameC = name.toChar();
final emailC = email.toChar();
final error = libgit2.git_signature_new(out, nameC, emailC, time, offset);
final result = out.value;
@ -42,8 +43,8 @@ Pointer<git_signature> create({
/// Throws a [LibGit2Error] if error occured.
Pointer<git_signature> now({required String name, required String email}) {
final out = calloc<Pointer<git_signature>>();
final nameC = name.toNativeUtf8().cast<Int8>();
final emailC = email.toNativeUtf8().cast<Int8>();
final nameC = name.toChar();
final emailC = email.toChar();
final error = libgit2.git_signature_now(out, nameC, emailC);
final result = out.value;

View file

@ -4,6 +4,7 @@ import 'package:ffi/ffi.dart';
import 'package:libgit2dart/src/bindings/checkout.dart' as checkout_bindings;
import 'package:libgit2dart/src/bindings/libgit2_bindings.dart';
import 'package:libgit2dart/src/error.dart';
import 'package:libgit2dart/src/extensions.dart';
import 'package:libgit2dart/src/oid.dart';
import 'package:libgit2dart/src/stash.dart';
import 'package:libgit2dart/src/util.dart';
@ -18,7 +19,7 @@ Pointer<git_oid> save({
required int flags,
}) {
final out = calloc<git_oid>();
final messageC = message?.toNativeUtf8().cast<Int8>() ?? nullptr;
final messageC = message?.toChar() ?? nullptr;
final error = libgit2.git_stash_save(
out,
repoPointer,
@ -143,16 +144,12 @@ var _stashList = <Stash>[];
/// A callback function to iterate over all the stashed states.
int _stashCb(
int index,
Pointer<Int8> message,
Pointer<Char> message,
Pointer<git_oid> oid,
Pointer<Void> payload,
) {
_stashList.add(
Stash(
index: index,
message: message.cast<Utf8>().toDartString(),
oid: Oid(oid),
),
Stash(index: index, message: message.toDartString(), oid: Oid(oid)),
);
return 0;
}

View file

@ -4,6 +4,7 @@ import 'package:ffi/ffi.dart';
import 'package:libgit2dart/libgit2dart.dart';
import 'package:libgit2dart/src/bindings/libgit2_bindings.dart';
import 'package:libgit2dart/src/error.dart';
import 'package:libgit2dart/src/extensions.dart';
import 'package:libgit2dart/src/util.dart';
/// Gather file status information and populate the git_status_list. The
@ -62,8 +63,8 @@ Pointer<git_status_entry> getByIndex({
///
/// Throws a [LibGit2Error] if error occured.
int file({required Pointer<git_repository> repoPointer, required String path}) {
final out = calloc<Uint32>();
final pathC = path.toNativeUtf8().cast<Int8>();
final out = calloc<UnsignedInt>();
final pathC = path.toChar();
final error = libgit2.git_status_file(out, repoPointer, pathC);
final result = out.value;

View file

@ -5,6 +5,7 @@ import 'package:libgit2dart/src/bindings/libgit2_bindings.dart';
import 'package:libgit2dart/src/bindings/remote_callbacks.dart';
import 'package:libgit2dart/src/callbacks.dart';
import 'package:libgit2dart/src/error.dart';
import 'package:libgit2dart/src/extensions.dart';
import 'package:libgit2dart/src/util.dart';
/// List of submodule paths.
@ -15,7 +16,7 @@ List<String> _pathsList = [];
/// Function to be called with the name of each submodule.
int _listCb(
Pointer<git_submodule> submodule,
Pointer<Int8> name,
Pointer<Char> name,
Pointer<Void> payload,
) {
_pathsList.add(path(submodule));
@ -26,7 +27,7 @@ int _listCb(
List<String> list(Pointer<git_repository> repo) {
const except = -1;
final callback = Pointer.fromFunction<
Int32 Function(Pointer<git_submodule>, Pointer<Int8>, Pointer<Void>)>(
Int Function(Pointer<git_submodule>, Pointer<Char>, Pointer<Void>)>(
_listCb,
except,
);
@ -50,7 +51,7 @@ Pointer<git_submodule> lookup({
required String name,
}) {
final out = calloc<Pointer<git_submodule>>();
final nameC = name.toNativeUtf8().cast<Int8>();
final nameC = name.toChar();
final error = libgit2.git_submodule_lookup(out, repoPointer, nameC);
@ -159,8 +160,8 @@ Pointer<git_submodule> addSetup({
bool useGitlink = true,
}) {
final out = calloc<Pointer<git_submodule>>();
final urlC = url.toNativeUtf8().cast<Int8>();
final pathC = path.toNativeUtf8().cast<Int8>();
final urlC = url.toChar();
final pathC = path.toChar();
final useGitlinkC = useGitlink ? 1 : 0;
final error = libgit2.git_submodule_add_setup(
out,
@ -232,8 +233,8 @@ int status({
required String name,
required int ignore,
}) {
final out = calloc<Uint32>();
final nameC = name.toNativeUtf8().cast<Int8>();
final out = calloc<UnsignedInt>();
final nameC = name.toChar();
libgit2.git_submodule_status(out, repoPointer, nameC, ignore);
final result = out.value;
@ -269,7 +270,7 @@ void reload({
/// Get the name of submodule.
String name(Pointer<git_submodule> submodule) {
return libgit2.git_submodule_name(submodule).cast<Utf8>().toDartString();
return libgit2.git_submodule_name(submodule).toDartString();
}
/// Get the path to the submodule.
@ -277,12 +278,12 @@ String name(Pointer<git_submodule> submodule) {
/// The path is almost always the same as the submodule name, but the two
/// are actually not required to match.
String path(Pointer<git_submodule> submodule) {
return libgit2.git_submodule_path(submodule).cast<Utf8>().toDartString();
return libgit2.git_submodule_path(submodule).toDartString();
}
/// Get the URL for the submodule.
String url(Pointer<git_submodule> submodule) {
return libgit2.git_submodule_url(submodule).cast<Utf8>().toDartString();
return libgit2.git_submodule_url(submodule).toDartString();
}
/// Set the URL for the submodule in the configuration.
@ -294,8 +295,8 @@ void setUrl({
required String name,
required String url,
}) {
final nameC = name.toNativeUtf8().cast<Int8>();
final urlC = url.toNativeUtf8().cast<Int8>();
final nameC = name.toChar();
final urlC = url.toChar();
libgit2.git_submodule_set_url(repoPointer, nameC, urlC);
@ -306,7 +307,7 @@ void setUrl({
/// Get the branch for the submodule.
String branch(Pointer<git_submodule> submodule) {
final result = libgit2.git_submodule_branch(submodule);
return result == nullptr ? '' : result.cast<Utf8>().toDartString();
return result == nullptr ? '' : result.toDartString();
}
/// Set the branch for the submodule in the configuration.
@ -318,8 +319,8 @@ void setBranch({
required String name,
required String branch,
}) {
final nameC = name.toNativeUtf8().cast<Int8>();
final branchC = branch.toNativeUtf8().cast<Int8>();
final nameC = name.toChar();
final branchC = branch.toChar();
libgit2.git_submodule_set_branch(repoPointer, nameC, branchC);
@ -369,7 +370,7 @@ void setIgnore({
required String name,
required int ignore,
}) {
final nameC = name.toNativeUtf8().cast<Int8>();
final nameC = name.toChar();
libgit2.git_submodule_set_ignore(repoPointer, nameC, ignore);
calloc.free(nameC);
}
@ -389,7 +390,7 @@ void setUpdateRule({
required String name,
required int update,
}) {
final nameC = name.toNativeUtf8().cast<Int8>();
final nameC = name.toChar();
libgit2.git_submodule_set_update(repoPointer, nameC, update);
calloc.free(nameC);
}

View file

@ -3,6 +3,7 @@ import 'dart:ffi';
import 'package:ffi/ffi.dart';
import 'package:libgit2dart/src/bindings/libgit2_bindings.dart';
import 'package:libgit2dart/src/error.dart';
import 'package:libgit2dart/src/extensions.dart';
import 'package:libgit2dart/src/util.dart';
/// Fill a list with all the tags in the repository.
@ -12,16 +13,16 @@ List<String> list(Pointer<git_repository> repo) {
final out = calloc<git_strarray>();
final error = libgit2.git_tag_list(out, repo);
final result = <String>[];
if (error < 0) {
calloc.free(out);
throw LibGit2Error(libgit2.git_error_last());
} else {
for (var i = 0; i < out.ref.count; i++) {
result.add(out.ref.strings[i].cast<Utf8>().toDartString());
}
final result = <String>[
for (var i = 0; i < out.ref.count; i++) out.ref.strings[i].toDartString()
];
calloc.free(out);
return result;
}
}
@ -80,13 +81,12 @@ Pointer<git_oid> targetOid(Pointer<git_tag> tag) =>
Pointer<git_oid> id(Pointer<git_tag> tag) => libgit2.git_tag_id(tag);
/// Get the name of a tag.
String name(Pointer<git_tag> tag) =>
libgit2.git_tag_name(tag).cast<Utf8>().toDartString();
String name(Pointer<git_tag> tag) => libgit2.git_tag_name(tag).toDartString();
/// Get the message of a tag.
String message(Pointer<git_tag> tag) {
final result = libgit2.git_tag_message(tag);
return result == nullptr ? '' : result.cast<Utf8>().toDartString();
return result == nullptr ? '' : result.toDartString();
}
/// Get the tagger (author) of a tag. The returned signature must be freed.
@ -115,8 +115,8 @@ Pointer<git_oid> createAnnotated({
required bool force,
}) {
final out = calloc<git_oid>();
final tagNameC = tagName.toNativeUtf8().cast<Int8>();
final messageC = message.toNativeUtf8().cast<Int8>();
final tagNameC = tagName.toChar();
final messageC = message.toChar();
final error = libgit2.git_tag_create(
out,
repoPointer,
@ -155,7 +155,7 @@ Pointer<git_oid> createLightweight({
required bool force,
}) {
final out = calloc<git_oid>();
final tagNameC = tagName.toNativeUtf8().cast<Int8>();
final tagNameC = tagName.toChar();
final error = libgit2.git_tag_create_lightweight(
out,
repoPointer,
@ -183,7 +183,7 @@ void delete({
required Pointer<git_repository> repoPointer,
required String tagName,
}) {
final tagNameC = tagName.toNativeUtf8().cast<Int8>();
final tagNameC = tagName.toChar();
final error = libgit2.git_tag_delete(repoPointer, tagNameC);
calloc.free(tagNameC);

View file

@ -3,6 +3,7 @@ import 'dart:ffi';
import 'package:ffi/ffi.dart';
import 'package:libgit2dart/src/bindings/libgit2_bindings.dart';
import 'package:libgit2dart/src/error.dart';
import 'package:libgit2dart/src/extensions.dart';
import 'package:libgit2dart/src/util.dart';
/// Get the id of a tree.
@ -59,7 +60,7 @@ Pointer<git_tree_entry> getByName({
required Pointer<git_tree> treePointer,
required String filename,
}) {
final filenameC = filename.toNativeUtf8().cast<Int8>();
final filenameC = filename.toChar();
final result = libgit2.git_tree_entry_byname(treePointer, filenameC);
calloc.free(filenameC);
@ -83,7 +84,7 @@ Pointer<git_tree_entry> getByPath({
required String path,
}) {
final out = calloc<Pointer<git_tree_entry>>();
final pathC = path.toNativeUtf8().cast<Int8>();
final pathC = path.toChar();
final error = libgit2.git_tree_entry_bypath(out, rootPointer, pathC);
final result = out.value;
@ -107,7 +108,7 @@ Pointer<git_oid> entryId(Pointer<git_tree_entry> entry) =>
/// Get the filename of a tree entry.
String entryName(Pointer<git_tree_entry> entry) =>
libgit2.git_tree_entry_name(entry).cast<Utf8>().toDartString();
libgit2.git_tree_entry_name(entry).toDartString();
/// Get the UNIX file attributes of a tree entry.
int entryFilemode(Pointer<git_tree_entry> entry) =>

View file

@ -3,6 +3,7 @@ import 'dart:ffi';
import 'package:ffi/ffi.dart';
import 'package:libgit2dart/src/bindings/libgit2_bindings.dart';
import 'package:libgit2dart/src/error.dart';
import 'package:libgit2dart/src/extensions.dart';
import 'package:libgit2dart/src/util.dart';
/// Create a new tree builder. The returned tree builder must be freed with
@ -53,7 +54,7 @@ Pointer<git_tree_entry> getByFilename({
required Pointer<git_treebuilder> builderPointer,
required String filename,
}) {
final filenameC = filename.toNativeUtf8().cast<Int8>();
final filenameC = filename.toChar();
final result = libgit2.git_treebuilder_get(builderPointer, filenameC);
calloc.free(filenameC);
@ -82,7 +83,7 @@ void add({
required Pointer<git_oid> oidPointer,
required int filemode,
}) {
final filenameC = filename.toNativeUtf8().cast<Int8>();
final filenameC = filename.toChar();
final error = libgit2.git_treebuilder_insert(
nullptr,
builderPointer,
@ -105,7 +106,7 @@ void remove({
required Pointer<git_treebuilder> builderPointer,
required String filename,
}) {
final filenameC = filename.toNativeUtf8().cast<Int8>();
final filenameC = filename.toChar();
final error = libgit2.git_treebuilder_remove(builderPointer, filenameC);
calloc.free(filenameC);

View file

@ -4,6 +4,7 @@ import 'package:ffi/ffi.dart';
import 'package:libgit2dart/libgit2dart.dart';
import 'package:libgit2dart/src/bindings/libgit2_bindings.dart';
import 'package:libgit2dart/src/error.dart';
import 'package:libgit2dart/src/extensions.dart';
import 'package:libgit2dart/src/util.dart';
/// Add a new working tree. The returned worktree must be freed with [free].
@ -20,8 +21,8 @@ Pointer<git_worktree> create({
Pointer<git_reference>? refPointer,
}) {
final out = calloc<Pointer<git_worktree>>();
final nameC = name.toNativeUtf8().cast<Int8>();
final pathC = path.toNativeUtf8().cast<Int8>();
final nameC = name.toChar();
final pathC = path.toChar();
final opts = calloc<git_worktree_add_options>();
libgit2.git_worktree_add_options_init(opts, GIT_WORKTREE_ADD_OPTIONS_VERSION);
@ -56,7 +57,7 @@ Pointer<git_worktree> lookup({
required String name,
}) {
final out = calloc<Pointer<git_worktree>>();
final nameC = name.toNativeUtf8().cast<Int8>();
final nameC = name.toChar();
final error = libgit2.git_worktree_lookup(out, repoPointer, nameC);
final result = out.value;
@ -95,8 +96,16 @@ bool isPrunable(Pointer<git_worktree> wt) {
/// Prune working tree.
///
/// Prune the working tree, that is remove the git data structures on disk.
void prune(Pointer<git_worktree> wt) {
libgit2.git_worktree_prune(wt, nullptr);
void prune({required Pointer<git_worktree> worktreePointer, int? flags}) {
final opts = calloc<git_worktree_prune_options>();
libgit2.git_worktree_prune_options_init(
opts,
GIT_WORKTREE_PRUNE_OPTIONS_VERSION,
);
if (flags != null) opts.ref.flags = flags;
libgit2.git_worktree_prune(worktreePointer, opts);
}
/// List names of linked working trees.
@ -110,23 +119,24 @@ List<String> list(Pointer<git_repository> repo) {
calloc.free(out);
throw LibGit2Error(libgit2.git_error_last());
} else {
final result = <String>[];
for (var i = 0; i < out.ref.count; i++) {
result.add(out.ref.strings[i].cast<Utf8>().toDartString());
}
final result = <String>[
for (var i = 0; i < out.ref.count; i++) out.ref.strings[i].toDartString()
];
calloc.free(out);
return result;
}
}
/// Retrieve the name of the worktree.
String name(Pointer<git_worktree> wt) {
return libgit2.git_worktree_name(wt).cast<Utf8>().toDartString();
return libgit2.git_worktree_name(wt).toDartString();
}
/// Retrieve the filesystem path for the worktree.
String path(Pointer<git_worktree> wt) {
return libgit2.git_worktree_path(wt).cast<Utf8>().toDartString();
return libgit2.git_worktree_path(wt).toDartString();
}
/// Check if worktree is locked.

View file

@ -1,10 +1,12 @@
import 'dart:collection';
import 'dart:ffi';
import 'package:ffi/ffi.dart';
import 'package:equatable/equatable.dart';
import 'package:libgit2dart/libgit2dart.dart';
import 'package:libgit2dart/src/bindings/blame.dart' as bindings;
import 'package:libgit2dart/src/bindings/libgit2_bindings.dart';
import 'package:libgit2dart/src/extensions.dart';
import 'package:meta/meta.dart';
class Blame with IterableMixin<BlameHunk> {
/// Returns the blame for a single file.
@ -120,7 +122,8 @@ final _finalizer = Finalizer<Pointer<git_blame>>(
);
// coverage:ignore-end
class BlameHunk {
@immutable
class BlameHunk extends Equatable {
/// Initializes a new instance of the [BlameHunk] class from
/// provided pointer to blame hunk object in memory.
const BlameHunk._(this._blameHunkPointer);
@ -171,8 +174,7 @@ class BlameHunk {
/// Path to the file where this hunk originated, as of the commit specified by
/// [originCommitOid].
String get originPath =>
_blameHunkPointer.ref.orig_path.cast<Utf8>().toDartString();
String get originPath => _blameHunkPointer.ref.orig_path.toDartString();
@override
String toString() {
@ -183,6 +185,19 @@ class BlameHunk {
'originCommitter: $originCommitter, originCommitOid: $originCommitOid, '
'originPath: $originPath}';
}
@override
List<Object?> get props => [
linesCount,
isBoundary,
finalStartLineNumber,
finalCommitter,
finalCommitOid,
originStartLineNumber,
originCommitter,
originCommitOid,
originPath,
];
}
class _BlameIterator implements Iterator<BlameHunk> {

View file

@ -1,14 +1,18 @@
import 'dart:ffi';
import 'package:equatable/equatable.dart';
import 'package:libgit2dart/libgit2dart.dart';
import 'package:libgit2dart/src/bindings/blob.dart' as bindings;
import 'package:libgit2dart/src/bindings/libgit2_bindings.dart';
import 'package:meta/meta.dart';
class Blob {
@immutable
class Blob extends Equatable {
/// Initializes a new instance of [Blob] class from provided pointer to
/// blob object in memory.
///
/// Note: For internal use. Use [Blob.lookup] instead.
@internal
Blob(this._blobPointer) {
_finalizer.attach(this, _blobPointer, detach: this);
}
@ -27,6 +31,7 @@ class Blob {
/// Pointer to memory address for allocated blob object.
///
/// Note: For internal use.
@internal
Pointer<git_blob> get pointer => _blobPointer;
/// Creates a new blob from a [content] string and writes it to ODB.
@ -124,6 +129,9 @@ class Blob {
String toString() {
return 'Blob{oid: $oid, isBinary: $isBinary, size: $size}';
}
@override
List<Object?> get props => [oid];
}
// coverage:ignore-start

View file

@ -1,17 +1,21 @@
import 'dart:ffi';
import 'package:equatable/equatable.dart';
import 'package:libgit2dart/libgit2dart.dart';
import 'package:libgit2dart/src/bindings/branch.dart' as bindings;
import 'package:libgit2dart/src/bindings/libgit2_bindings.dart';
import 'package:libgit2dart/src/bindings/reference.dart' as reference_bindings;
import 'package:meta/meta.dart';
class Branch {
@immutable
class Branch extends Equatable {
/// Initializes a new instance of [Branch] class from provided pointer to
/// branch object in memory.
///
/// Note: For internal use. Instead, use one of:
/// - [Branch.create]
/// - [Branch.lookup]
@internal
Branch(this._branchPointer) {
_finalizer.attach(this, _branchPointer, detach: this);
}
@ -71,6 +75,7 @@ class Branch {
/// Pointer to memory address for allocated branch object.
///
/// Note: For internal use.
@internal
Pointer<git_reference> get pointer => _branchPointer;
/// Returns a list of branches that can be found in a [repo]sitory for
@ -228,6 +233,9 @@ class Branch {
return 'Branch{name: $name, target: $target, isHead: $isHead, '
'isCheckedOut: $isCheckedOut}';
}
@override
List<Object?> get props => [target, name];
}
// coverage:ignore-start

View file

@ -1,15 +1,19 @@
import 'dart:ffi';
import 'package:equatable/equatable.dart';
import 'package:libgit2dart/libgit2dart.dart';
import 'package:libgit2dart/src/bindings/commit.dart' as bindings;
import 'package:libgit2dart/src/bindings/graph.dart' as graph_bindings;
import 'package:libgit2dart/src/bindings/libgit2_bindings.dart';
import 'package:meta/meta.dart';
class Commit {
@immutable
class Commit extends Equatable {
/// Initializes a new instance of [Commit] class from provided pointer to
/// commit object in memory.
///
/// Note: For internal use. Use [Commit.lookup] instead.
@internal
Commit(this._commitPointer) {
_finalizer.attach(this, _commitPointer, detach: this);
}
@ -28,6 +32,7 @@ class Commit {
/// Pointer to memory address for allocated commit object.
///
/// Note: For internal use.
@internal
Pointer<git_commit> get pointer => _commitPointer;
/// Creates new commit in the [repo]sitory.
@ -186,23 +191,64 @@ class Commit {
/// Reverts commit, producing changes in the index and working directory.
///
/// [mainline] is parent of the commit if it is a merge (i.e. 1, 2, etc.).
///
/// [mergeFavor] is one of the optional [GitMergeFileFavor] flags for
/// handling conflicting content.
///
/// [mergeFlags] is optional combination of [GitMergeFlag] flags.
///
/// [mergeFileFlags] is optional combination of [GitMergeFileFlag] flags.
///
/// [checkoutStrategy] is optional combination of [GitCheckout] flags.
///
/// [checkoutDirectory] is optional alternative checkout path to workdir.
///
/// [checkoutPaths] is optional list of files to checkout (by default all
/// paths are processed).
///
/// Throws a [LibGit2Error] if error occured.
void revert() {
void revert({
int mainline = 0,
GitMergeFileFavor? mergeFavor,
Set<GitMergeFlag>? mergeFlags,
Set<GitMergeFileFlag>? mergeFileFlags,
Set<GitCheckout>? checkoutStrategy,
String? checkoutDirectory,
List<String>? checkoutPaths,
}) {
bindings.revert(
repoPointer: bindings.owner(_commitPointer),
commitPointer: _commitPointer,
mainline: mainline,
mergeFavor: mergeFavor?.value,
mergeFlags: mergeFlags?.fold(0, (acc, e) => acc! | e.value),
mergeFileFlags: mergeFileFlags?.fold(0, (acc, e) => acc! | e.value),
checkoutStrategy: checkoutStrategy?.fold(0, (acc, e) => acc! | e.value),
checkoutDirectory: checkoutDirectory,
checkoutPaths: checkoutPaths,
);
}
/// Reverts commit against provided [commit], producing an index that
/// reflects the result of the revert.
///
/// [mainline] is parent of the commit if it is a merge (i.e. 1, 2).
/// [mainline] is parent of the commit if it is a merge (i.e. 1, 2, etc.).
///
/// [mergeFavor] is one of the optional [GitMergeFileFavor] flags for
/// handling conflicting content.
///
/// [mergeFlags] is optional combination of [GitMergeFlag] flags.
///
/// [mergeFileFlags] is optional combination of [GitMergeFileFlag] flags.
///
/// Throws a [LibGit2Error] if error occured.
Index revertTo({
required Commit commit,
int mainline = 0,
GitMergeFileFavor? mergeFavor,
Set<GitMergeFlag>? mergeFlags,
Set<GitMergeFileFlag>? mergeFileFlags,
}) {
return Index(
bindings.revertCommit(
@ -210,6 +256,9 @@ class Commit {
revertCommitPointer: _commitPointer,
ourCommitPointer: commit.pointer,
mainline: mainline,
mergeFavor: mergeFavor?.value,
mergeFlags: mergeFlags?.fold(0, (acc, e) => acc! | e.value),
mergeFileFlags: mergeFileFlags?.fold(0, (acc, e) => acc! | e.value),
),
);
}
@ -261,18 +310,11 @@ class Commit {
/// List of parent commits [Oid]s.
List<Oid> get parents {
final parents = <Oid>[];
final parentCount = bindings.parentCount(_commitPointer);
for (var i = 0; i < parentCount; i++) {
final parentOid = bindings.parentId(
commitPointer: _commitPointer,
position: i,
);
parents.add(Oid(parentOid));
}
return parents;
return <Oid>[
for (var i = 0; i < parentCount; i++)
Oid(bindings.parentId(commitPointer: _commitPointer, position: i))
];
}
/// Returns the specified parent of the commit at provided 0-based [position].
@ -338,6 +380,9 @@ class Commit {
'messageEncoding: $messageEncoding, time: $time, committer: $committer,'
' author: $author}';
}
@override
List<Object?> get props => [oid];
}
// coverage:ignore-start

View file

@ -2,11 +2,14 @@ import 'dart:collection';
import 'dart:ffi';
import 'dart:io';
import 'package:equatable/equatable.dart';
import 'package:ffi/ffi.dart';
import 'package:libgit2dart/libgit2dart.dart';
import 'package:libgit2dart/src/bindings/config.dart' as bindings;
import 'package:libgit2dart/src/bindings/libgit2_bindings.dart';
import 'package:libgit2dart/src/extensions.dart';
import 'package:libgit2dart/src/util.dart';
import 'package:meta/meta.dart';
class Config with IterableMixin<ConfigEntry> {
/// Initializes a new instance of [Config] class from provided
@ -17,6 +20,7 @@ class Config with IterableMixin<ConfigEntry> {
/// - [Config.system]
/// - [Config.global]
/// - [Config.xdg]
@internal
Config(this._configPointer) {
_finalizer.attach(this, _configPointer, detach: this);
}
@ -96,8 +100,8 @@ class Config with IterableMixin<ConfigEntry> {
configPointer: _configPointer,
variable: variable,
);
final name = entryPointer.ref.name.cast<Utf8>().toDartString();
final value = entryPointer.ref.value.cast<Utf8>().toDartString();
final name = entryPointer.ref.name.toDartString();
final value = entryPointer.ref.value.toDartString();
final includeDepth = entryPointer.ref.include_depth;
final level = GitConfigLevel.values.firstWhere(
(e) => entryPointer.ref.level == e.value,
@ -209,8 +213,9 @@ final _finalizer = Finalizer<Pointer<git_config>>(
);
// coverage:ignore-end
class ConfigEntry {
ConfigEntry._({
@immutable
class ConfigEntry extends Equatable {
const ConfigEntry._({
required this.name,
required this.value,
required this.includeDepth,
@ -234,6 +239,9 @@ class ConfigEntry {
return 'ConfigEntry{name: $name, value: $value, '
'includeDepth: $includeDepth, level: $level}';
}
@override
List<Object?> get props => [name, value, includeDepth, level];
}
class _ConfigIterator implements Iterator<ConfigEntry> {
@ -258,8 +266,8 @@ class _ConfigIterator implements Iterator<ConfigEntry> {
} else {
error = libgit2.git_config_next(entry, _iteratorPointer);
if (error != -31) {
final name = entry.value.ref.name.cast<Utf8>().toDartString();
final value = entry.value.ref.value.cast<Utf8>().toDartString();
final name = entry.value.ref.name.toDartString();
final value = entry.value.ref.value.toDartString();
final includeDepth = entry.value.ref.include_depth;
final level = GitConfigLevel.values.firstWhere(
(e) => entry.value.ref.level == e.value,

View file

@ -1,12 +1,15 @@
import 'dart:ffi';
import 'package:ffi/ffi.dart';
import 'package:equatable/equatable.dart';
import 'package:libgit2dart/libgit2dart.dart';
import 'package:libgit2dart/src/bindings/diff.dart' as bindings;
import 'package:libgit2dart/src/bindings/libgit2_bindings.dart';
import 'package:libgit2dart/src/extensions.dart';
import 'package:libgit2dart/src/util.dart';
import 'package:meta/meta.dart';
class Diff {
@immutable
class Diff extends Equatable {
/// Initializes a new instance of [Diff] class from provided
/// pointer to diff object in memory.
///
@ -18,6 +21,7 @@ class Diff {
/// - [Diff.treeToWorkdirWithIndex]
/// - [Diff.treeToTree]
/// - [Diff.parse]
@internal
Diff(this._diffPointer) {
_finalizer.attach(this, _diffPointer, detach: this);
}
@ -273,6 +277,7 @@ class Diff {
/// Pointer to memory address for allocated diff object.
///
/// Note: For internal use.
@internal
Pointer<git_diff> get pointer => _diffPointer;
/// How many diff records are there in a diff.
@ -282,28 +287,18 @@ class Diff {
/// revisions.
List<DiffDelta> get deltas {
final length = bindings.length(_diffPointer);
final deltas = <DiffDelta>[];
for (var i = 0; i < length; i++) {
deltas.add(
DiffDelta(
bindings.getDeltaByIndex(
diffPointer: _diffPointer,
index: i,
),
),
);
}
return deltas;
return <DiffDelta>[
for (var i = 0; i < length; i++)
DiffDelta(bindings.getDeltaByIndex(diffPointer: _diffPointer, index: i))
];
}
/// A List of [Patch]es.
List<Patch> get patches {
final length = bindings.length(_diffPointer);
final patches = <Patch>[];
for (var i = 0; i < length; i++) {
patches.add(Patch.fromDiff(diff: this, index: i));
}
return patches;
return <Patch>[
for (var i = 0; i < length; i++) Patch.fromDiff(diff: this, index: i)
];
}
/// The patch diff text.
@ -461,8 +456,11 @@ class Diff {
@override
String toString() {
return 'Diff{length: $length}';
return 'Diff{length: $length, patchOid: $patchOid}';
}
@override
List<Object?> get props => [patchOid];
}
// coverage:ignore-start
@ -471,9 +469,13 @@ final _finalizer = Finalizer<Pointer<git_diff>>(
);
// coverage:ignore-end
class DiffDelta {
@immutable
class DiffDelta extends Equatable {
/// Initializes a new instance of [DiffDelta] class from provided
/// pointer to diff delta object in memory.
///
/// Note: For internal use.
@internal
const DiffDelta(this._diffDeltaPointer);
/// Pointer to memory address for allocated diff delta object.
@ -519,6 +521,16 @@ class DiffDelta {
return 'DiffDelta{status: $status, flags: $flags, similarity: $similarity, '
'numberOfFiles: $numberOfFiles, oldFile: $oldFile, newFile: $newFile}';
}
@override
List<Object?> get props => [
status,
flags,
similarity,
numberOfFiles,
oldFile,
newFile,
];
}
/// Description of one side of a delta.
@ -526,7 +538,8 @@ class DiffDelta {
/// Although this is called a "file", it could represent a file, a symbolic
/// link, a submodule commit id, or even a tree (although that only if you
/// are tracking type changes or ignored/untracked directories).
class DiffFile {
@immutable
class DiffFile extends Equatable {
/// Initializes a new instance of [DiffFile] class from provided diff file
/// object.
const DiffFile._(this._diffFile);
@ -538,7 +551,7 @@ class DiffFile {
Oid get oid => Oid.fromRaw(_diffFile.id);
/// Path to the entry relative to the working directory of the repository.
String get path => _diffFile.path.cast<Utf8>().toDartString();
String get path => _diffFile.path.toDartString();
/// Size of the entry in bytes.
int get size => _diffFile.size;
@ -560,6 +573,9 @@ class DiffFile {
return 'DiffFile{oid: $oid, path: $path, size: $size, flags: $flags, '
'mode: $mode}';
}
@override
List<Object?> get props => [oid, path, size, flags, mode];
}
class DiffStats {
@ -567,6 +583,7 @@ class DiffStats {
/// pointer to diff stats object in memory.
///
/// Note: For internal use.
@internal
DiffStats(this._diffStatsPointer) {
_statsFinalizer.attach(this, _diffStatsPointer, detach: this);
}

View file

@ -1,17 +1,18 @@
// coverage:ignore-file
import 'dart:ffi';
import 'package:ffi/ffi.dart';
import 'package:libgit2dart/src/bindings/libgit2_bindings.dart';
import 'package:libgit2dart/src/extensions.dart';
import 'package:meta/meta.dart';
/// Details of the last error that occurred.
class LibGit2Error {
/// Note: For internal use.
@internal
LibGit2Error(this._errorPointer);
final Pointer<git_error> _errorPointer;
@override
String toString() {
return _errorPointer.ref.message.cast<Utf8>().toDartString();
}
String toString() => _errorPointer.ref.message.toDartString();
}

36
lib/src/extensions.dart Normal file
View file

@ -0,0 +1,36 @@
// coverage:ignore-file
import 'dart:ffi';
import 'package:ffi/ffi.dart';
import 'package:libgit2dart/src/bindings/libgit2_bindings.dart';
extension IsValidSHA on String {
bool isValidSHA() {
final hexRegExp = RegExp(r'^[0-9a-fA-F]+$');
return hexRegExp.hasMatch(this) &&
(GIT_OID_MINPREFIXLEN <= length && GIT_OID_HEXSZ >= length);
}
}
extension ToChar on String {
/// Creates a zero-terminated [Utf8] code-unit array from this String,
/// casts it to the C `char` type and returns allocated pointer to result.
Pointer<Char> toChar() => toNativeUtf8().cast<Char>();
}
extension ToDartString on Pointer<Char> {
/// Converts this UTF-8 encoded string to a Dart string.
///
/// Decodes the UTF-8 code units of this zero-terminated byte array as
/// Unicode code points and creates a Dart string containing those code
/// points.
///
/// If [length] is provided, zero-termination is ignored and the result can
/// contain NUL characters.
///
/// If [length] is not provided, the returned string is the string up til but
/// not including the first NUL character.
String toDartString({int? length}) =>
cast<Utf8>().toDartString(length: length);
}

View file

@ -1173,3 +1173,37 @@ enum GitBlobFilter {
const GitBlobFilter(this.value);
final int value;
}
/// Flags for APIs that add files matching pathspec.
enum GitIndexAddOption {
defaults(0),
/// Skip the checking of ignore rules.
force(1),
/// Disable glob expansion and force exact matching of files in working
/// directory.
disablePathspecMatch(2),
/// Check that each entry in the pathspec is an exact match to a filename on
/// disk is either not ignored or already in the index.
checkPathspec(4);
const GitIndexAddOption(this.value);
final int value;
}
/// Flags to alter working tree pruning behavior.
enum GitWorktree {
/// Prune working tree even if working tree is valid.
pruneValid(1),
/// Prune working tree even if it is locked.
pruneLocked(2),
/// Prune checked out working tree.
pruneWorkingTree(4);
const GitWorktree(this.value);
final int value;
}

View file

@ -1,16 +1,19 @@
import 'dart:collection';
import 'dart:ffi';
import 'package:ffi/ffi.dart';
import 'package:equatable/equatable.dart';
import 'package:libgit2dart/libgit2dart.dart';
import 'package:libgit2dart/src/bindings/index.dart' as bindings;
import 'package:libgit2dart/src/bindings/libgit2_bindings.dart';
import 'package:libgit2dart/src/extensions.dart';
import 'package:meta/meta.dart';
class Index with IterableMixin<IndexEntry> {
/// Initializes a new instance of [Index] class from provided
/// pointer to index object in memory.
///
/// Note: For internal use.
@internal
Index(this._indexPointer) {
_finalizer.attach(this, _indexPointer, detach: this);
}
@ -29,6 +32,7 @@ class Index with IterableMixin<IndexEntry> {
/// Pointer to memory address for allocated index object.
///
/// Note: For internal use.
@internal
Pointer<git_index> get pointer => _indexPointer;
/// Full path to the index file on disk.
@ -213,9 +217,18 @@ class Index with IterableMixin<IndexEntry> {
/// that matches will be added to the index (either updating an existing
/// entry or adding a new entry).
///
/// [flags] is optional combination of [GitIndexAddOption] flags.
///
/// Throws a [LibGit2Error] if error occured.
void addAll(List<String> pathspec) {
bindings.addAll(indexPointer: _indexPointer, pathspec: pathspec);
void addAll(
List<String> pathspec, {
Set<GitIndexAddOption> flags = const {GitIndexAddOption.defaults},
}) {
bindings.addAll(
indexPointer: _indexPointer,
pathspec: pathspec,
flags: flags.fold(0, (acc, e) => acc | e.value),
);
}
/// Updates all index entries to match the working directory.
@ -323,10 +336,12 @@ final _finalizer = Finalizer<Pointer<git_index>>(
);
// coverage:ignore-end
class IndexEntry {
@immutable
class IndexEntry extends Equatable {
/// Initializes a new instance of [IndexEntry] class.
///
/// Note: For internal use.
@internal
const IndexEntry(this._indexEntryPointer);
final Pointer<git_index_entry> _indexEntryPointer;
@ -334,6 +349,7 @@ class IndexEntry {
/// Pointer to memory address for allocated index entry object.
///
/// Note: For internal use.
@internal
Pointer<git_index_entry> get pointer => _indexEntryPointer;
/// [Oid] of the index entry.
@ -342,10 +358,9 @@ class IndexEntry {
set oid(Oid oid) => _indexEntryPointer.ref.id = oid.pointer.ref;
/// Path of the index entry.
String get path => _indexEntryPointer.ref.path.cast<Utf8>().toDartString();
String get path => _indexEntryPointer.ref.path.toDartString();
set path(String path) =>
_indexEntryPointer.ref.path = path.toNativeUtf8().cast<Int8>();
set path(String path) => _indexEntryPointer.ref.path = path.toChar();
/// UNIX file attributes of a index entry.
GitFilemode get mode {
@ -367,12 +382,16 @@ class IndexEntry {
String toString() {
return 'IndexEntry{oid: $oid, path: $path, mode: $mode, stage: $stage}';
}
@override
List<Object?> get props => [oid, path, mode, stage];
}
class ConflictEntry {
/// Initializes a new instance of [ConflictEntry] class.
///
/// Note: For internal use.
@internal
const ConflictEntry(
this._indexPointer,
this._path,

View file

@ -3,6 +3,7 @@ import 'dart:ffi';
import 'package:ffi/ffi.dart';
import 'package:libgit2dart/libgit2dart.dart';
import 'package:libgit2dart/src/bindings/libgit2_bindings.dart';
import 'package:libgit2dart/src/extensions.dart';
import 'package:libgit2dart/src/util.dart';
class Libgit2 {
@ -12,9 +13,9 @@ class Libgit2 {
static String get version {
libgit2.git_libgit2_init();
final major = calloc<Int32>();
final minor = calloc<Int32>();
final rev = calloc<Int32>();
final major = calloc<Int>();
final minor = calloc<Int>();
final rev = calloc<Int>();
libgit2.git_libgit2_version(major, minor, rev);
final version = '${major.value}.${minor.value}.${rev.value}';
@ -35,28 +36,509 @@ class Libgit2 {
.toSet();
}
/// Maximum mmap window size.
static int get mmapWindowSize {
libgit2.git_libgit2_init();
final out = calloc<Int>();
libgit2Opts.git_libgit2_opts_get_mwindow_size(out);
final result = out.value;
calloc.free(out);
return result;
}
static set mmapWindowSize(int value) {
libgit2.git_libgit2_init();
libgit2Opts.git_libgit2_opts_set_mwindow_size(value);
}
/// Maximum memory that will be mapped in total by the library.
///
/// The default (0) is unlimited.
static int get mmapWindowMappedLimit {
libgit2.git_libgit2_init();
final out = calloc<Int>();
libgit2Opts.git_libgit2_opts_get_mwindow_mapped_limit(out);
final result = out.value;
calloc.free(out);
return result;
}
static set mmapWindowMappedLimit(int value) {
libgit2.git_libgit2_init();
libgit2Opts.git_libgit2_opts_set_mwindow_mapped_limit(value);
}
/// Maximum number of files that will be mapped at any time by the library.
///
/// The default (0) is unlimited.
static int get mmapWindowFileLimit {
libgit2.git_libgit2_init();
final out = calloc<Int>();
libgit2Opts.git_libgit2_opts_get_mwindow_file_limit(out);
final result = out.value;
calloc.free(out);
return result;
}
static set mmapWindowFileLimit(int value) {
libgit2.git_libgit2_init();
libgit2Opts.git_libgit2_opts_set_mwindow_file_limit(value);
}
/// Returns search path for a given [level] of config data.
///
/// [level] must be one of:
/// - [GitConfigLevel.system]
/// - [GitConfigLevel.global]
/// - [GitConfigLevel.xdg]
/// - [GitConfigLevel.programData]
static String getConfigSearchPath(GitConfigLevel level) {
libgit2.git_libgit2_init();
final out = calloc<git_buf>();
libgit2Opts.git_libgit2_opts_get_search_path(level.value, out);
final result = out.ref.ptr.toDartString(length: out.ref.size);
libgit2.git_buf_dispose(out);
calloc.free(out);
return result;
}
/// Sets the search path for a [level] of config data. The search path
/// applied to shared attributes and ignore files.
///
/// [path] lists directories delimited by `:`.
/// Pass null to reset to the default (generally based on environment
/// variables). Use magic path `$PATH` to include the old value of the path
/// (if you want to prepend or append, for instance).
///
/// [level] must be one of:
/// - [GitConfigLevel.system]
/// - [GitConfigLevel.global]
/// - [GitConfigLevel.xdg]
/// - [GitConfigLevel.programData]
static void setConfigSearchPath({
required GitConfigLevel level,
required String? path,
}) {
libgit2.git_libgit2_init();
final pathC = path?.toChar() ?? nullptr;
libgit2Opts.git_libgit2_opts_set_search_path(level.value, pathC);
calloc.free(pathC);
}
/// Sets the maximum data size for the given [type] of object to be
/// considered eligible for caching in memory. Setting the [value] to
/// zero means that that type of object will not be cached.
///
/// Defaults to 0 for [GitObject.blob] (i.e. won't cache blobs) and 4k
/// for [GitObject.commit], [GitObject.tree] and [GitObject.tag].
static void setCacheObjectLimit({
required GitObject type,
required int value,
}) {
libgit2.git_libgit2_init();
libgit2Opts.git_libgit2_opts_set_cache_object_limit(type.value, value);
}
/// Sets the maximum total data size that will be cached in memory
/// across all repositories before libgit2 starts evicting objects
/// from the cache. This is a soft limit, in that the library might
/// briefly exceed it, but will start aggressively evicting objects
/// from cache when that happens.
///
/// The default cache size is 256MB.
static void setCacheMaxSize(int bytes) {
libgit2.git_libgit2_init();
libgit2Opts.git_libgit2_opts_set_cache_max_size(bytes);
}
/// [CachedMemory] object containing current bytes in cache and the maximum
/// that would be allowed in the cache.
static CachedMemory get cachedMemory {
libgit2.git_libgit2_init();
final current = calloc<Int>();
final allowed = calloc<Int>();
libgit2Opts.git_libgit2_opts_get_cached_memory(current, allowed);
final result = CachedMemory._(
current: current.value,
allowed: allowed.value,
);
calloc.free(current);
calloc.free(allowed);
return result;
}
/// Enables caching.
static void enableCaching() {
libgit2.git_libgit2_init();
libgit2Opts.git_libgit2_opts_enable_caching(1);
}
/// Disables caching completely.
///
/// Because caches are repository-specific, disabling the cache
/// cannot immediately clear all cached objects, but each cache will
/// be cleared on the next attempt to update anything in it.
static void disableCaching() {
libgit2.git_libgit2_init();
libgit2Opts.git_libgit2_opts_enable_caching(0);
}
/// Default template path.
static String get templatePath {
libgit2.git_libgit2_init();
final out = calloc<git_buf>();
libgit2Opts.git_libgit2_opts_get_template_path(out);
final result = out.ref.ptr.toDartString(length: out.ref.size);
libgit2.git_buf_dispose(out);
calloc.free(out);
return result;
}
static set templatePath(String path) {
libgit2.git_libgit2_init();
final pathC = path.toChar();
libgit2Opts.git_libgit2_opts_set_template_path(pathC);
calloc.free(pathC);
}
/// Sets the SSL certificate-authority locations.
///
/// - [file] is the location of a file containing several
/// certificates concatenated together.
/// - [path] is the location of a directory holding several
/// certificates, one per file.
///
/// Either parameter may be null, but not both.
///
/// Throws [ArgumentError] if both arguments are null.
static void setSSLCertLocations({String? file, String? path}) {
if (file == null && path == null) {
throw ArgumentError("Both file and path can't be null");
} else {
libgit2.git_libgit2_init();
final fileC = file?.toChar() ?? nullptr;
final pathC = path?.toChar() ?? nullptr;
libgit2Opts.git_libgit2_opts_set_ssl_cert_locations(fileC, pathC);
calloc.free(fileC);
calloc.free(pathC);
}
}
/// Value of the User-Agent header.
///
/// This value will be appended to "git/1.0", for compatibility with other
/// git clients.
static String get userAgent {
libgit2.git_libgit2_init();
final out = calloc<git_buf>();
libgit2Opts.git_libgit2_opts_get_user_agent(out);
final result = out.ref.ptr.toDartString(length: out.ref.size);
libgit2.git_buf_dispose(out);
calloc.free(out);
return result;
}
static set userAgent(String userAgent) {
libgit2.git_libgit2_init();
final userAgentC = userAgent.toChar();
libgit2Opts.git_libgit2_opts_set_user_agent(userAgentC);
calloc.free(userAgentC);
}
/// Enables strict input validation when creating new objects
/// to ensure that all inputs to the new objects are valid.
///
/// For example, when this is enabled, the parent(s) and tree inputs
/// will be validated when creating a new commit.
///
/// Enabled by default.
static void enableStrictObjectCreation() {
libgit2.git_libgit2_init();
libgit2Opts.git_libgit2_opts_enable_strict_object_creation(1);
}
/// Disables strict input validation when creating new objects.
///
/// Enabled by default.
static void disableStrictObjectCreation() {
libgit2.git_libgit2_init();
libgit2Opts.git_libgit2_opts_enable_strict_object_creation(0);
}
/// Enables validation of a symbolic ref target when creating it.
///
/// For example, `foobar` is not a valid ref, therefore `foobar` is
/// not a valid target for a symbolic ref by default, whereas
/// `refs/heads/foobar` is.
///
/// Disabling this bypasses validation so that an arbitrary strings
/// such as `foobar` can be used for a symbolic ref target.
///
/// Enabled by default.
static void enableStrictSymbolicRefCreation() {
libgit2.git_libgit2_init();
libgit2Opts.git_libgit2_opts_enable_strict_symbolic_ref_creation(1);
}
/// Disables validation of a symbolic ref target when creating it.
///
/// For example, `foobar` is not a valid ref, therefore `foobar` is
/// not a valid target for a symbolic ref by default, whereas
/// `refs/heads/foobar` is.
///
/// Disabling this bypasses validation so that an arbitrary strings
/// such as `foobar` can be used for a symbolic ref target.
///
/// Enabled by default.
static void disableStrictSymbolicRefCreation() {
libgit2.git_libgit2_init();
libgit2Opts.git_libgit2_opts_enable_strict_symbolic_ref_creation(0);
}
/// Enables the use of "offset deltas" when creating packfiles,
/// and the negotiation of them when talking to a remote server.
///
/// Offset deltas store a delta base location as an offset into the
/// packfile from the current location, which provides a shorter encoding
/// and thus smaller resultant packfiles.
///
/// Enabled by default.
static void enableOffsetDelta() {
libgit2.git_libgit2_init();
libgit2Opts.git_libgit2_opts_enable_offset_delta(1);
}
/// Disables the use of "offset deltas" when creating packfiles,
/// and the negotiation of them when talking to a remote server.
///
/// Offset deltas store a delta base location as an offset into the
/// packfile from the current location, which provides a shorter encoding
/// and thus smaller resultant packfiles.
///
/// Packfiles containing offset deltas can still be read.
///
/// Enabled by default.
static void disableOffsetDelta() {
libgit2.git_libgit2_init();
libgit2Opts.git_libgit2_opts_enable_offset_delta(0);
}
/// Enables synchronized writes of files in the gitdir using `fsync`
/// (or the platform equivalent) to ensure that new object data
/// is written to permanent storage, not simply cached.
///
/// Disabled by default.
static void enableFsyncGitdir() {
libgit2.git_libgit2_init();
libgit2Opts.git_libgit2_opts_enable_fsync_gitdir(1);
}
/// Disables synchronized writes of files in the gitdir using `fsync`
/// (or the platform equivalent).
///
/// Disabled by default.
static void disableFsyncGitdir() {
libgit2.git_libgit2_init();
libgit2Opts.git_libgit2_opts_enable_fsync_gitdir(0);
}
/// Enables strict verification of object hashsums when reading objects from
/// disk.
///
/// This may impact performance due to an additional checksum calculation
/// on each object.
///
/// Enabled by default.
static void enableStrictHashVerification() {
libgit2.git_libgit2_init();
libgit2Opts.git_libgit2_opts_enable_strict_hash_verification(1);
}
/// Disables strict verification of object hashsums when reading objects from
/// disk.
///
/// Enabled by default.
static void disableStrictHashVerification() {
libgit2.git_libgit2_init();
libgit2Opts.git_libgit2_opts_enable_strict_hash_verification(0);
}
/// Enables check for unsaved changes in the index before beginning any
/// operation that reloads the index from disk (e.g., checkout).
///
/// If there are unsaved changes, the instruction will fail (using
/// the FORCE flag to checkout will still overwrite these changes).
///
/// Enabled by default.
static void enableUnsavedIndexSafety() {
libgit2.git_libgit2_init();
libgit2Opts.git_libgit2_opts_enable_unsaved_index_safety(1);
}
/// Disables check for unsaved changes in the index before beginning any
/// operation that reloads the index from disk (e.g., checkout).
///
/// If there are unsaved changes, the instruction will fail (using
/// the FORCE flag to checkout will still overwrite these changes).
///
/// Enabled by default.
static void disableUnsavedIndexSafety() {
libgit2.git_libgit2_init();
libgit2Opts.git_libgit2_opts_enable_unsaved_index_safety(0);
}
/// Maximum number of objects libgit2 will allow in a pack file when
/// downloading a pack file from a remote. This can be used to limit maximum
/// memory usage when fetching from an untrusted remote.
static int get packMaxObjects {
libgit2.git_libgit2_init();
final out = calloc<Int>();
libgit2Opts.git_libgit2_opts_get_pack_max_objects(out);
final result = out.value;
calloc.free(out);
return result;
}
static set packMaxObjects(int value) {
libgit2.git_libgit2_init();
libgit2Opts.git_libgit2_opts_set_pack_max_objects(value);
}
/// Enables checks of .keep file existence to be skipped when accessing
/// packfiles.
static void enablePackKeepFileChecks() {
libgit2.git_libgit2_init();
libgit2Opts.git_libgit2_opts_disable_pack_keep_file_checks(0);
}
/// Disables checks of .keep file existence to be skipped when accessing
/// packfiles, which can help performance with remote filesystems.
static void disablePackKeepFileChecks() {
libgit2.git_libgit2_init();
libgit2Opts.git_libgit2_opts_disable_pack_keep_file_checks(1);
}
/// When connecting to a server using NTLM or Negotiate
/// authentication, use expect/continue when POSTing data.
///
/// This option is not available on Windows.
static void enableHttpExpectContinue() {
libgit2.git_libgit2_init();
libgit2Opts.git_libgit2_opts_enable_http_expect_continue(1);
}
/// When connecting to a server using NTLM or Negotiate
/// authentication, don't use expect/continue when POSTing data.
///
/// This option is not available on Windows.
static void disableHttpExpectContinue() {
libgit2.git_libgit2_init();
libgit2Opts.git_libgit2_opts_enable_http_expect_continue(0);
}
/// List of git extensions that are supported.
///
/// This is the list of built-in extensions supported by libgit2 and
/// custom extensions that have been added.
///
/// Extensions supported by libgit2 may be negated by prefixing
/// them with a `!`. For example: setting extensions to
/// `"!noop", "newext"` indicates that the caller does not want
/// to support repositories with the `noop` extension but does want
/// to support repositories with the `newext` extension.
///
/// Extensions that have been negated will not be returned.
static List<String> get extensions {
libgit2.git_libgit2_init();
final array = calloc<git_strarray>();
libgit2Opts.git_libgit2_opts_get_extensions(array);
final result = <String>[
for (var i = 0; i < array.ref.count; i++)
array.ref.strings.elementAt(i).value.toDartString()
];
calloc.free(array);
return result;
}
static set extensions(List<String> extensions) {
libgit2.git_libgit2_init();
final array = calloc<Pointer<Char>>(extensions.length);
for (var i = 0; i < extensions.length; i++) {
array[i] = extensions[i].toChar();
}
libgit2Opts.git_libgit2_opts_set_extensions(array, extensions.length);
for (var i = 0; i < extensions.length; i++) {
calloc.free(array[i]);
}
calloc.free(array);
}
/// Owner validation setting for repository directories.
///
/// Enabled by default.
static bool get ownerValidation {
libgit2.git_libgit2_init();
final out = calloc<Int8>();
libgit2.git_libgit2_opts(
git_libgit2_opt_t.GIT_OPT_GET_OWNER_VALIDATION,
out,
);
final out = calloc<Int>();
libgit2Opts.git_libgit2_opts_get_owner_validation(out);
final result = out.value;
calloc.free(out);
return result == 1 || false;
}
/// Sets owner validation setting for repository directories.
static set ownerValidation(bool value) {
libgit2.git_libgit2_init();
final valueC = value ? 1 : 0;
libgit2.git_libgit2_opts_set(
git_libgit2_opt_t.GIT_OPT_SET_OWNER_VALIDATION,
valueC,
);
libgit2Opts.git_libgit2_opts_set_owner_validation(valueC);
}
}
/// Current bytes in cache and the maximum that would be allowed in the cache.
class CachedMemory {
const CachedMemory._({required this.current, required this.allowed});
final int current;
final int allowed;
@override
String toString() {
return 'CachedMemory{current: $current, allowed: $allowed}';
}
}

View file

@ -265,18 +265,43 @@ class Merge {
/// given common [ancestor] as the baseline, producing a string that reflects
/// the merge result containing possible conflicts.
///
/// [ancestorLabel] is optional label for the ancestor file side of the
/// conflict which will be prepended to labels in diff3-format merge files.
///
/// [oursLabel] is optional label for our file side of the conflict which
/// will be prepended to labels in merge files.
///
/// [theirsLabel] is optional label for their file side of the conflict which
/// will be prepended to labels in merge files.
///
/// [favor] is one of the [GitMergeFileFavor] flags for handling conflicting
/// content. Defaults to [GitMergeFileFavor.normal].
///
/// [flags] is a combination of [GitMergeFileFlag] flags. Defaults to
/// [GitMergeFileFlag.defaults].
///
/// Throws a [LibGit2Error] if error occured.
static String fileFromIndex({
required Repository repo,
required IndexEntry? ancestor,
String ancestorLabel = '',
required IndexEntry ours,
String oursLabel = '',
required IndexEntry theirs,
String theirsLabel = '',
GitMergeFileFavor favor = GitMergeFileFavor.normal,
Set<GitMergeFileFlag> flags = const {GitMergeFileFlag.defaults},
}) {
return bindings.mergeFileFromIndex(
repoPointer: repo.pointer,
ancestorPointer: ancestor?.pointer,
ancestorLabel: ancestorLabel,
oursPointer: ours.pointer,
oursLabel: oursLabel,
theirsPointer: theirs.pointer,
theirsLabel: theirsLabel,
favor: favor.value,
flags: flags.fold(0, (acc, e) => acc | e.value),
);
}

View file

@ -1,13 +1,17 @@
import 'dart:ffi';
import 'package:equatable/equatable.dart';
import 'package:libgit2dart/libgit2dart.dart';
import 'package:libgit2dart/src/bindings/libgit2_bindings.dart';
import 'package:libgit2dart/src/bindings/note.dart' as bindings;
import 'package:meta/meta.dart';
class Note {
@immutable
class Note extends Equatable {
/// Initializes a new instance of the [Note] class from provided
/// pointer to note and annotatedOid objects in memory.
///
/// Note: For internal use. Use [Note.lookup] instead.
@internal
Note(this._notePointer, this._annotatedOidPointer) {
_finalizer.attach(this, _notePointer, detach: this);
}
@ -111,9 +115,17 @@ class Note {
/// Returns list of notes for [repo]sitory.
///
/// [notesRef] is the canonical name of the reference to use. Defaults to "refs/notes/commits".
///
/// Throws a [LibGit2Error] if error occured.
static List<Note> list(Repository repo) {
final notesPointers = bindings.list(repo.pointer);
static List<Note> list(
Repository repo, {
String notesRef = 'refs/notes/commits',
}) {
final notesPointers = bindings.list(
repoPointer: repo.pointer,
notesRef: notesRef,
);
return notesPointers
.map(
(e) => Note(
@ -143,6 +155,9 @@ class Note {
String toString() {
return 'Note{oid: $oid, message: $message, annotatedOid: $annotatedOid}';
}
@override
List<Object?> get props => [oid];
}
// coverage:ignore-start

View file

@ -1,14 +1,18 @@
import 'dart:ffi';
import 'package:equatable/equatable.dart';
import 'package:libgit2dart/libgit2dart.dart';
import 'package:libgit2dart/src/bindings/libgit2_bindings.dart';
import 'package:libgit2dart/src/bindings/odb.dart' as bindings;
import 'package:libgit2dart/src/util.dart';
import 'package:meta/meta.dart';
class Odb {
@immutable
class Odb extends Equatable {
/// Initializes a new instance of [Odb] class from provided
/// pointer to Odb object in memory.
///
/// Note: For internal use.
@internal
Odb(this._odbPointer) {
_finalizer.attach(this, _odbPointer, detach: this);
}
@ -29,6 +33,7 @@ class Odb {
/// Pointer to memory address for allocated oid object.
///
/// Note: For internal use.
@internal
Pointer<git_odb> get pointer => _odbPointer;
/// Adds an on-disk alternate to an existing Object DB.
@ -101,6 +106,9 @@ class Odb {
bindings.free(_odbPointer);
_finalizer.detach(this);
}
@override
List<Object?> get props => [objects];
}
// coverage:ignore-start
@ -109,7 +117,8 @@ final _finalizer = Finalizer<Pointer<git_odb>>(
);
// coverage:ignore-end
class OdbObject {
@immutable
class OdbObject extends Equatable {
/// Initializes a new instance of the [OdbObject] class from
/// provided pointer to odbObject object in memory.
OdbObject._(this._odbObjectPointer) {
@ -144,6 +153,9 @@ class OdbObject {
String toString() {
return 'OdbObject{oid: $oid, type: $type, size: $size}';
}
@override
List<Object?> get props => [oid];
}
// coverage:ignore-start

View file

@ -1,18 +1,20 @@
import 'dart:ffi';
import 'package:equatable/equatable.dart';
import 'package:libgit2dart/libgit2dart.dart';
import 'package:libgit2dart/src/bindings/libgit2_bindings.dart';
import 'package:libgit2dart/src/bindings/odb.dart' as odb_bindings;
import 'package:libgit2dart/src/bindings/oid.dart' as bindings;
import 'package:libgit2dart/src/util.dart';
import 'package:libgit2dart/src/extensions.dart';
import 'package:meta/meta.dart';
@immutable
class Oid {
class Oid extends Equatable {
/// Initializes a new instance of [Oid] class from provided
/// pointer to Oid object in memory.
///
/// Note: For internal use. Use [Oid.fromSHA] instead.
@internal
Oid(this._oidPointer);
/// Initializes a new instance of [Oid] class by determining if an object can
@ -23,7 +25,7 @@ class Oid {
///
/// Throws a [LibGit2Error] if error occured.
Oid.fromSHA({required Repository repo, required String sha}) {
if (isValidShaHex(sha)) {
if (sha.isValidSHA()) {
if (sha.length == 40) {
_oidPointer = bindings.fromSHA(sha);
} else {
@ -40,6 +42,9 @@ class Oid {
/// Initializes a new instance of [Oid] class from provided raw git_oid
/// structure.
///
/// Note: For internal use.
@internal
Oid.fromRaw(git_oid raw) {
_oidPointer = bindings.fromRaw(raw.id);
}
@ -49,18 +54,12 @@ class Oid {
/// Pointer to memory address for allocated oid object.
///
/// Note: For internal use.
@internal
Pointer<git_oid> get pointer => _oidPointer;
/// Hexadecimal SHA string.
String get sha => bindings.toSHA(_oidPointer);
@override
bool operator ==(Object other) {
return (other is Oid) &&
(bindings.compare(aPointer: _oidPointer, bPointer: other._oidPointer) ==
0);
}
bool operator <(Oid other) {
return bindings.compare(
aPointer: _oidPointer,
@ -93,9 +92,9 @@ class Oid {
1;
}
@override // coverage:ignore-line
int get hashCode => _oidPointer.address.hashCode; // coverage:ignore-line
@override
String toString() => 'Oid{sha: $sha}';
@override
List<Object?> get props => [sha];
}

View file

@ -2,6 +2,7 @@ import 'dart:ffi';
import 'package:libgit2dart/libgit2dart.dart';
import 'package:libgit2dart/src/bindings/libgit2_bindings.dart';
import 'package:libgit2dart/src/bindings/packbuilder.dart' as bindings;
import 'package:meta/meta.dart';
class PackBuilder {
/// Initializes a new instance of [PackBuilder] class.
@ -9,6 +10,7 @@ class PackBuilder {
/// Throws a [LibGit2Error] if error occured.
///
/// Note: For internal use.
@internal
PackBuilder(Repository repo) {
_packbuilderPointer = bindings.init(repo.pointer);
_finalizer.attach(this, _packbuilderPointer, detach: this);

View file

@ -1,12 +1,15 @@
import 'dart:ffi';
import 'package:equatable/equatable.dart';
import 'package:ffi/ffi.dart';
import 'package:libgit2dart/libgit2dart.dart';
import 'package:libgit2dart/src/bindings/libgit2_bindings.dart';
import 'package:libgit2dart/src/bindings/patch.dart' as bindings;
import 'package:libgit2dart/src/util.dart';
import 'package:meta/meta.dart';
class Patch {
@immutable
class Patch extends Equatable {
/// Initializes a new instance of [Patch] class from provided
/// pointer to patch object in memory and pointers to old and new blobs/buffers.
///
@ -15,6 +18,7 @@ class Patch {
/// - [Patch.fromBlobAndBuffer]
/// - [Patch.fromBuffers]
/// - [Patch.fromDiff]
@internal
Patch(this._patchPointer) {
_finalizer.attach(this, _patchPointer, detach: this);
}
@ -234,10 +238,10 @@ class Patch {
);
}
final intHeader = <int>[];
for (var i = 0; i < hunkPointer.ref.header_len; i++) {
intHeader.add(hunkPointer.ref.header[i]);
}
final intHeader = <int>[
for (var i = 0; i < hunkPointer.ref.header_len; i++)
hunkPointer.ref.header[i]
];
hunks.add(
DiffHunk._(
@ -264,6 +268,9 @@ class Patch {
@override
String toString() => 'Patch{size: ${size()}, delta: $delta}';
@override
List<Object?> get props => [delta];
}
// coverage:ignore-start
@ -296,7 +303,8 @@ class PatchStats {
}
}
class DiffHunk {
@immutable
class DiffHunk extends Equatable {
const DiffHunk._({
required this.linesCount,
required this.index,
@ -338,9 +346,22 @@ class DiffHunk {
'oldStart: $oldStart, oldLines: $oldLines, newStart: $newStart, '
'newLines: $newLines, header: $header}';
}
@override
List<Object?> get props => [
linesCount,
index,
oldStart,
oldLines,
newStart,
newLines,
header,
lines
];
}
class DiffLine {
@immutable
class DiffLine extends Equatable {
const DiffLine._({
required this.origin,
required this.oldLineNumber,
@ -374,4 +395,14 @@ class DiffLine {
'newLineNumber: $newLineNumber, numLines: $numLines, '
'contentOffset: $contentOffset, content: $content}';
}
@override
List<Object?> get props => [
origin,
oldLineNumber,
newLineNumber,
numLines,
contentOffset,
content,
];
}

View file

@ -47,18 +47,13 @@ class Rebase {
/// List of operations that are to be applied.
List<RebaseOperation> get operations {
final result = <RebaseOperation>[];
final operationsCount = bindings.operationsCount(_rebasePointer);
for (var i = 0; i < operationsCount; i++) {
final operation = bindings.getOperationByIndex(
rebase: _rebasePointer,
index: i,
);
result.add(RebaseOperation._(operation));
}
return result;
return <RebaseOperation>[
for (var i = 0; i < operationsCount; i++)
RebaseOperation._(
bindings.getOperationByIndex(rebase: _rebasePointer, index: i),
)
];
}
/// Index of the rebase operation that is currently being applied. If the

View file

@ -1,5 +1,6 @@
import 'dart:ffi';
import 'package:equatable/equatable.dart';
import 'package:libgit2dart/libgit2dart.dart';
import 'package:libgit2dart/src/bindings/libgit2_bindings.dart';
import 'package:libgit2dart/src/bindings/object.dart' as object_bindings;
@ -7,13 +8,16 @@ import 'package:libgit2dart/src/bindings/refdb.dart' as refdb_bindings;
import 'package:libgit2dart/src/bindings/reference.dart' as bindings;
import 'package:libgit2dart/src/bindings/repository.dart'
as repository_bindings;
import 'package:meta/meta.dart';
class Reference {
@immutable
class Reference extends Equatable {
/// Initializes a new instance of the [Reference] class.
///
/// Note: For internal use. Instead, use one of:
/// - [Reference.create]
/// - [Reference.lookup]
@internal
Reference(this._refPointer) {
_finalizer.attach(this, _refPointer, detach: this);
}
@ -79,11 +83,12 @@ class Reference {
_finalizer.attach(this, _refPointer, detach: this);
}
late Pointer<git_reference> _refPointer;
late final Pointer<git_reference> _refPointer;
/// Pointer to memory address for allocated reference object.
///
/// Note: For internal use.
@internal
Pointer<git_reference> get pointer => _refPointer;
/// Deletes an existing reference with provided [name].
@ -124,6 +129,39 @@ class Reference {
);
}
/// Updates the [target] of reference with provided [name].
///
/// [target] being either Oid for direct reference or string reference name
/// for symbolic reference.
///
/// Throws a [LibGit2Error] if error occured or [ArgumentError] if [target]
/// is not [Oid] or string.
static void setTarget({
required Repository repo,
required String name,
required Object target,
String? logMessage,
}) {
final ref = Reference.lookup(repo: repo, name: name);
if (target is Oid) {
bindings.setTarget(
refPointer: ref.pointer,
oidPointer: target.pointer,
logMessage: logMessage,
);
} else if (target is String) {
bindings.setTargetSymbolic(
refPointer: ref.pointer,
target: target,
logMessage: logMessage,
);
} else {
throw ArgumentError.value(
'$target must be either Oid or String reference name',
);
}
}
/// List of all the references names that can be found in a [repo]sitory.
///
/// Throws a [LibGit2Error] if error occured.
@ -167,43 +205,9 @@ class Reference {
///
/// Throws an [Exception] if error occured.
Oid get target {
late final Pointer<git_oid> oidPointer;
if (type == ReferenceType.direct) {
oidPointer = bindings.target(_refPointer);
} else {
oidPointer = bindings.target(bindings.resolve(_refPointer));
}
return Oid(oidPointer);
}
/// Updates the [target] of this reference.
///
/// [target] being either Oid for direct reference or string reference name
/// for symbolic reference.
///
/// Throws a [LibGit2Error] if error occured or [ArgumentError] if [target]
/// is not [Oid] or string.
void setTarget({required Object target, String? logMessage}) {
if (target is Oid) {
final newPointer = bindings.setTarget(
refPointer: _refPointer,
oidPointer: target.pointer,
logMessage: logMessage,
);
_refPointer = newPointer;
} else if (target is String) {
final newPointer = bindings.setTargetSymbolic(
refPointer: _refPointer,
target: target,
logMessage: logMessage,
);
_refPointer = newPointer;
} else {
throw ArgumentError.value(
'$target must be either Oid or String reference name',
);
}
return type == ReferenceType.direct
? Oid(bindings.target(_refPointer))
: Oid(bindings.target(bindings.resolve(_refPointer)));
}
/// Recursively peel reference until object of the specified [type] is found.
@ -272,17 +276,6 @@ class Reference {
/// Whether reference is a tag.
bool get isTag => bindings.isTag(_refPointer);
/// Compares two references.
bool equals(Reference other) {
return bindings.compare(
ref1Pointer: _refPointer,
ref2Pointer: other._refPointer,
);
}
/// Compares two references.
bool notEquals(Reference other) => !equals(other);
/// Releases memory allocated for reference object.
void free() {
bindings.free(_refPointer);
@ -295,6 +288,9 @@ class Reference {
'isBranch: $isBranch, isNote: $isNote, isRemote: $isRemote, '
'isTag: $isTag}';
}
@override
List<Object?> get props => [target];
}
// coverage:ignore-start

View file

@ -1,9 +1,11 @@
import 'dart:collection';
import 'dart:ffi';
import 'package:equatable/equatable.dart';
import 'package:libgit2dart/libgit2dart.dart';
import 'package:libgit2dart/src/bindings/libgit2_bindings.dart';
import 'package:libgit2dart/src/bindings/reference.dart' as reference_bindings;
import 'package:libgit2dart/src/bindings/reflog.dart' as bindings;
import 'package:meta/meta.dart';
class RefLog with IterableMixin<RefLogEntry> {
/// Initializes a new instance of [RefLog] class from provided [Reference].
@ -109,7 +111,8 @@ final _finalizer = Finalizer<Pointer<git_reflog>>(
);
// coverage:ignore-end
class RefLogEntry {
@immutable
class RefLogEntry extends Equatable {
/// Initializes a new instance of [RefLogEntry] class from provided
/// pointer to RefLogEntry object in memory.
const RefLogEntry._(this._entryPointer);
@ -133,6 +136,9 @@ class RefLogEntry {
@override
String toString() => 'RefLogEntry{message: $message, committer: $committer}';
@override
List<Object?> get props => [message, committer, newOid, oldOid];
}
class _RefLogIterator implements Iterator<RefLogEntry> {

View file

@ -1,13 +1,17 @@
import 'dart:ffi';
import 'package:equatable/equatable.dart';
import 'package:libgit2dart/libgit2dart.dart';
import 'package:libgit2dart/src/bindings/libgit2_bindings.dart';
import 'package:libgit2dart/src/bindings/refspec.dart' as bindings;
import 'package:meta/meta.dart';
class Refspec {
@immutable
class Refspec extends Equatable {
/// Initializes a new instance of the [Refspec] class
/// from provided pointer to refspec object in memory.
///
/// Note: For internal use.
@internal
const Refspec(this._refspecPointer);
/// Pointer to memory address for allocated refspec object.
@ -72,6 +76,9 @@ class Refspec {
@override
String toString() {
return 'Refspec{source: $source, destination: $destination, force: $force, '
'string: $string}';
'string: $string, direction: $direction}';
}
@override
List<Object?> get props => [source, destination, force, string, direction];
}

View file

@ -1,9 +1,12 @@
import 'dart:ffi';
import 'package:equatable/equatable.dart';
import 'package:libgit2dart/libgit2dart.dart';
import 'package:libgit2dart/src/bindings/libgit2_bindings.dart';
import 'package:libgit2dart/src/bindings/remote.dart' as bindings;
import 'package:meta/meta.dart';
class Remote {
@immutable
class Remote extends Equatable {
/// Lookups remote with provided [name] in a [repo]sitory.
///
/// The [name] will be checked for validity.
@ -208,20 +211,16 @@ class Remote {
final refs = bindings.lsRemotes(_remotePointer);
bindings.disconnect(_remotePointer);
final result = <RemoteReference>[];
for (final ref in refs) {
result.add(
return <RemoteReference>[
for (final ref in refs)
RemoteReference._(
isLocal: ref['local']! as bool,
localId: ref['loid'] as Oid?,
name: ref['name']! as String,
oid: ref['oid']! as Oid,
symRef: ref['symref']! as String,
),
);
}
return result;
)
];
}
/// Downloads new data and updates tips.
@ -310,6 +309,9 @@ class Remote {
return 'Remote{name: $name, url: $url, pushUrl: $pushUrl, '
'refspecCount: $refspecCount}';
}
@override
List<Object?> get props => [name];
}
// coverage:ignore-start
@ -325,6 +327,7 @@ class TransferProgress {
/// pointer to transfer progress object in memory.
///
/// Note: For internal use.
@internal
const TransferProgress(this._transferProgressPointer);
/// Pointer to memory address for allocated transfer progress object.
@ -378,7 +381,8 @@ class RemoteCallback {
final String? fetch;
}
class RemoteReference {
@immutable
class RemoteReference extends Equatable {
const RemoteReference._({
required this.isLocal,
required this.localId,
@ -408,4 +412,7 @@ class RemoteReference {
return 'RemoteReference{isLocal: $isLocal, localId: $localId, '
'name: $name, oid: $oid, symRef: $symRef}';
}
@override
List<Object?> get props => [isLocal, localId, name, oid, symRef];
}

View file

@ -1,8 +1,8 @@
import 'dart:ffi';
import 'package:equatable/equatable.dart';
import 'package:ffi/ffi.dart';
import 'package:libgit2dart/libgit2dart.dart';
import 'package:libgit2dart/src/bindings/attr.dart' as attr_bindings;
import 'package:libgit2dart/src/bindings/describe.dart' as describe_bindings;
import 'package:libgit2dart/src/bindings/graph.dart' as graph_bindings;
@ -12,8 +12,10 @@ import 'package:libgit2dart/src/bindings/repository.dart' as bindings;
import 'package:libgit2dart/src/bindings/reset.dart' as reset_bindings;
import 'package:libgit2dart/src/bindings/status.dart' as status_bindings;
import 'package:libgit2dart/src/util.dart';
import 'package:meta/meta.dart';
class Repository {
@immutable
class Repository extends Equatable {
/// Initializes a new instance of the [Repository] class from provided
/// pointer to repository object in memory.
///
@ -21,6 +23,7 @@ class Repository {
/// - [Repository.init]
/// - [Repository.open]
/// - [Repository.clone]
@internal
Repository(Pointer<git_repository> pointer) {
_repoPointer = pointer;
_finalizer.attach(this, _repoPointer, detach: this);
@ -159,6 +162,7 @@ class Repository {
/// Pointer to memory address for allocated repository object.
///
/// Note: For internal use.
@internal
Pointer<git_repository> get pointer => _repoPointer;
/// Looks for a git repository and return its path. The lookup start from
@ -553,8 +557,23 @@ class Repository {
///
/// [resetType] is one of the [GitReset] flags.
///
/// [strategy], [checkoutDirectory] and [pathspec] are optional checkout
/// options to be used for a HARD reset.
///
/// [strategy] is optional combination of [GitCheckout] flags.
///
/// [checkoutDirectory] is optional alternative checkout path to workdir.
///
/// [pathspec] is optional list of files to checkout.
///
/// Throws a [LibGit2Error] if error occured.
void reset({required Oid oid, required GitReset resetType}) {
void reset({
required Oid oid,
required GitReset resetType,
Set<GitCheckout>? strategy,
String? checkoutDirectory,
List<String>? pathspec,
}) {
final object = object_bindings.lookup(
repoPointer: _repoPointer,
oidPointer: oid.pointer,
@ -565,7 +584,9 @@ class Repository {
repoPointer: _repoPointer,
targetPointer: object,
resetType: resetType.value,
checkoutOptsPointer: nullptr,
strategy: strategy?.fold(0, (acc, e) => acc! | e.value),
checkoutDirectory: checkoutDirectory,
pathspec: pathspec,
);
object_bindings.free(object);
@ -576,13 +597,19 @@ class Repository {
/// The scope of the updated entries is determined by the paths being passed
/// in the [pathspec].
///
/// Passing a null [oid] will result in removing entries in the index
/// matching the provided [pathspec]s.
///
/// Throws a [LibGit2Error] if error occured.
void resetDefault({required Oid oid, required List<String> pathspec}) {
final object = object_bindings.lookup(
repoPointer: _repoPointer,
oidPointer: oid.pointer,
type: GitObject.commit.value,
);
void resetDefault({required Oid? oid, required List<String> pathspec}) {
Pointer<git_object>? object;
if (oid != null) {
object = object_bindings.lookup(
repoPointer: _repoPointer,
oidPointer: oid.pointer,
type: GitObject.commit.value,
);
}
reset_bindings.resetDefault(
repoPointer: _repoPointer,
@ -741,6 +768,9 @@ class Repository {
return packbuilder.writtenLength;
}
@override
List<Object?> get props => [path];
}
// coverage:ignore-start
@ -821,10 +851,14 @@ class RepositoryCallback {
final String? originUrl;
}
class Identity {
@immutable
class Identity extends Equatable {
/// Identity to use for reflogs.
const Identity({required this.name, required this.email});
final String name;
final String email;
@override
List<Object?> get props => [name, email];
}

View file

@ -22,11 +22,9 @@ class RevParse {
spec: spec,
);
object = Commit(pointers[0].cast<git_commit>());
if (pointers.length == 2) {
reference = Reference(pointers[1].cast<git_reference>());
} else {
reference = null;
}
reference = pointers.length == 2
? Reference(pointers[1].cast<git_reference>())
: null;
}
/// Object found by a revision string.

View file

@ -2,6 +2,7 @@ import 'dart:ffi';
import 'package:libgit2dart/libgit2dart.dart';
import 'package:libgit2dart/src/bindings/libgit2_bindings.dart';
import 'package:libgit2dart/src/bindings/revwalk.dart' as bindings;
import 'package:meta/meta.dart';
class RevWalk {
/// Initializes a new instance of the [RevWalk] class.
@ -15,15 +16,20 @@ class RevWalk {
/// Pointer to memory address for allocated [RevWalk] object.
///
/// Note: For internal use.
@internal
Pointer<git_revwalk> get pointer => _revWalkPointer;
/// Returns the list of commits from the revision walk.
///
/// [limit] is optional number of commits to walk (by default walks through
/// all of the commits pushed onto the walker).
///
/// Default sorting is reverse chronological order (default in git).
List<Commit> walk() {
List<Commit> walk({int limit = 0}) {
final pointers = bindings.walk(
repoPointer: bindings.repository(_revWalkPointer),
walkerPointer: _revWalkPointer,
limit: limit,
);
return pointers.map((e) => Commit(e)).toList();

View file

@ -1,19 +1,22 @@
import 'dart:ffi';
import 'package:ffi/ffi.dart';
import 'package:equatable/equatable.dart';
import 'package:libgit2dart/libgit2dart.dart';
import 'package:libgit2dart/src/bindings/libgit2_bindings.dart';
import 'package:libgit2dart/src/bindings/signature.dart' as bindings;
import 'package:libgit2dart/src/extensions.dart';
import 'package:libgit2dart/src/util.dart';
import 'package:meta/meta.dart';
@immutable
class Signature {
class Signature extends Equatable {
/// Initializes a new instance of [Signature] class from provided pointer to
/// signature object in memory.
///
/// Note: For internal use. Instead, use one of:
/// - [Signature.create]
/// - [Signature.defaultSignature]
@internal
Signature(Pointer<git_signature> pointer) {
_signaturePointer = bindings.duplicate(pointer);
_finalizer.attach(this, _signaturePointer, detach: this);
@ -60,13 +63,14 @@ class Signature {
/// Pointer to memory address for allocated signature object.
///
/// Note: For internal use.
@internal
Pointer<git_signature> get pointer => _signaturePointer;
/// Full name of the author.
String get name => _signaturePointer.ref.name.cast<Utf8>().toDartString();
String get name => _signaturePointer.ref.name.toDartString();
/// Email of the author.
String get email => _signaturePointer.ref.email.cast<Utf8>().toDartString();
String get email => _signaturePointer.ref.email.toDartString();
/// Time in seconds from epoch.
int get time => _signaturePointer.ref.when.time;
@ -74,16 +78,8 @@ class Signature {
/// Timezone offset in minutes.
int get offset => _signaturePointer.ref.when.offset;
@override
bool operator ==(Object other) {
return (other is Signature) &&
(name == other.name) &&
(email == other.email) &&
(time == other.time) &&
(offset == other.offset) &&
(_signaturePointer.ref.when.sign ==
other._signaturePointer.ref.when.sign);
}
/// Indicator for questionable '-0000' offsets in signature.
String get sign => String.fromCharCode(_signaturePointer.ref.when.sign);
/// Releases memory allocated for signature object.
void free() {
@ -91,15 +87,14 @@ class Signature {
_finalizer.detach(this);
}
@override // coverage:ignore-line
int get hashCode =>
_signaturePointer.address.hashCode; // coverage:ignore-line
@override
String toString() {
return 'Signature{name: $name, email: $email, time: $time, '
'offset: $offset}';
'offset: $sign$offset}';
}
@override
List<Object?> get props => [name, email, time, offset, sign];
}
// coverage:ignore-start

View file

@ -1,9 +1,15 @@
import 'package:equatable/equatable.dart';
import 'package:libgit2dart/libgit2dart.dart';
import 'package:libgit2dart/src/bindings/stash.dart' as bindings;
import 'package:meta/meta.dart';
class Stash {
@immutable
class Stash extends Equatable {
/// Initializes a new instance of [Stash] class from provided stash [index],
/// [message] and [oid].
///
/// Note: For internal use. Use [Stash.create] instead to create stash.
@internal
const Stash({
required this.index,
required this.message,
@ -40,14 +46,12 @@ class Stash {
String? message,
Set<GitStash> flags = const {GitStash.defaults},
}) {
final flagsInt = flags.fold(0, (int acc, e) => acc | e.value);
return Oid(
bindings.save(
repoPointer: repo.pointer,
stasherPointer: stasher.pointer,
message: message,
flags: flagsInt,
flags: flags.fold(0, (int acc, e) => acc | e.value),
),
);
}
@ -146,4 +150,7 @@ class Stash {
String toString() {
return 'Stash{index: $index, message: $message, oid: $oid}';
}
@override
List<Object?> get props => [index, message, oid];
}

View file

@ -1,9 +1,12 @@
import 'dart:ffi';
import 'package:equatable/equatable.dart';
import 'package:libgit2dart/libgit2dart.dart';
import 'package:libgit2dart/src/bindings/libgit2_bindings.dart';
import 'package:libgit2dart/src/bindings/submodule.dart' as bindings;
import 'package:meta/meta.dart';
class Submodule {
@immutable
class Submodule extends Equatable {
/// Lookups submodule information by [name] or path (they are usually the
/// same).
///
@ -267,10 +270,23 @@ class Submodule {
@override
String toString() {
return 'Submodule{name: $name, path: $path, url: $url, status: $status, '
'branch: $branch, headOid: $headOid, indexOid: $indexOid, '
'workdirOid: $workdirOid, ignore: $ignore, updateRule: $updateRule}';
return 'Submodule{name: $name, path: $path, url: $url, branch: $branch, '
'headOid: $headOid, indexOid: $indexOid, workdirOid: $workdirOid, '
'ignore: $ignore, updateRule: $updateRule}';
}
@override
List<Object?> get props => [
name,
path,
url,
branch,
headOid,
indexOid,
workdirOid,
ignore,
updateRule,
];
}
// coverage:ignore-start

View file

@ -1,15 +1,19 @@
import 'dart:ffi';
import 'package:equatable/equatable.dart';
import 'package:libgit2dart/libgit2dart.dart';
import 'package:libgit2dart/src/bindings/libgit2_bindings.dart';
import 'package:libgit2dart/src/bindings/object.dart' as object_bindings;
import 'package:libgit2dart/src/bindings/tag.dart' as bindings;
import 'package:meta/meta.dart';
class Tag {
@immutable
class Tag extends Equatable {
/// Initializes a new instance of [Tag] class from provided pointer to
/// tag object in memory.
///
/// Note: For internal use. Use [Tag.lookup] instead.
@internal
Tag(this._tagPointer) {
_finalizer.attach(this, _tagPointer, detach: this);
}
@ -205,11 +209,7 @@ class Tag {
/// Tagger (author) of a tag if there is one.
Signature? get tagger {
final sigPointer = bindings.tagger(_tagPointer);
if (sigPointer != nullptr) {
return Signature(sigPointer);
} else {
return null;
}
return sigPointer != nullptr ? Signature(sigPointer) : null;
}
/// Releases memory allocated for tag object.
@ -223,6 +223,9 @@ class Tag {
return 'Tag{oid: $oid, name: $name, message: $message, target: $target, '
'tagger: $tagger}';
}
@override
List<Object?> get props => [name];
}
// coverage:ignore-start

View file

@ -1,14 +1,18 @@
import 'dart:ffi';
import 'package:equatable/equatable.dart';
import 'package:libgit2dart/libgit2dart.dart';
import 'package:libgit2dart/src/bindings/libgit2_bindings.dart';
import 'package:libgit2dart/src/bindings/tree.dart' as bindings;
import 'package:meta/meta.dart';
class Tree {
@immutable
class Tree extends Equatable {
/// Initializes a new instance of [Tree] class from provided pointer to
/// tree object in memory.
///
/// Note: For internal use. Use [Tree.lookup] instead.
@internal
Tree(this._treePointer) {
_finalizer.attach(this, _treePointer, detach: this);
}
@ -27,24 +31,16 @@ class Tree {
/// Pointer to memory address for allocated tree object.
///
/// Note: For internal use.
@internal
Pointer<git_tree> get pointer => _treePointer;
/// List with tree entries of a tree.
List<TreeEntry> get entries {
final entryCount = bindings.entryCount(_treePointer);
final result = <TreeEntry>[];
for (var i = 0; i < entryCount; i++) {
result.add(
TreeEntry(
bindings.getByIndex(
treePointer: _treePointer,
index: i,
),
),
);
}
return result;
return <TreeEntry>[
for (var i = 0; i < entryCount; i++)
TreeEntry(bindings.getByIndex(treePointer: _treePointer, index: i))
];
}
/// Lookups a tree entry in the tree.
@ -102,6 +98,9 @@ class Tree {
String toString() {
return 'Tree{oid: $oid, length: $length}';
}
@override
List<Object?> get props => [oid];
}
// coverage:ignore-start
@ -110,12 +109,14 @@ final _finalizer = Finalizer<Pointer<git_tree>>(
);
// coverage:ignore-end
class TreeEntry {
@immutable
class TreeEntry extends Equatable {
/// Initializes a new instance of [TreeEntry] class from provided pointer to
/// tree entry object in memory.
///
/// Note: For internal use.
TreeEntry(this._treeEntryPointer);
@internal
const TreeEntry(this._treeEntryPointer);
/// Initializes a new instance of [TreeEntry] class from provided pointer to
/// tree entry object in memory.
@ -150,6 +151,9 @@ class TreeEntry {
@override
String toString() => 'TreeEntry{oid: $oid, name: $name, filemode: $filemode}';
@override
List<Object?> get props => [oid, name, filemode];
}
// coverage:ignore-start

View file

@ -1,14 +1,15 @@
// coverage:ignore-file
import 'dart:convert';
import 'dart:ffi';
import 'dart:io';
import 'package:cli_util/cli_logging.dart' show Ansi, Logger;
import 'package:libgit2dart/src/bindings/libgit2_bindings.dart';
import 'package:libgit2dart/src/bindings/libgit2_opts_bindings.dart';
import 'package:path/path.dart' as path;
import 'package:pub_cache/pub_cache.dart';
import 'package:pub_semver/pub_semver.dart';
const libgit2Version = '1.4.3';
const libgit2Version = '1.5.0';
final libDir = path.join('.dart_tool', 'libgit2');
String getLibName() {
@ -25,6 +26,20 @@ String getLibName() {
return 'libgit2-$libgit2Version.$ext';
}
/// Returns location of the most recent verison of the libgit2dart package
/// contained in the cache.
String? checkCache() {
final cache = json.decode(
Process.runSync('dart', ['pub', 'cache', 'list']).stdout as String,
) as Map<String, dynamic>;
final packages = cache['packages'] as Map<String, dynamic>;
final libPackages = packages['libgit2dart'] as Map<String, dynamic>?;
final versions = libPackages?.keys.map((e) => Version.parse(e)).toList();
final latestVersion = libPackages?[Version.primary(versions!).toString()]
as Map<String, dynamic>?;
return latestVersion?['location'] as String?;
}
/// Checks if [File]/[Link] exists for [path].
bool _doesFileExist(String path) {
return File(path).existsSync() || Link(path).existsSync();
@ -32,13 +47,8 @@ bool _doesFileExist(String path) {
/// Returns path to dynamic library if found.
String? _resolveLibPath(String name) {
var libPath = path.join(Directory.current.path, name);
// If lib is in Present Working Directory.
if (_doesFileExist(libPath)) return libPath;
// If lib is in Present Working Directory's '.dart_tool/libgit2/[platform]' folder.
libPath = path.join(
var libPath = path.join(
Directory.current.path,
libDir,
Platform.operatingSystem,
@ -50,22 +60,30 @@ String? _resolveLibPath(String name) {
libPath = path.join(Directory.current.path, Platform.operatingSystem, name);
if (_doesFileExist(libPath)) return libPath;
String checkCache(PubCache pubCache) {
final pubCacheDir =
pubCache.getLatestVersion('libgit2dart')!.resolve()!.location;
return path.join(pubCacheDir.path, Platform.operatingSystem, name);
}
// If lib is in Dart's '.pub_cache' folder.
libPath = checkCache(PubCache());
// If lib is in executable's folder.
libPath = path.join(path.dirname(Platform.resolvedExecutable), name);
if (_doesFileExist(libPath)) return libPath;
// If lib is in Flutter's '.pub_cache' folder.
final env = Platform.environment;
if (env.containsKey('FLUTTER_ROOT')) {
final flutterPubCache =
PubCache(Directory(path.join(env['FLUTTER_ROOT']!, '.pub-cache')));
libPath = checkCache(flutterPubCache);
// If lib is in executable's bundled 'lib' folder.
libPath = path.join(path.dirname(Platform.resolvedExecutable), 'lib', name);
if (_doesFileExist(libPath)) return libPath;
// If lib is installed in system dir.
if (Platform.isMacOS || Platform.isLinux) {
final paths = [
'/usr/local/lib/libgit2.$libgit2Version.dylib',
'/usr/local/lib/libgit2.so.$libgit2Version',
'/usr/lib64/libgit2.so.$libgit2Version'
];
for (final path in paths) {
if (_doesFileExist(path)) return path;
}
}
// If lib is in '.pub_cache' folder.
final cachedLocation = checkCache();
if (cachedLocation != null) {
libPath = path.join(cachedLocation, Platform.operatingSystem, name);
if (_doesFileExist(libPath)) return libPath;
}
@ -74,26 +92,15 @@ String? _resolveLibPath(String name) {
DynamicLibrary loadLibrary(String name) {
try {
return DynamicLibrary.open(
_resolveLibPath(name) ?? name,
);
return DynamicLibrary.open(_resolveLibPath(name) ?? name);
} catch (e) {
final logger = Logger.standard();
final ansi = Ansi(Ansi.terminalSupportsAnsi);
logger.stderr(
'${ansi.red}Failed to open the library. Make sure that libgit2 '
'library is bundled with the application.${ansi.none}',
stderr.writeln(
'Failed to open the library. Make sure that libgit2 library is bundled '
'with the application.',
);
logger.stdout(ansi.none);
rethrow;
}
}
final libgit2 = Libgit2(loadLibrary(getLibName()));
bool isValidShaHex(String str) {
final hexRegExp = RegExp(r'^[0-9a-fA-F]+$');
return hexRegExp.hasMatch(str) &&
(GIT_OID_MINPREFIXLEN <= str.length && GIT_OID_HEXSZ >= str.length);
}
final libgit2Opts = Libgit2Opts(loadLibrary(getLibName()));

View file

@ -1,9 +1,12 @@
import 'dart:ffi';
import 'package:equatable/equatable.dart';
import 'package:libgit2dart/libgit2dart.dart';
import 'package:libgit2dart/src/bindings/libgit2_bindings.dart';
import 'package:libgit2dart/src/bindings/worktree.dart' as bindings;
import 'package:meta/meta.dart';
class Worktree {
@immutable
class Worktree extends Equatable {
/// Creates new worktree.
///
/// If [ref] is provided, no new branch will be created but specified [ref]
@ -74,10 +77,15 @@ class Worktree {
/// Throws a [LibGit2Error] if error occured.
bool get isPrunable => bindings.isPrunable(_worktreePointer);
/// Prunes working tree.
/// Prunes working tree, that is removes the git data structures on disk.
///
/// Prune the working tree, that is remove the git data structures on disk.
void prune() => bindings.prune(_worktreePointer);
/// [flags] is optional combination of [GitWorktree] flags.
void prune([Set<GitWorktree>? flags]) {
bindings.prune(
worktreePointer: _worktreePointer,
flags: flags?.fold(0, (acc, e) => acc! | e.value),
);
}
/// Whether worktree is valid.
///
@ -93,8 +101,12 @@ class Worktree {
@override
String toString() {
return 'Worktree{name: $name, path: $path}';
return 'Worktree{name: $name, path: $path, isLocked: $isLocked, '
'isPrunable: $isPrunable, isValid: $isValid}';
}
@override
List<Object?> get props => [name, path, isLocked, isValid];
}
// coverage:ignore-start

View file

@ -20,6 +20,6 @@ target_link_libraries(${PLUGIN_NAME} PRIVATE PkgConfig::GTK)
# List of absolute paths to libraries that should be bundled with the plugin
set(libgit2dart_bundled_libraries
"${CMAKE_CURRENT_SOURCE_DIR}/libgit2-1.4.3.so"
"${CMAKE_CURRENT_SOURCE_DIR}/libgit2-1.5.0.so"
PARENT_SCOPE
)

Binary file not shown.

BIN
linux/libgit2-1.5.0.so Normal file

Binary file not shown.

Binary file not shown.

BIN
macos/libgit2-1.5.0.dylib Normal file

Binary file not shown.

View file

@ -4,7 +4,7 @@
#
Pod::Spec.new do |s|
s.name = 'libgit2dart'
s.version = '1.0.0'
s.version = '1.2.2'
s.summary = 'Dart bindings to libgit2.'
s.description = <<-DESC
Dart bindings to libgit2.
@ -15,7 +15,7 @@ Dart bindings to libgit2.
s.source = { :path => '.' }
s.source_files = 'Classes/**/*'
s.dependency 'FlutterMacOS'
s.vendored_libraries = 'libgit2-1.4.3.dylib'
s.vendored_libraries = 'libgit2-1.5.0.dylib'
s.platform = :osx, '10.11'
s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES' }

View file

@ -1,25 +1,25 @@
name: libgit2dart
description: Dart bindings to libgit2.
description: Dart bindings to libgit2, provides ability to use libgit2 library in Dart and Flutter.
version: 1.0.0
version: 1.2.2
homepage: https://github.com/SkinnyMind/libgit2dart
environment:
sdk: ">=2.17.0 <3.0.0"
flutter: ">=2.13.0-0.0.pre.578"
sdk: ">=2.18.0 <3.0.0"
flutter: ">=3.3.0"
dependencies:
args: ^2.3.0
cli_util: ^0.3.5
ffi: ^1.1.2
equatable: ^2.0.3
ffi: ^2.0.0
meta: ^1.7.0
path: ^1.8.1
pub_cache: ^0.3.1
pub_semver: ^2.1.3
dev_dependencies:
ffigen: ^4.1.2
ffigen: ^6.0.1
lints: ^2.0.0
test: ^1.20.0

View file

@ -107,5 +107,12 @@ void main() {
final annotated = AnnotatedCommit.lookup(repo: repo, oid: tip);
expect(() => annotated.free(), returnsNormally);
});
test('supports value comparison', () {
expect(
AnnotatedCommit.lookup(repo: repo, oid: tip),
equals(AnnotatedCommit.lookup(repo: repo, oid: tip)),
);
});
});
}

View file

@ -211,5 +211,12 @@ void main() {
final blame = Blame.file(repo: repo, path: 'feature_file');
expect(blame.toString(), contains('BlameHunk{'));
});
test('supports value comparison', () {
expect(
Blame.file(repo: repo, path: 'feature_file'),
equals(Blame.file(repo: repo, path: 'feature_file')),
);
});
});
}

View file

@ -153,5 +153,12 @@ void main() {
final blob = Blob.lookup(repo: repo, oid: repo[blobSHA]);
expect(blob.toString(), contains('Blob{'));
});
test('supports value comparison', () {
expect(
Blob.lookup(repo: repo, oid: repo[blobSHA]),
equals(Blob.lookup(repo: repo, oid: repo[blobSHA])),
);
});
});
}

View file

@ -327,5 +327,12 @@ void main() {
final branch = Branch.lookup(repo: repo, name: 'master');
expect(branch.toString(), contains('Branch{'));
});
test('supports value comparison', () {
expect(
Branch.lookup(repo: repo, name: 'master'),
equals(Branch.lookup(repo: repo, name: 'master')),
);
});
});
}

View file

@ -67,6 +67,109 @@ void main() {
expect(file.existsSync(), false);
});
test('reverts merge commit to provided parent', () {
const masterContents = 'master contents';
final file = File(p.join(repo.workdir, 'another_feature_file'))
..createSync()
..writeAsStringSync(masterContents);
repo.index.add('another_feature_file');
repo.index.write();
// Creating commit on 'master' branch with file contents conflicting to
// 'feature' branch.
final masterTip = Commit.create(
repo: repo,
updateRef: 'HEAD',
message: 'master commit\n',
author: author,
committer: committer,
tree: Tree.lookup(repo: repo, oid: repo.index.writeTree()),
parents: [Commit.lookup(repo: repo, oid: repo.head.target)],
);
// Switching to 'feature' branch.
Checkout.reference(repo: repo, name: 'refs/heads/feature');
repo.setHead('refs/heads/feature');
file.writeAsStringSync('feature contents');
repo.index.add('another_feature_file');
repo.index.write();
// Creating commit on 'feature' branch with file contents conflicting to
// 'master' branch.
final featureTip = Commit.create(
repo: repo,
updateRef: 'HEAD',
message: 'feature commit\n',
author: author,
committer: committer,
tree: Tree.lookup(repo: repo, oid: repo.index.writeTree()),
parents: [Commit.lookup(repo: repo, oid: repo.head.target)],
);
// Merging master branch.
Merge.commit(
repo: repo,
commit: AnnotatedCommit.lookup(
repo: repo,
oid: Oid.fromSHA(repo: repo, sha: masterTip.sha),
),
);
expect(repo.index.hasConflicts, true);
// "Resolving" conflict.
repo.index.updateAll(['another_feature_file']);
repo.index.write();
repo.stateCleanup();
// Creating merge commit.
final mergeOid = Commit.create(
repo: repo,
updateRef: 'HEAD',
message: 'merge commit\n',
author: author,
committer: committer,
tree: Tree.lookup(repo: repo, oid: repo.index.writeTree()),
parents: [
Commit.lookup(repo: repo, oid: featureTip),
Commit.lookup(repo: repo, oid: masterTip),
],
);
final mergeCommit = Commit.lookup(repo: repo, oid: mergeOid);
mergeCommit.revert(mainline: 2);
expect(file.readAsStringSync(), masterContents);
});
test('reverts commit with provided merge options and checkout options', () {
final commit = Commit.lookup(repo: repo, oid: repo['821ed6e']);
final file = File(p.join(repo.workdir, 'dir', 'dir_file.txt'));
expect(repo.index.find('dir/dir_file.txt'), true);
expect(file.existsSync(), true);
commit.revert(
mergeFavor: GitMergeFileFavor.ours,
mergeFlags: {GitMergeFlag.noRecursive, GitMergeFlag.skipREUC},
mergeFileFlags: {
GitMergeFileFlag.ignoreWhitespace,
GitMergeFileFlag.styleZdiff3
},
checkoutStrategy: {
GitCheckout.force,
GitCheckout.conflictStyleMerge,
},
checkoutDirectory: repo.workdir,
checkoutPaths: ['dir/dir_file.txt'],
);
expect(repo.index.find('dir/dir_file.txt'), false);
expect(file.existsSync(), false);
});
test('throws when trying to revert and error occurs', () {
expect(() => Commit(nullptr).revert(), throwsA(isA<LibGit2Error>()));
});
@ -84,6 +187,25 @@ void main() {
expect(file.existsSync(), true);
});
test('reverts commit to provided commit with provided merge options', () {
final file = File(p.join(repo.workdir, 'dir', 'dir_file.txt'));
expect(repo.index.find('dir/dir_file.txt'), true);
expect(file.existsSync(), true);
final from = Commit.lookup(repo: repo, oid: repo['821ed6e']);
final revertIndex = from.revertTo(
commit: Commit.lookup(repo: repo, oid: repo['78b8bf1']),
mergeFavor: GitMergeFileFavor.ours,
mergeFlags: {GitMergeFlag.noRecursive, GitMergeFlag.skipREUC},
mergeFileFlags: {
GitMergeFileFlag.ignoreWhitespace,
GitMergeFileFlag.styleZdiff3
},
);
expect(revertIndex.find('dir/dir_file.txt'), false);
expect(file.existsSync(), true);
});
test('throws when trying to revert commit and error occurs', () {
final nullCommit = Commit(nullptr);
expect(
@ -396,5 +518,12 @@ Some description.
final commit = Commit.lookup(repo: repo, oid: tip);
expect(commit.toString(), contains('Commit{'));
});
test('supports value comparison', () {
expect(
Commit.lookup(repo: repo, oid: tip),
equals(Commit.lookup(repo: repo, oid: tip)),
);
});
});
}

View file

@ -217,5 +217,9 @@ void main() {
final entry = config.first;
expect(entry.toString(), contains('ConfigEntry{'));
});
test('supports value comparison', () {
expect(Config.open(filePath), equals(Config.open(filePath)));
});
});
}

View file

@ -83,32 +83,28 @@ void main() {
cloneDir.deleteSync(recursive: true);
});
test(
testOn: '!linux',
'clones repository with provided keypair',
() {
final cloneDir = Directory.systemTemp.createTempSync('clone');
final keypair = Keypair(
username: 'git',
pubKey: p.join('test', 'assets', 'keys', 'id_rsa.pub'),
privateKey: p.join('test', 'assets', 'keys', 'id_rsa'),
passPhrase: 'empty',
);
final callbacks = Callbacks(credentials: keypair);
test('clones repository with provided keypair', () {
final cloneDir = Directory.systemTemp.createTempSync('clone');
final keypair = Keypair(
username: 'git',
pubKey: p.join('test', 'assets', 'keys', 'id_rsa.pub'),
privateKey: p.join('test', 'assets', 'keys', 'id_rsa'),
passPhrase: 'empty',
);
final callbacks = Callbacks(credentials: keypair);
final repo = Repository.clone(
url: 'ssh://git@github.com/libgit2/TestGitRepository',
localPath: cloneDir.path,
callbacks: callbacks,
);
final repo = Repository.clone(
url: 'ssh://git@github.com/libgit2/TestGitRepository',
localPath: cloneDir.path,
callbacks: callbacks,
);
expect(repo.isEmpty, false);
expect(repo.isEmpty, false);
if (Platform.isLinux || Platform.isMacOS) {
cloneDir.deleteSync(recursive: true);
}
},
);
if (Platform.isLinux || Platform.isMacOS) {
cloneDir.deleteSync(recursive: true);
}
});
test('throws when no credentials is provided', () {
final cloneDir = Directory.systemTemp.createTempSync('clone');
@ -189,36 +185,32 @@ void main() {
cloneDir.deleteSync(recursive: true);
});
test(
testOn: '!linux',
'clones repository with provided keypair from memory',
() {
final cloneDir = Directory.systemTemp.createTempSync('clone');
final pubKey = File(p.join('test', 'assets', 'keys', 'id_rsa.pub'))
.readAsStringSync();
final privateKey =
File(p.join('test', 'assets', 'keys', 'id_rsa')).readAsStringSync();
final keypair = KeypairFromMemory(
username: 'git',
pubKey: pubKey,
privateKey: privateKey,
passPhrase: 'empty',
);
final callbacks = Callbacks(credentials: keypair);
test('clones repository with provided keypair from memory', () {
final cloneDir = Directory.systemTemp.createTempSync('clone');
final pubKey = File(p.join('test', 'assets', 'keys', 'id_rsa.pub'))
.readAsStringSync();
final privateKey =
File(p.join('test', 'assets', 'keys', 'id_rsa')).readAsStringSync();
final keypair = KeypairFromMemory(
username: 'git',
pubKey: pubKey,
privateKey: privateKey,
passPhrase: 'empty',
);
final callbacks = Callbacks(credentials: keypair);
final repo = Repository.clone(
url: 'ssh://git@github.com/libgit2/TestGitRepository',
localPath: cloneDir.path,
callbacks: callbacks,
);
final repo = Repository.clone(
url: 'ssh://git@github.com/libgit2/TestGitRepository',
localPath: cloneDir.path,
callbacks: callbacks,
);
expect(repo.isEmpty, false);
expect(repo.isEmpty, false);
if (Platform.isLinux || Platform.isMacOS) {
cloneDir.deleteSync(recursive: true);
}
},
);
if (Platform.isLinux || Platform.isMacOS) {
cloneDir.deleteSync(recursive: true);
}
});
test('throws when provided keypair from memory is incorrect', () {
final cloneDir = Directory.systemTemp.createTempSync('clone');

View file

@ -580,5 +580,15 @@ index e69de29..c217c63 100644
expect(patch.delta.oldFile.toString(), contains('DiffFile{'));
expect(stats.toString(), contains('DiffStats{'));
});
test('supports value comparison', () {
expect(Diff.parse(patchText), equals(Diff.parse(patchText)));
final diff = Diff.parse(patchText);
expect(diff.deltas[0], equals(diff.deltas[0]));
final delta = diff.deltas[0];
expect(delta.oldFile, equals(delta.oldFile));
});
});
}

View file

@ -551,4 +551,25 @@ void main() {
expect(actual, expected);
});
});
test('GitIndexAddOption returns correct values', () {
const expected = {
GitIndexAddOption.defaults: 0,
GitIndexAddOption.force: 1,
GitIndexAddOption.disablePathspecMatch: 2,
GitIndexAddOption.checkPathspec: 4,
};
final actual = {for (final e in GitIndexAddOption.values) e: e.value};
expect(actual, expected);
});
test('GitWorktree returns correct values', () {
const expected = {
GitWorktree.pruneValid: 1,
GitWorktree.pruneLocked: 2,
GitWorktree.pruneWorkingTree: 4,
};
final actual = {for (final e in GitWorktree.values) e: e.value};
expect(actual, expected);
});
}

View file

@ -175,7 +175,10 @@ void main() {
group('addAll()', () {
test('adds with provided pathspec', () {
index.clear();
index.addAll(['file', 'feature_file']);
index.addAll(
['file', 'feature_file'],
flags: {GitIndexAddOption.checkPathspec, GitIndexAddOption.force},
);
expect(index.length, 2);
expect(index['file'].oid.sha, fileSha);
@ -509,5 +512,9 @@ void main() {
expect(index.toString(), contains('Index{'));
expect(index['file'].toString(), contains('IndexEntry{'));
});
test('supports value comparison', () {
expect(repo.index, equals(repo.index));
});
});
}

View file

@ -20,10 +20,202 @@ void main() {
'directories', () {
final oldValue = Libgit2.ownerValidation;
Libgit2.ownerValidation = !oldValue;
expect(Libgit2.ownerValidation, equals(!oldValue));
expect(Libgit2.ownerValidation, isNot(oldValue));
// Set it back
// Reset to avoid side effects in later tests
Libgit2.ownerValidation = oldValue;
});
test('sets and returns the maximum mmap window size', () {
final oldValue = Libgit2.mmapWindowSize;
Libgit2.mmapWindowSize = 420 * 1024;
expect(Libgit2.mmapWindowSize, isNot(oldValue));
// Reset to avoid side effects in later tests
Libgit2.mmapWindowSize = oldValue;
});
test(
'sets and returns the maximum memory that will be mapped in total by '
'the library', () {
final oldValue = Libgit2.mmapWindowMappedLimit;
Libgit2.mmapWindowMappedLimit = 420 * 1024;
expect(Libgit2.mmapWindowMappedLimit, isNot(oldValue));
// Reset to avoid side effects in later tests
Libgit2.mmapWindowMappedLimit = oldValue;
});
test(
'sets and returns the maximum number of files that will be mapped '
'at any time by the library', () {
final oldValue = Libgit2.mmapWindowFileLimit;
Libgit2.mmapWindowFileLimit = 69;
expect(Libgit2.mmapWindowFileLimit, isNot(oldValue));
// Reset to avoid side effects in later tests
Libgit2.mmapWindowFileLimit = oldValue;
});
test('sets and returns the search path for a given level of config data',
() {
const paths = '/tmp/global:/tmp/another';
Libgit2.setConfigSearchPath(level: GitConfigLevel.global, path: paths);
expect(Libgit2.getConfigSearchPath(GitConfigLevel.global), paths);
// Reset to avoid side effects in later tests
Libgit2.setConfigSearchPath(level: GitConfigLevel.global, path: null);
});
test(
'sets the maximum data size for the given type of object '
'to be considered eligible for caching in memory', () {
expect(
() => Libgit2.setCacheObjectLimit(type: GitObject.blob, value: 420),
returnsNormally,
);
// Reset to avoid side effects in later tests
Libgit2.setCacheObjectLimit(type: GitObject.blob, value: 0);
});
test('sets the maximum cache size', () {
expect(Libgit2.cachedMemory.allowed, 256 * (1024 * 1024));
Libgit2.setCacheMaxSize(128 * (1024 * 1024));
expect(Libgit2.cachedMemory.allowed, 128 * (1024 * 1024));
// Reset to avoid side effects in later tests
Libgit2.setCacheMaxSize(256 * (1024 * 1024));
});
test('returns CachedMemory object', () {
expect(Libgit2.cachedMemory.allowed, 256 * (1024 * 1024));
expect(Libgit2.cachedMemory.toString(), contains('CachedMemory{'));
});
test('disables and enables caching', () {
expect(() => Libgit2.disableCaching(), returnsNormally);
// Reset to avoid side effects in later tests
Libgit2.enableCaching();
});
test('sets and returns the default template path', () {
final oldValue = Libgit2.templatePath;
Libgit2.templatePath = '/tmp/template';
expect(Libgit2.templatePath, isNot(oldValue));
// Reset to avoid side effects in later tests
Libgit2.templatePath = oldValue;
});
test('sets location for ssl certificates', () {
expect(
() => Libgit2.setSSLCertLocations(file: 'etc/ssl/cert.pem'),
returnsNormally,
);
expect(
() => Libgit2.setSSLCertLocations(path: 'etc/ssl/certs/'),
returnsNormally,
);
});
test('throws when trying to set both ssl certificates location to null',
() {
expect(
() => Libgit2.setSSLCertLocations(),
throwsA(isA<ArgumentError>()),
);
});
test('sets and returns the User-Agent header', () {
final oldValue = Libgit2.userAgent;
Libgit2.userAgent = 'Mozilla/5.0';
expect(Libgit2.userAgent, isNot(oldValue));
// Reset to avoid side effects in later tests
Libgit2.userAgent = oldValue;
});
test('disables and enables strict object creation', () {
expect(() => Libgit2.disableStrictObjectCreation(), returnsNormally);
// Reset to avoid side effects in later tests
Libgit2.enableStrictObjectCreation();
});
test('disables and enables strict symbolic reference creation', () {
expect(() => Libgit2.disableStrictSymbolicRefCreation(), returnsNormally);
// Reset to avoid side effects in later tests
Libgit2.enableStrictSymbolicRefCreation();
});
test(
'disables and enables the use of offset deltas when creating packfiles',
() {
expect(() => Libgit2.disableOffsetDelta(), returnsNormally);
// Reset to avoid side effects in later tests
Libgit2.enableOffsetDelta();
});
test('enables and disables the fsync of files in gitdir', () {
expect(() => Libgit2.enableFsyncGitdir(), returnsNormally);
// Reset to avoid side effects in later tests
Libgit2.disableFsyncGitdir();
});
test('disables and enables strict hash verification', () {
expect(() => Libgit2.disableStrictHashVerification(), returnsNormally);
// Reset to avoid side effects in later tests
Libgit2.enableStrictHashVerification();
});
test('disables and enables check for unsaved changes in index', () {
expect(() => Libgit2.disableUnsavedIndexSafety(), returnsNormally);
// Reset to avoid side effects in later tests
Libgit2.enableUnsavedIndexSafety();
});
test('sets and returns the pack maximum objects', () {
final oldValue = Libgit2.packMaxObjects;
Libgit2.packMaxObjects = 69;
expect(Libgit2.packMaxObjects, isNot(oldValue));
// Reset to avoid side effects in later tests
Libgit2.packMaxObjects = oldValue;
});
test('disables and enables check for unsaved changes in index', () {
expect(() => Libgit2.disablePackKeepFileChecks(), returnsNormally);
// Reset to avoid side effects in later tests
Libgit2.enablePackKeepFileChecks();
});
test(
'disables and enables check for unsaved changes in index',
testOn: '!windows',
() {
expect(() => Libgit2.disableHttpExpectContinue(), returnsNormally);
// Reset to avoid side effects in later tests
Libgit2.enableHttpExpectContinue();
},
);
test('sets and returns the list of git extensions', () {
Libgit2.extensions = ['newext', 'anotherext'];
expect(Libgit2.extensions, ['noop', 'newext', 'anotherext']);
// Reset to avoid side effects in later tests
Libgit2.extensions = ['!newext', '!anotherext'];
});
});
}

View file

@ -168,31 +168,38 @@ Another feature edit
expect(diff, diffExpected);
});
test('merges with provided merge flags and file flags', () {
test('merges with provided options', () {
const diffExpected = """
\<<<<<<< conflict_file
master conflict edit
\<<<<<<< ours
Feature edit on feature branch
||||||| ancestor
Feature edit
=======
conflict branch edit
>>>>>>> conflict_file
Another feature edit
>>>>>>> theirs
""";
Checkout.reference(repo: repo, name: 'refs/heads/feature');
repo.setHead('refs/heads/feature');
Merge.commit(
repo: repo,
commit: AnnotatedCommit.lookup(
repo: repo,
oid: Branch.lookup(repo: repo, name: 'conflict-branch').target,
oid: Branch.lookup(repo: repo, name: 'ancestor-conflict').target,
),
mergeFlags: {GitMergeFlag.noRecursive},
fileFlags: {GitMergeFileFlag.ignoreWhitespaceEOL},
);
final conflictedFile = repo.index.conflicts['conflict_file']!;
final conflictedFile = repo.index.conflicts['feature_file']!;
final diff = Merge.fileFromIndex(
repo: repo,
ancestor: null,
ancestor: conflictedFile.ancestor,
ancestorLabel: 'ancestor',
ours: conflictedFile.our!,
oursLabel: 'ours',
theirs: conflictedFile.their!,
theirsLabel: 'theirs',
flags: {GitMergeFileFlag.styleDiff3},
);
expect(diff, diffExpected);

View file

@ -134,5 +134,13 @@ void main() {
final note = Note.lookup(repo: repo, annotatedOid: repo['821ed6e']);
expect(note.toString(), contains('Note{'));
});
test('supports value comparison', () {
final oid = repo.head.target;
expect(
Note.lookup(repo: repo, annotatedOid: oid),
equals(Note.lookup(repo: repo, annotatedOid: oid)),
);
});
});
}

Some files were not shown because too many files have changed in this diff Show more