Skip to content

Git Repository Storage

Robin Rodricks edited this page Aug 20, 2026 · 7 revisions

This package lets you read and write files in a folder of a Git repository. The repository is cloned into a local working directory and every FluentStorage operation is performed against that working tree.

In order to use FluentStorage to manage Git Repositories, you need to reference FluentStorage.Git which wraps LibGit2Sharp.

This package targets net8.0 and net9.0 only, because LibGit2Sharp 0.32 does not ship a netstandard2.0 build.

Special thanks to Gustavo Mauricio de Barros for the first version of this package.

Configuration

All config is passed into the factory API as a GitStorageOptions instance. Some of those props are also exposed by the GitStore:

  • AutoCommit — When true, each write operation automatically commits the changes to the repository.
  • AutoPush — When true, each write operation automatically commits and pushes the changes to the remote.
  • RootPath — Root sub-folder within the repository that acts as the FluentStorage root. Null means the repository root.
  • LocalWorkingDirectory — Local working directory of the clone.

Git API

In addition to supporting many IStore API methods, GitStore provides the following Git-specific API:

  • GetCurrentCommit — Returns the current HEAD commit, or null if the repository has no commits. Uses the repository's HEAD reference and returns its tip commit.

  • GitCommit — Stages all pending changes under the store's root and commits them. When PullBeforeWrite is true, the remote is pulled (best effort) before committing. Returns the created commit, or null if there was nothing to commit. Runs on a worker thread and maps Git exceptions.

  • GitCommitAndPush — Commits all pending changes and pushes them to the remote. Calls GitCommit first, then GitPush, both operations are performed through their respective locked Git operations.

  • GitPush — Pushes the current branch to its remote. Runs on a worker thread and maps Git exceptions.

  • GitPull — Pulls the latest changes from the remote into the current branch. Runs on a worker thread and maps Git exceptions.

Connect to a Git repository

// HTTPS with username + password / personal access token
IStore storage = GitStorage.FromCredentials("https://github.com/me/repo.git", "username", "password");

// Personal access token (GitHub/GitLab/Azure DevOps)
IStore storage = GitStorage.FromToken("https://github.com/me/repo.git", "ghp_xxx");

// Full control over branch, root folder, commit author and credentials
IStore storage = GitStorage.FromUrl("https://github.com/me/repo.git", new GitStorageOptions {
   Token = "ghp_xxx",
   Branch = "develop",
   RootPath = "data",                       // work only within the "data" folder
   CommitAuthorName = "My App",
   CommitAuthorEmail = "app@example.com",
});

Commits and pushes

Writing files only changes the local working tree. Commits and pushes are performed either automatically or explicitly:

var store = (GitStore)GitStorage.FromToken(url, token);

// explicit commit/push (group many files into a single commit)
await store.SetText("folder/a.txt", "aaa");
await store.SetText("folder/b.txt", "bbb");
await store.CommitAndPushAsync("add a and b");

// or pull the latest remote changes
await store.PullAsync();

Automatic commit/push on every write:

var store = (GitStore)GitStorage.FromUrl(url, new GitStorageOptions {
   Token = token,
   AutoCommit = true,   // commit after each write
   AutoPush = true,     // push after each write
});
await store.SetText("folder/a.txt", "aaa");   // committed and pushed

Versioning

Object versioning is mapped to git history:

List<StorageObjectVersion> versions = await store.ListObjectVersions("folder/a.txt");
StorageObjectVersion old = versions.First(v => !v.IsCurrent);
await store.RestoreObjectVersion("folder/a.txt", old.VersionId);

Connection Strings

To create from a connection string, first register the module when your program starts:

GitStorage.Use();

Then use the following connection string:

IStore storage = StorageFactory.FromConnectionString("git://url=https://github.com/me/repo.git;token=ghp_xxx;branch=main;root=data;localpath=/tmp/myrepo");
Parameter Required Description
url yes Repository URL (HTTP/HTTPS or a local path).
user no HTTPS username.
password no HTTPS password.
token no Personal access token (overrides password).
branch no Branch to clone and work on.
root no Root sub-folder that acts as the store root.
localpath no Local working directory (a temporary one is used when omitted).

Clone this wiki locally