Skip to content
Derek Christensen edited this page Nov 17, 2022 · 28 revisions

Welcome to the LibGit2Sharp project wiki!

If you are interested in contributing to the development of this project we would love to have your help. Please take a moment to read through the contributing guide below.

General Support and Questions

  • If you've found a bug, want a new feature, please use the issue tracker
  • You've got a usage or programming related questions, please direct it to StackOverflow

Documentation

Let's put it simply: we currently lack proper documentation. Any help on this subject would be greatly appreciated ;-)

General usage

  • What is Git? Read the online book Pro Git.
  • The LibGit2Sharp Hitchhiker's Guide to Git should provide you with C# code snippets demonstrating the LibGit2Sharp API
  • You may find also some help in understanding how to use LibGit2Sharp by browsing the tests.

API documentation

We rely on Xml documentation comments to describe types and methods. This post shares some nice practices about it.

Contributing

  1. Configure your repo to convert line endings on commit so they are always LF (LineFeeds) in the repo. This requires changing the value of the core.autocrlf configuration entry. More information about this can been found on this help.github page.
    • On Windows:
      $ git config --global core.autocrlf true
    • On Linux:
      $ git config --global core.autocrlf input
  2. Fork the project on github and create a topic branch that is named after the feature you are implementing or the bug you are fixing. As the development is being done in the master branch, make sure to create your topic branch from the tip of it.
  3. Write tests, following the code style of the existing tests.
  4. Implement your feature or fix your bug. Please following existing coding styles and do not introduce new ones.
  5. Make atomic, focused commits with good commit messages.
  6. Make sure that feature commits are easy to review by separating code beautification proposals in dedicated commits (eg. code beautification commit).
  7. If you are using code from elsewhere (such as other open source projects, Stack Overflow posts, blog posts etc) then please make sure you give proper credit and a link to the source in your code comments. If you can then flag this fact in the pull request, we can double check we're doing everything to be compliant with how that person licensed their original code and their license is compatible with our very permissive MIT based open source license.
  8. Send a Pull Request targeting the master branch.

High Level Design Goals for the API

A lot of thought has gone into the current API design, please help keep things consistent. The following is a list of general guidelines for implementing new features in the API.

  1. The API should be intuitive, discoverable, and consistent.
  2. The Repository is intended to be the primary interface and root aggregate object for accessing all functionality. It is the only object that implements IDisposable.
  3. GitObjects like Tree, Tag, Blob, Commit should not implement IDisposable. The consumer should not have to worry about disposing these objects when they are returned from methods like repository.Lookup(sha).
  4. If you do have to implement IDisposable, please use the SafeHandle pattern.
  5. LibGit2Sharp should not be a 1:1 mapping of the libgit2 C API. This means that there maybe features in libgit2 that are not supported or are only exposed in a constrained manner.
  6. Sketch out the API design before implementing! Here is a good example of the initial API sketch done in a gist:
using (var repo = new Repository("path\to\repo.git"))
{
    // Object lookup
    var obj = repo.Lookup("sha");
    var commit = repo.Lookup<Commit>("sha");
    var tree = repo.Lookup<Tree>("sha");
    var tag = repo.Lookup<Tag>("sha");

    // Rev walking
    foreach (var c in repo.Commits.Walk("sha")) { }
    var commits = repo.Commits.StartingAt("sha").Where(c => c).ToList();
    var sortedCommits = repo.Commits.StartingAt("sha").SortBy(SortMode.Topo).ToList();

    // Refs
    var reference = repo.Refs["refs/heads/master"];
    var allRefs = repo.Refs.ToList();
    foreach (var c in repo.Refs["HEAD"].Commits) { }
    foreach (var c in repo.Head.Commits) { }
    var headCommit = repo.Head.Commits.First();
    var allCommits = repo.Refs["HEAD"].Commits.ToList();
    var newRef = repo.Refs.CreateFrom(reference);
    var anotherNewRef = repo.Refs.CreateFrom("sha");

    // Branches
    // special kind of reference
    var allBranches = repo.Branches.ToList();
    var branch = repo.Branches["master"];
    var remoteBranch = repo.Branches["origin/master"];
    var localBranches = repo.Branches.Where(p => p.Type == BranchType.Local).ToList();
    var remoteBranches = repo.Branches.Where(p => p.Type == BranchType.Remote).ToList();
    var newBranch = repo.Branches.CreateFrom("sha");
    var anotherNewBranch = repo.Branches.CreateFrom(newBranch);
    repo.Branches.Delete(anotherNewBranch);

    // Tags
    // really another special kind of reference
    var aTag = repo.Tags["refs/tags/v1.0"];
    var allTags = repo.Tags.ToList();
    var newTag = repo.Tags.CreateFrom("sha");
    var newTag2 = repo.Tags.CreateFrom(commit);
    var newTag3 = repo.Tags.CreateFrom(reference);
}

In many cases, if you are implementing brand new parts of the API it is a good idea to sketch out how the API would be used by a consumer, post it somewhere like gists and ask for some feedback before diving in and implementing.