localgit

package
v0.38.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 6, 2026 License: Apache-2.0 Imports: 7 Imported by: 0

Documentation

Overview

Package localgit reads the local Git repository through the git binary.

It is deliberately read-only where credentials are concerned: nothing here writes a token into .git/config, and nothing here pushes. Pushing is always the user's own `git push`, with the credentials already on their machine.

Index

Constants

View Source
const DefaultRemoteName = "origin"

DefaultRemoteName is the remote picked when a repository has several and the caller did not name one.

View Source
const Placeholder = "[redacted: unrecognized remote URL]"

Placeholder stands in for a remote URL whose parts could not be identified, so that none of its contents are echoed.

Variables

View Source
var (
	// ErrGitUnavailable indicates git could not report this directory's
	// remotes. The directory may not be a repository, git may be missing, or
	// git may have refused to read it — dubious ownership in a container,
	// an unreadable config. git's own message is appended whenever there is
	// one, because the fix differs sharply per cause and "not a git
	// repository" points nowhere near most of them.
	ErrGitUnavailable = errors.New("could not read this directory's Git repository")
	// ErrNoRemotes indicates a repository that has no remote configured.
	ErrNoRemotes = errors.New("no remote URLs found in your Git config")
	// ErrNotGitHub indicates a remote URL that does not point at github.com.
	ErrNotGitHub = errors.New("remote is not a github.com repository")
	// ErrUnparsableRemote indicates a remote URL that is not a recognizable Git URL.
	ErrUnparsableRemote = errors.New("remote URL could not be parsed")
)

Functions

func Redact

func Redact(rawURL string) string

Redact renders a remote URL safe to print. CI systems rewrite remotes to carry a job token — GitLab's is "https://gitlab-ci-token:<token>@…", and the url.<base>.insteadOf idiom injects one into any URL — so a message naming the remote would otherwise put that token in the build log.

A recognized URL comes back with its whole userinfo removed, not just a password field: a token is as often the entire userinfo ("https://<pat>@github.com/owner/repo.git" is GitHub's own documented form), and nothing distinguishes that from a user name.

Anything whose parts cannot be identified comes back as Placeholder rather than verbatim. git accepts remotes whose "URL" is a command line ("ext::ssh -o Password=… %S repo.git"), a local path, or — when an argument was mistyped — a bare token, and none of those can be safely echoed.

The scheme is checked against the transports git names, not taken as whatever precedes the first "://". A transport helper's command line frequently ends in a URL — git's own documented example is "ext::ssh -o Password=… %S ssh://…" — and splitting on the first "://" makes the whole command line up to that point the "scheme", which was then echoed with the password in it.

Types

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client runs git in the working directory.

func New

func New(deps cliruntime.Deps) Client

New returns a client that runs the real git binary unless deps injects a runner.

func (Client) PushRemote added in v0.22.1

func (c Client) PushRemote(ctx context.Context) (PushRemote, error)

PushRemote reads the push routing out of the repository's configuration.

func (Client) Remotes

func (c Client) Remotes(ctx context.Context) ([]Remote, error)

Remotes returns the remotes configured in the working directory, in git's own output order, each carrying both of its URLs.

type PushRemote added in v0.22.1

type PushRemote struct {
	Name string
	// Source is the config key that set Name, so a configuration pointing
	// somewhere unusable can be reported by the key the user has to fix.
	Source string
	// RewrittenURL is Name after git's push URL rewriting, and is empty when no
	// rule matched — the ordinary case. It only applies when Name is used as a
	// URL rather than as a remote name, because git looks the name up first.
	RewrittenURL string
}

PushRemote names the remote a `git push` with no arguments would send to, and the config key that decided it. Both are empty when the configuration does not say, which is the common case.

git resolves this in a precedence git help config spells out — branch.<name>.pushRemote, then remote.pushDefault, then branch.<name>.remote — and only falls back to origin when none is set. Picking origin regardless would bind the repository a triangular or fork checkout never pushes to.

type Remote

type Remote struct {
	Name string
	// FetchURL is where the remote fetches from.
	FetchURL string
	// PushURLs is every destination a push to this remote reaches. git accepts
	// several `remote.<name>.pushurl` entries and a single push updates all of
	// them, so a remote with more than one names no single repository to bind.
	// git prints the fetch URL as the sole push URL unless a pushurl is set.
	PushURLs []string
}

Remote is one configured Git remote.

func SelectRemote

func SelectRemote(remotes []Remote, name string, push PushRemote) (Remote, error)

SelectRemote picks the push destination to connect. A named remote must exist. With no name, where git would push wins, then a lone remote, then "origin"; anything else is ambiguous and the caller has to choose.

push comes from Client.PushRemote and is what makes this agree with git rather than with a convention: in a fork checkout the repository that receives pushes — and so the one a deployment comes from — is routinely not origin.

func (Remote) Diverges

func (r Remote) Diverges() bool

Diverges reports whether this remote fetches from a different repository than the single one it pushes to.

Repositories, not URL strings: fetching over https and pushing over ssh is an ordinary setup — `git remote set-url --push` and url.<base>.pushInsteadOf both produce it — and the two spellings name the same repository. Comparing the strings would report every such checkout as pointing at two places.

func (Remote) Named added in v0.22.1

func (r Remote) Named() bool

Named reports whether this destination is one of the repository's configured remotes. An unnamed one came from a URL in git's push configuration, and has to be described by its redacted URL rather than by a remote name that does not exist.

func (Remote) PushTarget

func (r Remote) PushTarget() (string, error)

PushTarget returns the one repository a push to this remote reaches. A push is what triggers a deployment, so this — not the fetch URL — is what a binding has to name; a remote that reaches several has no answer, and choosing one would bind a repository while pushes kept updating the others.

type Repository

type Repository struct {
	Owner string
	Name  string
}

Repository is a GitHub repository identified by a remote URL.

func ParseGitHubRepository

func ParseGitHubRepository(rawURL string) (Repository, error)

ParseGitHubRepository resolves a Git remote URL to the GitHub repository it names. It accepts the three forms GitHub hands out — scp-like SSH (git@github.com:owner/repo.git), ssh:// URLs, and https:// URLs — and rejects anything hosted elsewhere, since the platform's only provider is GitHub.

func (Repository) FullName

func (r Repository) FullName() string

FullName returns the owner/name form the API selects repositories by.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL