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
25 changes: 23 additions & 2 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,10 @@ jobs:
- platform: ubuntu-latest
- platform: macos-latest
- platform: windows-latest
- platform: ios
- platform: android
arch: x86_64
runs-on: ${{ matrix.platform == 'android' && 'ubuntu-latest' || matrix.platform }}
runs-on: ${{ (matrix.platform == 'android' && 'ubuntu-latest') || (matrix.platform == 'ios' && 'macos-latest') || matrix.platform }}

steps:
- name: Set git to use LF
Expand Down Expand Up @@ -55,10 +56,30 @@ jobs:
channel: stable

- name: Run tests on desktop platforms
if: ${{ matrix.platform != 'android' }}
if: ${{ matrix.platform != 'android' && matrix.platform != 'ios' }}
run: |
flutter test

- 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)"
fi

if [ -z "$IOS_DEVICE_NAME" ]; 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
flutter devices
flutter test -d "$IOS_DEVICE_NAME"

- name: Setup Flutter path for Android
if: ${{ matrix.platform == 'android' }}
id: flutter-path
Expand Down
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,15 @@
# Changelog
## [0.5.0] - 2026-05-30
### Features
* Update `git2dart_binaries` constraint to `>=1.11.0 <1.12.0`.
* Add public APIs for commit graphs, ignore rules, messages, and pathspec matching.
* Extend config, diff, oid, repository, and tree APIs with additional libgit2-backed helpers.
* Add Flutter iOS platform support and shared `PlatformSpecific.initialize()`.

### Documentation
* Refresh public API documentation for consistency.
* Add platform setup documentation for iOS.

