Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,27 +58,27 @@ jobs:
- name: Run tests on desktop platforms
if: ${{ matrix.platform != 'android' && matrix.platform != 'ios' }}
run: |
flutter test
flutter test -j 1 --reporter expanded

- name: Run tests on iOS
if: ${{ matrix.platform == 'ios' }}
shell: bash
run: |
IOS_DEVICE_NAME="iPhone 16"
if ! xcrun simctl list devices available | grep -q "$IOS_DEVICE_NAME"; then
IOS_DEVICE_NAME="$(xcrun simctl list devices available | awk -F '[()]' '/iPhone/ && /Shutdown/ {print $1; exit}' | xargs)"
IOS_DEVICE_ID="$(xcrun simctl list devices available | awk -F '[()]' '/iPhone 16/ && /Shutdown/ {print $2; exit}')"
if [ -z "$IOS_DEVICE_ID" ]; then
IOS_DEVICE_ID="$(xcrun simctl list devices available | awk -F '[()]' '/iPhone/ && /Shutdown/ {print $2; exit}')"
fi

if [ -z "$IOS_DEVICE_NAME" ]; then
if [ -z "$IOS_DEVICE_ID" ]; then
echo "No available iOS simulator found"
xcrun simctl list devices available
exit 1
fi

xcrun simctl boot "$IOS_DEVICE_NAME" || true
xcrun simctl bootstatus "$IOS_DEVICE_NAME" -b
xcrun simctl boot "$IOS_DEVICE_ID" || true
xcrun simctl bootstatus "$IOS_DEVICE_ID" -b
flutter devices
flutter test -d "$IOS_DEVICE_NAME"
flutter test -d "$IOS_DEVICE_ID" --reporter expanded

- name: Setup Flutter path for Android
if: ${{ matrix.platform == 'android' }}
Expand Down
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,18 @@
# Changelog
## [0.5.2] - 2026-06-29
### Features
* Expand libgit2 binding coverage across repository, remote, status, tree,
tag, signature, submodule, config, diff, index, ODB, reference, and related
APIs.
* Add public wrappers for extended repository opening, basic repository
initialization, annotated HEAD detaching, remote instance URL overrides,
remote autotag configuration, tree walking, tree updates, status callbacks,
and annotation-only tag creation.

### Testing
* Add focused tests for the newly exposed binding wrappers.
* Include binding files in coverage by removing file-level coverage ignores.

