git2go

repository·main·Indexed 24 days ago

https://github.com/libgit2/git2go

Go bindings for the libgit2 library, providing Go developers with a high-performance C implementation for performing Git operations. The library includes APIs for managing branches, blobs, checkout operations, and performing line-by-line blame operations.

Tokens
31.7K
Snippets
62
Records
260
Agent score
84%

What's inside git2go

  1. Map libgit2 versions to git2go module versions

    main

    Because Go 1.11 module versions follow semantic versioning and do not align with libgit2's release schedule, you must use the correct git2go module suffix to match your installed libgit2 version. This ensures API stability.

    libgit2git2go module version
    main(will be v35)
    1.5v34
    1.3v33
    1.2v32
    1.1v31
    1.0v30
    0.99v29
    0.28v28
    0.27v27
  2. Run git2go tests

    main

    Testing requirements depend on the branch you are using:

    • Stable versions: Use go test as usual.
    • main branch: Requires a local libgit2 library. You can use the provided Makefile wrapper:
      make test-static
      Or build the library manually first:
      make install-static
      go test -v -tags static ./...
    make test-static
  3. Install git2go using dynamic linking

    main

    To use a versioned branch with dynamic linking, install the corresponding libgit2 version via your system's package manager. CGo will use pkg-config to locate the library and set up linking automatically.

    Example for libgit2 v1.2 (using git2go v34):

    go get github.com/libgit2/git2go/v34
    import "github.com/libgit2/git2go/v34"
  4. Install git2go using the main branch or vendored static linking

    main

    When using the main branch or building with the vendored libgit2, you must compile libgit2 manually.

    Prerequisites:

    • cmake, pkg-config, and a C compiler.
    • OpenSSL development packages (required for HTTPS support, except on Windows/macOS).
    • LibSSH2 development packages (required for SSH support).

    Steps:

    1. Download the code: go get -d github.com/libgit2/git2go
    2. Navigate to your $GOPATH/src/github.com/libgit2/git2go directory.
    3. Build and install:
      git submodule update --init
      make install-static

    Important Notes:

    • When building binaries, you must pass the -tags static flag to all go commands.
    • Because Go expects the pkg-config file to be in the same directory where make install-static was executed, you may need to use a replace directive in your project's go.mod file to point to the local git2go directory.

    Example go.mod replace directive: If your project is at $GOPATH/src/github.com/my/project and git2go is at $GOPATH/src/github.com/libgit2/git2go:

    replace github.com/libgit2/git2go/v34 => ../../libgit2/git2go
    git submodule update --init
    make install-static
  5. Install git2go using static linking (system libgit2)

    main

    To link statically against a versioned libgit2 already installed on your system, you must pass the -tags static,system_libgit2 flag to all go commands used during the build process.

    go build -tags static,system_libgit2 github.com/my/project/...
    go test -tags static,system_libgit2 github.com/my/project/...
    go install -tags static,system_libgit2 github.com/my/project/...
  6. Implement custom protocols with SmartSubtransport

    main

    If you need to support a custom communication protocol for Git remotes, you can implement the SmartSubtransport interface and register it using NewRegisteredSmartTransport.

    To implement a custom subtransport, you must provide:

    1. An Action(url string, action SmartServiceAction) method: This creates a SmartSubtransportStream for a specific URL and requested action (e.g., SmartServiceActionUploadpack).
    2. A Close() method: Closes the subtransport.
    3. A Free() method: Releases all resources used by the subtransport.

    The SmartSubtransportStream (which you return from Action) must implement io.Reader, io.Writer, and a Free() method to handle the actual data transfer.

  7. Manage the Git Index (Staging Area)

    main
    The Index type in git2go provides an interface to manage the Git staging area. You can create a new in-memory index using NewIndex(), or open an existing index from a file path using OpenIndex(path). Changes made to the index in memory are not persistent until Write() is called.
  8. Manage git stash operations with StashCollection

    main

    The StashCollection type provides the primary interface for managing the stash list in a repository. You can use it to save new stashes, apply existing ones, pop them from the list, drop specific entries, or iterate over all stashed states.

    Key methods:

    • Save(stasher *Signature, message string, flags StashFlag) (*Oid, error): Saves local modifications to a new stash.
    • Apply(index int, opts StashApplyOptions) error: Applies a stashed state at the given index (0 is the most recent).
    • Pop(index int, opts StashApplyOptions) error: Applies a stashed state and removes it from the list if successful.
    • Drop(index int) error: Removes a stashed state at the given index.
    • Foreach(callback StashCallback) error: Iterates over all stashes, calling the provided callback for each entry.
  9. Interact with the Git Object Database (ODB)

    main

    The Odb type provides the primary interface for interacting with Git's object storage. You can use it to read, write, hash, and iterate over Git objects (blobs, trees, commits, etc.).

    Key operations include:

    • Reading: Use Read(oid) to get an OdbObject or NewReadStream(id) for streaming large objects.
    • Writing: Use Write(data, otype) for small objects or NewWriteStream(size, otype) for streaming writes.
    • Existence/Metadata: Use Exists(oid) to check for an object or ReadHeader(oid) to get its size and type without loading the full content.
    • Hashing: Use Hash(data, otype) to compute the Oid of a data buffer.
  10. How Branch and Reference relate

    main

    In git2go, a Branch is a specialized type that embeds a *Reference. This means a Branch provides all the functionality of a Git reference (like a pointer to a commit) but adds branch-specific logic such as upstream management and branch-specific iteration.

    You can convert any *Reference into a *Branch using the Branch() method on the reference.

    branch := reference.Branch()
  11. Manage Git submodules with SubmoduleCollection and Submodule

    main

    The git2go API provides two primary types for submodule management: SubmoduleCollection (representing the set of submodules in a repository) and Submodule (representing an individual submodule).

    • Use SubmoduleCollection.Lookup(name string) to find a specific submodule by its name.
    • Use SubmoduleCollection.Foreach(callback SubmoduleCallback) to iterate over all submodules in the repository.
    • Use SubmoduleCollection.Add(url, path string, use_git_link bool) to prepare a new submodule.
    • Use Submodule.Open() to obtain a *Repository instance for the submodule's own working directory.
    • Use Submodule.Update(init bool, opts *SubmoduleUpdateOptions) to update the submodule's content.
  12. Traverse git commit history with RevWalk

    main

    The RevWalk type allows you to traverse the commit history of a repository. You can define the scope of the walk by pushing specific commits, globs, ranges, or references, and you can exclude certain commits using Hide methods. The traversal can be configured with different sorting strategies and can be executed manually using Next or via a high-level Iterate function.

    To use RevWalk, you typically:

    1. Push starting points (e.g., PushHead, Push, PushRef).
    2. (Optional) Hide specific commits or references.
    3. Set a sorting strategy using Sorting.
    4. Iterate through the commits using Iterate.