GitObjectDb.Api.ProtoBuf 0.2.155-alpha

This is a prerelease version of GitObjectDb.Api.ProtoBuf.
dotnet add package GitObjectDb.Api.ProtoBuf --version 0.2.155-alpha                
NuGet\Install-Package GitObjectDb.Api.ProtoBuf -Version 0.2.155-alpha                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="GitObjectDb.Api.ProtoBuf" Version="0.2.155-alpha" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add GitObjectDb.Api.ProtoBuf --version 0.2.155-alpha                
#r "nuget: GitObjectDb.Api.ProtoBuf, 0.2.155-alpha"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install GitObjectDb.Api.ProtoBuf as a Cake Addin
#addin nuget:?package=GitObjectDb.Api.ProtoBuf&version=0.2.155-alpha&prerelease

// Install GitObjectDb.Api.ProtoBuf as a Cake Tool
#tool nuget:?package=GitObjectDb.Api.ProtoBuf&version=0.2.155-alpha&prerelease                

GitObjectDb simplifies the configuration management versioning by backing it in Git.

Name Badge
GitObjectDb NuGet Badge
GitObjectDb.SystemTextJson NuGet Badge
GitObjectDb.YamlDotNet NuGet Badge
GitObjectDb.Api.OData NuGet Badge
GitObjectDb.Api.GraphQL NuGet Badge
GitObjectDb.Api.ProtoBuf NuGet Badge
GitObjectDb.Api.ProtoBuf.Model NuGet Badge

Build Status alternate text is missing from this package README image alternate text is missing from this package README image alternate text is missing from this package README image alternate text is missing from this package README image

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:
    [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:
     var existingApplication = connection.Lookup<Application>("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

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
{
  "$type": "Sample.SomeNode",
  "id": "zerzrzrz",
  "someProperty": "Value stored as json"
}
  • zerzrzrz.RichContent.txt
Value stored many dynamic resources in separate Git blob, next to primary one

You can also store resources as separate files:

new Resource(node, "Some/Folder", "File.txt", new Resource.Data("Value stored in a separate file in <node path>/Resources/Some/Folder/File.txt"));

Branching

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

var comparison = connection.Compare("main~5", "main");
var nodeChanges = comparison.Modified.OfType<Change.NodeChange>();

Node references

Node references allows linking existing nodes in a repository:

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<DataPath, ITreeItem>();
var order = connection.GetNodes<Order>("main", referenceCache: cache).First();
Console.WriteLine(order.Client.Id);

Merge, Rebase, Cherry-pick

// 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:

[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:

[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.

[GitFolder(FolderName = "Items", UseNodeFolders = false)]
[IsDeprecatedNodeType(typeof(SomeNodeV2))]
private record SomeNodeV1 : Node
{
    // ...
}
var model = new ConventionBaseModelBuilder()
    .RegisterType<SomeNodeV1>()
    .RegisterType<SomeNodeV2>()
    .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.

Prerequisites

  • .NET Standard 2.0 or 2.1

Online resources

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 file).

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
0.2.155-alpha 58 3/29/2024
0.2.52-alpha 93 5/19/2023
0.2.42-alpha 103 3/28/2023
0.2.33-alpha 95 3/7/2023
0.2.32-alpha 101 3/7/2023
0.2.31-alpha 96 3/7/2023
0.2.30-alpha 108 2/4/2023