## [0.5.1] - 2026-06-29
### Fixed
* Require `git2dart_binaries` `>=1.11.2 <1.12.0` to pick up the latest
Expand Down
34 changes: 34 additions & 0 deletions lib/src/bindings/blame.dart
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,11 @@ Pointer<git_blame> fileFromBuffer({

/// Gets the number of hunks that exist in the blame structure.
int hunkCount(Pointer<git_blame> blame) {
return libgit2.git_blame_get_hunk_count(blame);
}

/// Gets the number of hunks using libgit2's legacy blame API name.
int hunkCountLegacy(Pointer<git_blame> blame) {
return libgit2.git_blame_hunkcount(blame);
}

Expand All @@ -156,6 +161,21 @@ int hunkCount(Pointer<git_blame> blame) {
Pointer<git_blame_hunk> getHunkByline({
required Pointer<git_blame> blamePointer,
required int lineno,
}) {
final result = libgit2.git_blame_get_hunk_byline(blamePointer, lineno);

if (result == nullptr) {
throw Git2DartError('Line number out of bounds');
} else {
return result;
}
}

/// Get the hunk that contains the given line number using libgit2's legacy API
/// name.
Pointer<git_blame_hunk> getHunkBylineLegacy({
required Pointer<git_blame> blamePointer,
required int lineno,
}) {
final result = libgit2.git_blame_hunk_byline(blamePointer, lineno);

Expand All @@ -174,6 +194,20 @@ Pointer<git_blame_hunk> getHunkByline({
Pointer<git_blame_hunk> getHunkByIndex({
required Pointer<git_blame> blamePointer,
required int index,
}) {
final result = libgit2.git_blame_get_hunk_byindex(blamePointer, index);

if (result == nullptr) {
throw Git2DartError('Index out of bounds');
} else {
return result;
}
}

/// Get the hunk at the given index using libgit2's legacy API name.
Pointer<git_blame_hunk> getHunkByIndexLegacy({
required Pointer<git_blame> blamePointer,
required int index,
}) {
final result = libgit2.git_blame_hunk_byindex(blamePointer, index);

Expand Down
4 changes: 4 additions & 0 deletions lib/src/bindings/blob.dart
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ Pointer<git_blob> lookupPrefix({
/// Get the [Oid] of a blob.
Pointer<git_oid> id(Pointer<git_blob> blob) => libgit2.git_blob_id(blob);

/// Get the repository that contains the blob.
Pointer<git_repository> owner(Pointer<git_blob> blob) =>
libgit2.git_blob_owner(blob);

/// Determine if the blob content is most certainly binary or not.
///
/// The heuristic used to guess if a file is binary is taken from core git:
Expand Down
11 changes: 11 additions & 0 deletions lib/src/bindings/branch.dart
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,17 @@ String getName(Pointer<git_reference> ref) {
});
}

/// Check whether a branch name is valid.
bool nameIsValid(String name) {
return using((arena) {
final valid = arena<Int>();
final nameC = name.toChar(arena);
final error = libgit2.git_branch_name_is_valid(valid, nameC);
checkErrorAndThrow(error);
return valid.value == 1;
});
}

/// Find the remote name of a remote-tracking branch.
///
/// This will return the name of the remote whose fetch refspec is matching the
Expand Down
50 changes: 50 additions & 0 deletions lib/src/bindings/commit.dart
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,11 @@ String message(Pointer<git_commit> commit) {
return libgit2.git_commit_message(commit).toDartString();
}

/// Get the full raw message of a commit.
String messageRaw(Pointer<git_commit> commit) {
return libgit2.git_commit_message_raw(commit).toDartString();
}

/// Get the short "summary" of the git commit message.
///
/// The returned message is the summary of the commit, comprising the first
Expand Down Expand Up @@ -372,6 +377,11 @@ String headerField({
});
}

/// Get the full raw header of a commit.
String rawHeader(Pointer<git_commit> commit) {
return libgit2.git_commit_raw_header(commit).toDartString();
}

/// Get the id of a commit.
Pointer<git_oid> id(Pointer<git_commit> commit) =>
libgit2.git_commit_id(commit);
Expand Down Expand Up @@ -437,12 +447,52 @@ int timeOffset(Pointer<git_commit> commit) =>
Pointer<git_signature> committer(Pointer<git_commit> commit) =>
libgit2.git_commit_committer(commit);

/// Get the committer of a commit, using a mailmap to resolve names and emails.
///
/// The returned signature must be freed.
Pointer<git_signature> committerWithMailmap({
required Pointer<git_commit> commitPointer,
required Pointer<git_mailmap> mailmapPointer,
}) {
return using((arena) {
final out = arena<Pointer<git_signature>>();
final error = libgit2.git_commit_committer_with_mailmap(
out,
commitPointer,
mailmapPointer,
);

checkErrorAndThrow(error);
return out.value;
});
}

/// Get the author of a commit.
///
/// The returned signature must be freed.
Pointer<git_signature> author(Pointer<git_commit> commit) =>
libgit2.git_commit_author(commit);

/// Get the author of a commit, using a mailmap to resolve names and emails.
///
/// The returned signature must be freed.
Pointer<git_signature> authorWithMailmap({
required Pointer<git_commit> commitPointer,
required Pointer<git_mailmap> mailmapPointer,
}) {
return using((arena) {
final out = arena<Pointer<git_signature>>();
final error = libgit2.git_commit_author_with_mailmap(
out,
commitPointer,
mailmapPointer,
);

checkErrorAndThrow(error);
return out.value;
});
}

/// Get the id of the tree pointed to by a commit.
Pointer<git_oid> treeOid(Pointer<git_commit> commit) =>
libgit2.git_commit_tree_id(commit);
Expand Down
Loading
Loading