## [0.4.0] - 2025-11-20
### Features
* Add `PlatformSpecific.androidInitialize` to wire up libgit2 SSL certificates automatically on Flutter/Android before cloning or fetching.
Expand Down
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ git2dart package provides ability to use [libgit2](https://github.com/libgit2/li

This is a hardfork of [libgit2dart](https://github.com/SkinnyMind/libgit2dart)

Currently supported platforms are 64-bit Windows, Linux, macOS and Android (arm64-v8a, x86_64) on both Flutter and Dart VM.
Currently supported platforms are 64-bit Windows, Linux, macOS, Android
(arm64-v8a, x86_64), and iOS on Flutter. Desktop platforms also work on the
Dart VM when native libraries are available.
## Usage

git2dart provides you ability to manage Git repository. You can read and write objects (commit, tag, tree and blob), walk a tree, access the staging area, manage config and lots more.
Expand Down Expand Up @@ -51,6 +53,10 @@ choco install openssl -y

[Android Setup Guide](doc/android.md).

### iOS

[iOS Setup Guide](doc/ios.md).

## Getting Started

1. Add package as a dependency in your `pubspec.yaml`
Expand Down
68 changes: 41 additions & 27 deletions doc/README.md
Original file line number Diff line number Diff line change
@@ -1,58 +1,72 @@
# git2dart Documentation

This documentation covers the public Dart API exposed by `package:git2dart`.
The package wraps libgit2 with null-safe Dart classes and keeps raw FFI details
inside `lib/src/bindings`.

## Platform Setup

- [Android Setup](android.md) - Required initialize library for Android
- [Android setup](android.md)
- [iOS setup](ios.md)

## Core Types

## Usage Guide
- [Repository](types/repository.md)
- [Git Objects](types/git_objects.md)
- [Git objects and Oid](types/git_objects.md)
- [Commit](types/commit.md)
- [Tree and TreeEntry](types/tree_and_treeentry.md)
- [Tag](types/tag.md)
- [Blob](types/blob.md)
- [Commit Walker](types/commit_walker.md)
- [Tag](types/tag.md)
- [Signature](types/signature.md)
- [AnnotatedCommit](types/annotatedcommit.md)

## Repository Data

- [Config files](types/config_files.md)
- [Index and IndexEntry](types/index_and_indexentry.md)
- [References and RefLog](types/references_and_reflog.md)
- [Branches](types/branches.md)
- [Diff](types/diff.md)
- [Patch](types/patch.md)
- [Config files](types/config_files.md)
- [Checkout](types/checkout.md)
- [Merge](types/merge.md)
- [Stashes](types/stashes.md)
- [Remote](types/remote.md)
- [Worktrees](types/worktrees.md)
- [Submodules](types/submodules.md)
- [Remote](types/remote.md)
- [ODB (Object Database)](types/odb_object_database.md)
- [Packbuilder](types/packbuilder.md)
- [CommitGraph](types/commit_graph.md)

## Operations

- [Checkout](types/checkout.md)
- [Reset](types/reset.md)
- [Merge](types/merge.md)
- [Rebase](types/rebase.md)
- [Stashes](types/stashes.md)
- [Diff](types/diff.md)
- [Patch](types/patch.md)
- [Pathspec](types/pathspec.md)
- [Ignore](types/ignore.md)
- [Attributes](types/attributes.md)
- [Blame](types/blame.md)
- [Describe](types/describe.md)
- [Note](types/note.md)
- [Rebase](types/rebase.md)
- [RevParse](types/revparse.md)
- [Commit Walker](types/commit_walker.md)
- [Mailmap](types/mailmap.md)
- [Message](types/message.md)
- [Credentials](types/credentials.md)
- [ODB (Object Database)](types/odb_object_database.md)
- [Packbuilder](types/packbuilder.md)
- [Signature](types/signature.md)
- [RevParse](types/revparse.md)
- [AnnotatedCommit](types/annotatedcommit.md)

# Troubleshooting
## Troubleshooting

#### Linux
### Linux

If you are developing on Linux using non-Debian based distrib you might encounter these errors:
The bundled native libraries are built on Ubuntu. On distributions that expose
PCRE under different library names, loading libgit2 can fail with messages like:

- Failed to load dynamic library: libpcre.so.3: cannot open shared object file: No such file or directory
- Failed to load dynamic library: libpcreposix.so.3: cannot open shared object file: No such file or directory
- `Failed to load dynamic library: libpcre.so.3`
- `Failed to load dynamic library: libpcreposix.so.3`

That happens because dynamic library is precompiled on Ubuntu and Arch/Fedora/RedHat names for those libraries are `libpcre.so` and `libpcreposix.so`.

To fix these errors create symlinks:
Create compatibility symlinks for your distribution when needed:

```shell
sudo ln -s /usr/lib64/libpcre.so /usr/lib64/libpcre.so.3
sudo ln -s /usr/lib64/libpcreposix.so /usr/lib64/libpcreposix.so.3
```

159 changes: 53 additions & 106 deletions doc/android.md
Original file line number Diff line number Diff line change
@@ -1,148 +1,95 @@
# Android Platform Setup

git2dart supports Android.
git2dart supports Android API 21+ on the architectures provided by
`git2dart_binaries`.

## Requirements

- Android API 21+ (Android 5.0+)
- Currently supports arm64-v8a and x86_64 architectures
- Android API 21 or newer
- Flutter app initialization before using git2dart
- App-private storage for repositories

### Quick Setup
## Initialization

Add this to your app's `main()` function:
Call `PlatformSpecific.initialize()` before any repository, remote, or
credential operation. If you want an Android-only call, use
`PlatformSpecific.androidInitialize()`.

```dart
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:git2dart/git2dart.dart';
void main() async {

Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
// Initialize platform specific logic
await PlatformSpecific.androidInitialize();
await PlatformSpecific.initialize();

runApp(MyApp());
runApp(const MyApp());
}
```

### Why is this needed?

Android apps cannot access system CA certificates via standard filesystem paths. git2dart bundles Mozilla's trusted root certificates and extracts them to your app's cache directory on first run.

### Initialization Order

**Critical**: You must call Call `await PlatformSpecific.androidInitialize()` before all works.
Android does not expose system CA certificates through the same filesystem
paths as desktop platforms. git2dart extracts bundled trusted root certificates
to the app cache directory during initialization.

## Storage Recommendations
## Storage

Use app-private storage to avoid Android permission issues:
Use app-private directories for repositories. This avoids Android scoped storage
and permission issues.

```dart
import 'package:git2dart/git2dart.dart';
import 'package:path_provider/path_provider.dart';
Future<void> cloneRepo() async {
// Use app-private directory

Future<Repository> cloneRepo() async {
final appDir = await getApplicationDocumentsDirectory();
final repoPath = '${appDir.path}/my-repo';
final repo = Repository.clone(

return Repository.clone(
url: 'https://github.com/user/repo.git',
localPath: repoPath,
);
}
```

## Complete Example
## Authentication

```dart
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:git2dart/git2dart.dart';
import 'package:path_provider/path_provider.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await PlatformSpecific.androidInitialize();
Pass a concrete `Credentials` object through `Callbacks`.

runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: GitDemo(),
);
}
}
class GitDemo extends StatefulWidget {
@override
_GitDemoState createState() => _GitDemoState();
}
class _GitDemoState extends State<GitDemo> {
String _status = 'Ready';
Future<void> _cloneRepo() async {
setState(() => _status = 'Cloning...');
try {
final appDir = await getApplicationDocumentsDirectory();
final repoPath = '${appDir.path}/my-repo';
final repo = Repository.clone(
url: 'https://github.com/DartGit-dev/git2dart_binaries.git',
localPath: repoPath,
);
setState(() => _status = 'Cloned successfully!');
} catch (e) {
setState(() => _status = 'Error: $e');
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('git2dart Android Demo')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(_status),
SizedBox(height: 20),
ElevatedButton(
onPressed: _cloneRepo,
child: Text('Clone Repository'),
),
],
),
),
);
}
}
```dart
final repo = Repository.clone(
url: 'https://github.com/user/private-repo.git',
localPath: repoPath,
callbacks: const Callbacks(
credentials: UserPass(
username: 'user',
password: 'personal-access-token',
),
),
);
```

## Troubleshooting
For SSH remotes, use `Keypair`, `KeypairFromMemory`, or `KeypairFromAgent`
depending on where the key material is stored.

### SSL errors
## Troubleshooting

If you see SSL errors like "SSL error: unknown" or "no TLS stream available":
### SSL Errors

1. Verify you've added `await PlatformSpecific.androidInitialize()` to `main()`
2. Ensure `WidgetsFlutterBinding.ensureInitialized()` is called before call androidInitialize
If you see SSL errors such as `SSL error: unknown` or `no TLS stream available`:

### Authentication for private repositories
- Ensure `WidgetsFlutterBinding.ensureInitialized()` runs first.
- Ensure `await PlatformSpecific.initialize()` runs before git2dart APIs.
- Ensure repository operations use app-private storage.

Use personal access tokens for private repositories:
### Permission Errors

```dart
Repository.clone(
url: 'https://github.com/user/private-repo.git',
localPath: repoPath,
callbacks: Callbacks(
credentials: (url, usernameFromUrl, allowedTypes) {
return Credential.userpassPlaintext(
username: 'your-username',
password: 'your-personal-access-token',
);
},
),
);
```
Prefer `getApplicationDocumentsDirectory()` or another app-private location.
Avoid shared external storage unless the app explicitly manages Android storage
permissions.

## See Also

- [Main Documentation](README.md)
- [Repository Guide](types/repository.md)
- [Remote Operations](types/remote.md)
- [Credentials](types/credentials.md)
- [Main documentation](README.md)
- [Repository](types/repository.md)
- [Remote](types/remote.md)
- [Credentials](types/credentials.md)
Loading
Loading