A .NET library for programmatically writing Git history to a Git repository. It simplifies the process of creating commits, branches, tags, and managing Git repository structure from code. While useful for tasks like converting repositories from other version control systems (e.g., Subversion), it can be used in any scenario where you need to generate Git history programmatically.
- Programmatic Git History Creation: Provides an API to create and manage Git commits, branches, and tags directly from your .NET code.
- Abstracts Git Complexity: Simplifies interaction with Git repositories, allowing developers to focus on the logic of history generation rather than low-level Git commands.
- Step-by-Step Commit Building: Supports building Git history revision by revision, suitable for processing data from external sources in chunks.
- Author Mapping: Allows you to map author names to Git author identities (name and email), crucial for accurate history representation.
- Flexible Change Handling: Provides mechanisms to define file and directory changes (add, modify, delete, replace) within commits, including content for both text and binary files.
- Extensible Architecture: Designed with interfaces and factories for customization and extension of conversion processes.
- .NET 9.0 Compatibility: Built using modern .NET features for performance and maintainability.
- .NET 9.0 SDK or later.
- A compatible IDE for .NET development (e.g., Visual Studio, Visual Studio Code with C# extension, Rider).
- Git command-line tools must be installed and accessible in your environment, as the library interacts with Git repositories on disk.
As GitImporter is a library, you would typically include it in your .NET project using NuGet.
-
Add NuGet Package: You can add the
GitImporterNuGet package to your project using the .NET CLI or your IDE's NuGet package manager.Using .NET CLI:
dotnet add package GitImporter
Using Visual Studio NuGet Package Manager:
- Right-click on your project in Solution Explorer.
- Select "Manage NuGet Packages...".
- Go to the "Browse" tab and search for "GitImporter".
- Select the
GitImporterpackage and click "Install".
To use GitImporter, you will typically:
- Create a
CompositionRoot: This is the entry point for accessing the library's services and managing the Git repository context. - Get a
IGitRevisionConverter: This service is responsible for converting and writing individual revisions (commits) to the Git repository. - Prepare
GitRevisionobjects: Create instances ofGitRevisionandGitNodeChange(fromGitImporter.Models) to represent the history you want to write to Git. This is where you would process data from your source (e.g., SVN dump, another system, or generate history programmatically). - Use the
IGitRevisionConverterto convert and write eachGitRevision. - Call
Checkout()on theCompositionRootafter all revisions are processed to finalize the Git repository (e.g., checkout the main branch).
Example Code Snippet (Conceptual - You'll need to adapt this to your specific data source):
using GitImporter;
using GitImporter.Models;
using GitImporter.Interfaces; // Make sure to include this for IAuthorsMap if you're using it
public class ExampleImporter
{
public static void Main(string[] args)
{
string gitRepoPath = "path/to/your/new/git/repo"; // Specify where to create/use the Git repo
// You might need to initialize an empty Git repository at gitRepoPath beforehand
// Example Author Mapping (if needed) - Implement IAuthorsMap
IAuthorsMap authorsMap = new MyAuthorsMap(); // Create your own implementation
using (var compositionRoot = new CompositionRoot(gitRepoPath, authorsMap))
{
var revisionConverter = compositionRoot.GetRevisionConverter();
// Simulate processing some data source and creating GitRevisions
List<GitRevision> revisionsToImport = GenerateRevisionsFromDataSource();
foreach (var gitRevision in revisionsToImport)
{
revisionConverter.ConvertRevision(gitRevision);
}
compositionRoot.Checkout(); // Finalize Git repository
}
Console.WriteLine("Git history import complete!");
}
// Example: You would replace this with your actual data processing logic
static List<GitRevision> GenerateRevisionsFromDataSource()
{
var revisions = new List<GitRevision>();
// Example Revision 1
var revision1 = new GitRevision
{
Number = 1,
Author = "user1", // SVN username or similar identifier
Date = DateTime.Now.AddDays(-2),
LogMessage = "Initial commit",
};
revision1.AddNode(new GitNodeChange { Action = EChangeAction.Add, Kind = ENodeKind.File, Path = "file1.txt", TextContent = "Content of file1" });
revisions.Add(revision1);
// Example Revision 2
var revision2 = new GitRevision
{
Number = 2,
Author = "user2", // SVN username or similar identifier
Date = DateTime.Now.AddDays(-1),
LogMessage = "Modify file1 and add file2",
};
revision2.AddNode(new GitNodeChange { Action = EChangeAction.Modify, Kind = ENodeKind.File, Path = "file1.txt", TextContent = "Updated content of file1" });
revision2.AddNode(new GitNodeChange { Action = EChangeAction.Add, Kind = ENodeKind.File, Path = "file2.txt", TextContent = "Content of file2" });
revisions.Add(revision2);
return revisions;
}
// Example IAuthorsMap implementation (replace with your actual mapping logic)
class MyAuthorsMap : IAuthorsMap
{
public string GetAuthorEmail(string authorName)
{
// Implement your author mapping logic here.
// For example, based on authorName, return the corresponding Git email.
if (authorName == "user1") return "user1@example.com";
if (authorName == "user2") return "user2@example.com";
return "default@example.com"; // Default email if no mapping found
}
}
}Important Notes:
- Repository Initialization:
GitImporterassumes you have a Git repository ready at the specifiedgitRepoPath. You might need to initialize an empty repository usinggit initcommand or through code before usingGitImporter. The library does not create the repository itself. - Error Handling: The example code is simplified. In a real application, you would need to add proper error handling, logging, and potentially progress reporting.
- Author Mapping Implementation: You'll need to implement the
IAuthorsMapinterface according to your author mapping requirements. The exampleMyAuthorsMapis just a placeholder. - Data Source Integration: The
GenerateRevisionsFromDataSource()function is a placeholder. You will replace this with code that reads your data source (SVN dump, database, other VCS, etc.) and transforms it intoGitRevisionobjects.
The GitImporter library supports author mapping through the IAuthorsMap interface. This is essential for correctly attributing commits in Git when importing history from systems that use different author identifiers (like SVN usernames).
To use author mapping:
-
Implement the
IAuthorsMapInterface: Create a class that implements theGitImporter.Interfaces.IAuthorsMapinterface. The interface has a single method:string GetAuthorEmail(string authorName);
Your implementation of
GetAuthorEmailshould take an author name (e.g., an SVN username) as input and return the corresponding Git author's email address. You can use any logic you need within this method (e.g., lookups in a dictionary, reading from a file, etc.). -
Pass your
IAuthorsMapimplementation to theCompositionRootconstructor when creating an instance ofCompositionRoot. If you don't provide anIAuthorsMap, a default implementation will be used (which might not perform any mapping).
Example IAuthorsMap Implementation (using a Dictionary):
using GitImporter.Interfaces;
using System.Collections.Generic;
public class DictionaryAuthorsMap : IAuthorsMap
{
private readonly Dictionary<string, string> _authorMap;
public DictionaryAuthorsMap(Dictionary<string, string> authorMap)
{
_authorMap = authorMap;
}
public string GetAuthorEmail(string authorName)
{
if (_authorMap.TryGetValue(authorName, out string? email))
{
return email;
}
return "default@example.com"; // Default email if no mapping found
}
}Usage with DictionaryAuthorsMap:
// ... (rest of your code)
Dictionary<string, string> myAuthorMappings = new Dictionary<string, string>()
{
{"svn_user1", "Git User One <gituser1@example.com>"},
{"svn_user2", "Git User Two <gituser2@example.com>"}
};
IAuthorsMap authorsMap = new DictionaryAuthorsMap(myAuthorMappings);
using (var compositionRoot = new CompositionRoot(gitRepoPath, authorsMap))
{
// ... (rest of your import logic)
}This project is licensed under the MIT License. See the LICENSE file for details.
For questions, bug reports, or feature requests, please open an issue on the [GitHub repository]([Your GitHub Repository Link Here]).