Documentation
¶
Overview ¶
Package git provides helper functions to execute common Git commands by wrapping the system's git binary using os/exec.
Index ¶
- Variables
- func Clone(ctx context.Context, url, targetDir string, opts CloneOptions) error
- func CurrentBranch(targetDir string) (string, error)
- func IsEmpty(targetDir string) bool
- func Pull(ctx context.Context, targetDir string, opts PullOptions) error
- func RemoteOrigin(targetDir string) (string, error)
- func RemoteOriginFromConfig(targetDir string) (string, error)
- func ResolveGitBinary() error
- type CloneOptions
- type PullOptions
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var TokenProvider func() string
TokenProvider, when set, returns a GitHub token used to authenticate HTTPS operations against github.com so private repositories can be cloned and pulled non-interactively. The token is supplied to git via GIT_CONFIG_* environment variables (an http extraheader scoped to https://github.com/), so it is never written to a repository's .git/config or exposed in the process argument list.
Functions ¶
func Clone ¶
func Clone(ctx context.Context, url, targetDir string, opts CloneOptions) error
Clone executes a git clone command for the given URL into the target directory.
Example ¶
ExampleClone demonstrates a shallow, single-branch, blobless partial clone — the combination Corral uses to minimise bandwidth and disk for large mirrors.
package main
import (
"context"
"log"
"github.com/sebastienrousseau/corral/internal/git"
)
func main() {
ctx := context.Background()
opts := git.CloneOptions{
SingleBranch: true,
Blobless: true,
Depth: 1,
}
if err := git.Clone(ctx, "https://github.com/sebastienrousseau/corral.git", "/tmp/corral", opts); err != nil {
log.Printf("clone failed: %v", err)
}
}
Output:
func CurrentBranch ¶
CurrentBranch retrieves the name of the currently checked-out branch.
func IsEmpty ¶ added in v0.0.13
IsEmpty reports whether the repo at targetDir has no commits.
This is the local mirror of "an empty GitHub repository" — one that was created upstream but never pushed to. Its .git/refs/heads is empty and HEAD is unborn, so `git pull` fails with "no such ref was fetched". Detecting the state locally lets corral treat it as SKIP-with-reason instead of surfacing that git error to the user.
`git rev-parse --verify HEAD^{commit} -q` returns 0 exactly when HEAD resolves to a commit. On any failure — unborn HEAD (empty repo), corrupted refs, or the target not being a git repo at all — this returns true. Callers should have already established that targetDir *is* a git repo (via a .git-directory check) before calling; the "not a git repo" case is defence-in-depth.
func Pull ¶
func Pull(ctx context.Context, targetDir string, opts PullOptions) error
Pull executes a `git pull --rebase --autostash` in the target directory. Signature verification (merge.verifySignatures / rebase.verifySignatures) and commit signing (commit.gpgsign) are explicitly disabled for this invocation so an unattended sync never aborts on unsigned commits or blocks on a GPG/SSH passphrase prompt for users who sign commits globally.
When opts.RecurseSubmodules is true:
- if opts.IgnoreSubmoduleFailures is false, --recurse-submodules is appended to the pull so failures abort the whole operation (existing pre-v0.0.7 behaviour);
- if opts.IgnoreSubmoduleFailures is true, the pull runs without --recurse-submodules and submodule updates are attempted in a separate `git submodule update --init --recursive` step whose error is logged but not returned.
Example ¶
ExamplePull demonstrates updating an existing clone with rebase + autostash, recursing into submodules but tolerating submodule failures so a single inaccessible nested repo doesn't block the parent sync.
package main
import (
"context"
"log"
"github.com/sebastienrousseau/corral/internal/git"
)
func main() {
ctx := context.Background()
opts := git.PullOptions{
RecurseSubmodules: true,
IgnoreSubmoduleFailures: true,
}
if err := git.Pull(ctx, "/tmp/corral", opts); err != nil {
log.Printf("pull failed: %v", err)
}
}
Output:
func RemoteOrigin ¶
RemoteOrigin retrieves the remote origin URL of the target directory by invoking `git remote get-url origin`. Prefer RemoteOriginFromConfig on hot paths (e.g. orphan detection over hundreds of clones) to avoid the per-call cost of spawning a subprocess.
func RemoteOriginFromConfig ¶ added in v0.0.7
RemoteOriginFromConfig parses the `url =` entry under [remote "origin"] directly from <targetDir>/.git/config, avoiding the ~5-15ms per-call cost of spawning `git remote get-url origin`. Returns the wrapped os.ErrNotExist when the config file is absent, and a clear error when the section or key is missing. Tolerates blank lines, `#` / `;` comments, indented entries, and CRLF line endings.
func ResolveGitBinary ¶ added in v0.0.7
func ResolveGitBinary() error
ResolveGitBinary looks up the absolute path to the git executable on PATH and caches it for the rest of the process. Returns a clear error when git is not installed.
Types ¶
type CloneOptions ¶ added in v0.0.3
type CloneOptions struct {
// RecurseSubmodules, when true, clones submodules recursively by adding
// the --recurse-submodules flag.
RecurseSubmodules bool
// SingleBranch, when true, clones only the history of the default branch
// by adding the --single-branch flag.
SingleBranch bool
// Blobless, when true, performs a blobless partial clone by adding the
// --filter=blob:none flag, deferring blob downloads until needed.
Blobless bool
// Depth, when greater than zero, creates a shallow clone truncated to the
// given number of commits by adding the --depth flag.
Depth int
}
CloneOptions configures optional clone-time performance and layout flags.
type PullOptions ¶ added in v0.0.7
type PullOptions struct {
// RecurseSubmodules, when true, also updates submodules after the pull.
// When IgnoreSubmoduleFailures is set, the submodule update runs as a
// separate step so its failure does not abort the parent pull.
RecurseSubmodules bool
// IgnoreSubmoduleFailures, when true, logs (but does not propagate)
// errors from the post-pull submodule update step. Useful when a
// submodule has been deleted upstream or access has been revoked but
// the parent repository's history should still update.
IgnoreSubmoduleFailures bool
}
PullOptions configures a `git pull` invocation.