diff --git a/lib/src/bindings/config.dart b/lib/src/bindings/config.dart index e0dd332..aebb24c 100644 --- a/lib/src/bindings/config.dart +++ b/lib/src/bindings/config.dart @@ -69,7 +69,7 @@ Pointer openDefault() { /// /// Throws an error if file has not been found. String findGlobal() { - final out = calloc(2); + final out = calloc(sizeOf()); final error = libgit2.git_config_find_global(out); final path = out.ref.ptr.cast().toDartString(); calloc.free(out); diff --git a/lib/src/bindings/repository.dart b/lib/src/bindings/repository.dart index 80ef458..2e4b9a9 100644 --- a/lib/src/bindings/repository.dart +++ b/lib/src/bindings/repository.dart @@ -40,6 +40,35 @@ Pointer openBare(String barePath) { return out.value; } +/// Look for a git repository and return its path. The lookup start from [startPath] +/// and walk across parent directories if nothing has been found. The lookup ends when +/// the first repository is found, or when reaching a directory referenced in [ceilingDirs]. +/// +/// The method will automatically detect if the repository is bare (if there is a repository). +/// +/// Throws a [LibGit2Error] if error occured. +String discover(String startPath, String ceilingDirs) { + final out = calloc(sizeOf()); + final startPathC = startPath.toNativeUtf8().cast(); + final ceilingDirsC = ceilingDirs.toNativeUtf8().cast(); + final error = + libgit2.git_repository_discover(out, startPathC, 0, ceilingDirsC); + var result = ''; + + if (error == git_error_code.GIT_ENOTFOUND) { + return result; + } else if (error < 0) { + throw LibGit2Error(libgit2.git_error_last()); + } + + result = out.ref.ptr.cast().toDartString(); + calloc.free(out); + calloc.free(startPathC); + calloc.free(ceilingDirsC); + + return result; +} + /// Returns the path to the `.git` folder for normal repositories or the /// repository itself for bare repositories. String path(Pointer repo) { diff --git a/lib/src/repository.dart b/lib/src/repository.dart index e43c9f7..f30bda1 100644 --- a/lib/src/repository.dart +++ b/lib/src/repository.dart @@ -29,6 +29,17 @@ class Repository { /// Pointer to memory address for allocated repository object. Pointer get pointer => _repoPointer; + /// Look for a git repository and return its path. The lookup start from [startPath] + /// and walk across parent directories if nothing has been found. The lookup ends when + /// the first repository is found, or when reaching a directory referenced in [ceilingDirs]. + /// + /// The method will automatically detect if the repository is bare (if there is a repository). + /// + /// Throws a [LibGit2Error] if error occured. + static String discover(String startPath, [String ceilingDirs = '']) { + return bindings.discover(startPath, ceilingDirs); + } + /// Returns path to the `.git` folder for normal repositories /// or path to the repository itself for bare repositories. String get path => bindings.path(_repoPointer); diff --git a/test/repository_test.dart b/test/repository_test.dart index a3cd248..1b08ea6 100644 --- a/test/repository_test.dart +++ b/test/repository_test.dart @@ -149,6 +149,18 @@ void main() { config.free(); }); + group('.discover()', () { + test('discovers repository', () async { + final subDir = '${tmpDir}subdir1/subdir2/'; + await Directory(subDir).create(recursive: true); + expect(Repository.discover(subDir), repo.path); + }); + + test('returns empty string when repository not found', () { + expect(Repository.discover(Directory.systemTemp.path), ''); + }); + }); + test('returns empty string when there is no namespace', () { expect(repo.namespace, isEmpty); });