https://github.com/frblondin/gitobjectdb
Configuration management versioning stored in Git. See https://gitobjectdb.readthedocs.io
https://github.com/frblondin/gitobjectdb
configuration-management csharp git net
Last synced: 7 months ago
JSON representation
Configuration management versioning stored in Git. See https://gitobjectdb.readthedocs.io
- Host: GitHub
- URL: https://github.com/frblondin/gitobjectdb
- Owner: frblondin
- License: mit
- Created: 2018-06-19T21:28:46.000Z (over 7 years ago)
- Default Branch: main
- Last Pushed: 2025-01-06T08:20:38.000Z (10 months ago)
- Last Synced: 2025-04-02T03:43:09.545Z (8 months ago)
- Topics: configuration-management, csharp, git, net
- Language: C#
- Homepage:
- Size: 34.1 MB
- Stars: 8
- Watchers: 4
- Forks: 6
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
**GitObjectDb simplifies the configuration management versioning by backing it in Git.**
| Name | Badge |
| --- | --- |
| GitObjectDb | [](https://www.nuget.org/packages/GitObjectDb/) |
| GitObjectDb.SystemTextJson | [](https://www.nuget.org/packages/GitObjectDb.SystemTextJson/) |
| GitObjectDb.YamlDotNet | [](https://www.nuget.org/packages/GitObjectDb.YamlDotNet/) |
| GitObjectDb.Api.OData | [](https://www.nuget.org/packages/GitObjectDb.Api.OData/) |
| GitObjectDb.Api.GraphQL | [](https://www.nuget.org/packages/GitObjectDb.Api.GraphQL/) |
| GitObjectDb.Api.ProtoBuf | [](https://www.nuget.org/packages/GitObjectDb.Api.ProtoBuf/) |
| GitObjectDb.Api.ProtoBuf.Model | [](https://www.nuget.org/packages/GitObjectDb.Api.ProtoBuf.Model/) |
[](https://github.com/frblondin/GitObjectDb/actions/workflows/Release.yml)
[](https://sonarcloud.io/dashboard/index/GitObjectDb)
[](https://sonarcloud.io/project/issues?id=GitObjectDb&resolved=false&types=BUG)
[](https://sonarcloud.io/component_measures?id=GitObjectDb&metric=Coverage)
[](https://sonarcloud.io/project/issues?id=GitObjectDb&resolved=false&types=CODE_SMELL)
# Overview
GitObjectDb is designed to simplify the configuration management versioning. It does so by removing the need for hand-coding the commands needed to interact with Git.
The Git repository is used as a pure database as the files containing the serialized copy of the objects are never fetched in the filesystem. GitObjectDb only uses the blob storage provided by Git.
Here's a simple example:
1. Define your own repository data model:
```csharp
[GitFolder("Applications")]
public record Application : Node
{
public string Name { get; init; }
public string Description { get; init; }
}
[GitFolder("Pages")]
public record Table : Node
{
public string Name { get; init; }
public string Description { get; init; }
[StoreAsSeparateFile(Extension = "txt")]
public string? RichContent { get; init; }
}
```
2. Manipulate objects as follows:
```csharp
var existingApplication = connection.Lookup("main", "applications", new UniqueId(id));
var newTable = new Table { ... };
connection
.Update("main", c => c.CreateOrUpdate(newTable, parent: existingApplication))
.Commit(new("Added new table.", author, committer));
```
# Features
## Structured & unstructured data storage
```csharp
var node = new SomeNode
{
SomeProperty = "Value stored as json",
RichContent = "Value stored as raw text in separate Git blob, next to primary one",
}:
```
... gets stored in Git as follows:
* zerzrzrz.json
```json
{
"$type": "Sample.SomeNode",
"id": "zerzrzrz",
"someProperty": "Value stored as json"
}
```
* zerzrzrz.RichContent.txt
```text
Value stored many dynamic resources in separate Git blob, next to primary one
```
You can also store resources as separate files:
```csharp
new Resource(node, "Some/Folder", "File.txt", new Resource.Data("Value stored in a separate file in /Resources/Some/Folder/File.txt"));
```
## Branching
```csharp
connection
.Update("main", c => c.CreateOrUpdate(table with { Description = newDescription }))
.Commit(new("Some message", signature, signature));
connection.Checkout("newBranch", "main~1");
connection
.Update("main", c => c.CreateOrUpdate(table with { Name = newName }))
.Commit(new("Another message", signature, signature));
```
## Comparing commits
```csharp
var comparison = connection.Compare("main~5", "main");
var nodeChanges = comparison.Modified.OfType();
```
## Node references
Node references allows linking existing nodes in a repository:
```csharp
public record Order : Node
{
public Client Client { get; set; }
// ...
}
public record Client : Node
{
// ...
}
// Nodes get loaded with their references (using a shared )
var cache = new Dictionary();
var order = connection.GetNodes("main", referenceCache: cache).First();
Console.WriteLine(order.Client.Id);
```
## Merge, Rebase, Cherry-pick
```csharp
// main: A---B A---B
// \ -> \ \
// newBranch: C C---x
connection
.Update("main", c => c.CreateOrUpdate(table with { Description = newDescription }))
.Commit(new("B", signature, signature));
connection.Repository.Branches.Add("newBranch", "main~1");
connection
.Update("newBranch", c => c.CreateOrUpdate(table with { Name = newName }))
.Commit(new("C", signature, signature));
sut.Merge(upstreamCommittish: "main");
```
## Node versioning management
Imagine a scenario where you define in your code a first type:
```csharp
[GitFolder(FolderName = "Items", UseNodeFolders = false)]
[IsDeprecatedNodeType(typeof(SomeNodeV2))]
private record SomeNodeV1 : Node
{
public int Flags { get; set; }
}
[GitFolder(FolderName = "Items", UseNodeFolders = false)]
private record SomeNodeV2 : Node
{
public BindingFlags TypedFlags { get; set; }
}
```
You then want to introduce a new change so that the `Flags` property contains more meaningful information, relying on enums:
```csharp
[GitFolder(FolderName = "Items", UseNodeFolders = false)]
private record SomeNodeV2 : Node
{
public BindingFlags TypedFlags { get; set; }
}
```
All you need to do is to #1 add the `[IsDeprecatedNodeType(typeof(SomeNodeV2))]` attribute. This will instruct the deserializer to convert nodes to new version, using a converter. #2 converter needs to be provided in the model. You can use AutoMapper or other tools at your convenience.
```csharp
[GitFolder(FolderName = "Items", UseNodeFolders = false)]
[IsDeprecatedNodeType(typeof(SomeNodeV2))]
private record SomeNodeV1 : Node
{
// ...
}
var model = new ConventionBaseModelBuilder()
.RegisterType()
.RegisterType()
.AddDeprecatedNodeUpdater(UpdateDeprecatedNode)
.Build();
Node UpdateDeprecatedNode(Node old, Type targetType)
{
var nodeV1 = (SomeNodeV1)old;
return new SomeNodeV2
{
Id = old.Id,
TypedFlags = (BindingFlags)nodeV1.Flags,
};
}
```
# Documentation
See [documentation][Documentation].
[Documentation]: https://gitobjectdb.readthedocs.io
# Prerequisites
- .NET Standard 2.0 or 2.1
# Online resources
- [LibGit2Sharp][LibGit2Sharp] (Requires NuGet 2.7+)
[LibGit2Sharp]: https://github.com/libgit2/libgit2sharp
# Quick contributing guide
- Fork and clone locally
- Create a topic specific branch. Add some nice feature. Do not forget the tests ;-)
- Send a Pull Request to spread the fun!
# License
The MIT license (Refer to the [LICENSE][license] file).
[license]: https://github.com/frblondin/GitObjectDb/blob/master/LICENSE