Documentation
¶
Overview ¶
Package gitutil provides utilities for working with git repositories. All git operations shell out to the git CLI via Run; the go-git library must not be used here. Credential-embedded remote URLs may be passed as command-line arguments, but must never be persisted to .git/config; Run redacts URL credentials in error messages.
Index ¶
- Variables
- func Checkout(repoDir, branch string, force, create bool, startPoint string) error
- func Clone(ctx context.Context, path, remote, checkoutBranch string, ...) error
- func CloneRepo(ctx context.Context, repoURL string) (string, error)
- func CloneWithConfig(ctx context.Context, path string, config *Config) error
- func CommitAll(ctx context.Context, path, pathspec, message string, author Signature) (string, error)
- func CommitAndForcePush(ctx context.Context, path string, config *Config, commitMsg string, ...) error
- func CommitAndPush(ctx context.Context, path string, config *Config, commitMsg string, ...) error
- func CurrentBranch(ctx context.Context, path string) (string, error)
- func Diff(ctx context.Context, path, subpath, remoteName, remoteBranch string) (string, error)
- func EnsureGitignoreHas(ctx context.Context, repo drivers.RepoStore, path string) (bool, error)
- func EnsureInit(ctx context.Context, path, defaultBranch string) error
- func Fetch(ctx context.Context, path string, config *Config) error
- func FetchBranches(ctx context.Context, path string, branches ...string) error
- func ForcePush(ctx context.Context, path, remote, branch string) error
- func Hash(ctx context.Context, path, ref string) (string, error)
- func InferRepoRoot(path string) (string, error)
- func InferRepoRootAndSubpath(path string) (string, string, error)
- func IsCommitHash(s string) bool
- func IsGitRepo(path string) bool
- func MergeWithBailOnConflict(path, branch string) (bool, error)
- func MergeWithStrategy(path, branch, strategy string) error
- func NormalizeGithubRemote(remote string) (string, error)
- func Pull(ctx context.Context, path string, discardLocal bool, remote, remoteName string) (string, error)
- func Push(ctx context.Context, path, remote, refspec string) error
- func RemoveRemote(path, remoteName string) error
- func Revert(ctx context.Context, path, subpath, remoteName, remoteBranch string, ...) ([]string, error)
- func Run(ctx context.Context, path string, args ...string) (string, error)
- func SetRemote(path string, config *Config) error
- func SplitGithubRemote(remote string) (account, repo string, ok bool)
- func UpstreamMerge(ctx context.Context, path, remoteName, branch string, favourLocal bool) error
- type ChangedFile
- type ChangedFileStatus
- type Config
- type GitStatus
- type Remote
- type Signature
Constants ¶
This section is empty.
Variables ¶
var ErrDetachedHead = errors.New("detached HEAD state detected, please checkout a branch")
ErrDetachedHead is returned when an operation requires HEAD to point to a branch.
var ErrEmptyCommit = errors.New("nothing to commit")
ErrEmptyCommit is returned by CommitAll when there are no changes to commit.
var ErrGitRemoteNotFound = errors.New("no git remotes found")
var ErrNotAGitRepository = errors.New("not a git repository")
var ErrRefNotFound = errors.New("git reference not found")
Functions ¶
func Checkout ¶ added in v0.87.0
Checkout checks out a branch using the git command. If create is true, it creates the branch (using -B) at the given startPoint. go-git wipes out git-ignored changes during checkout so must use the git command.
func CloneRepo ¶ added in v0.88.0
CloneRepo clones the repository at repoURL into the current working directory and returns the repository name.
func CloneWithConfig ¶ added in v0.88.0
CloneWithConfig clones the remote described by config into path, naming the remote config.RemoteName() and checking out config.DefaultBranch. Only the clean config.Remote URL is persisted in the repo's config; credentials are passed exclusively on the command line.
func CommitAll ¶ added in v0.87.0
func CommitAll(ctx context.Context, path, pathspec, message string, author Signature) (string, error)
CommitAll stages all changes in the working tree and creates a commit with the given message. If pathspec is non-empty, staging and the empty-commit check are scoped to that pathspec. The commit's author and committer are set to the provided author. Returns the new commit hash, or ErrEmptyCommit if there are no changes to commit.
func CommitAndForcePush ¶ added in v0.88.0
func CommitAndForcePush(ctx context.Context, path string, config *Config, commitMsg string, author Signature) error
CommitAndForcePush is similar to CommitAndPush but force pushes the local changes to the remote. Unlike CommitAndPush, the current local branch need not match config.DefaultBranch, and HEAD may be detached.
func CommitAndPush ¶ added in v0.88.0
func CommitAndPush(ctx context.Context, path string, config *Config, commitMsg string, author Signature) error
CommitAndPush stages and commits all changes at path (scoped to config.Subpath if set) and pushes the current branch to the remote described by config. It initializes a git repository at path if one does not exist. If there is nothing new to commit, it still attempts the push. Only the clean config.Remote URL is persisted in the repo's config; credentials are passed exclusively on the command line.
func CurrentBranch ¶ added in v0.88.0
CurrentBranch returns the name of the branch HEAD points to. It also succeeds on unborn branches in repositories without commits. Returns ErrDetachedHead if HEAD is detached.
func Diff ¶ added in v0.88.0
Diff returns the combined unified patch between the working tree at path and the comparison ref, i.e. the changes that would land on the ref if merged. It mirrors ChangedFiles: committed, staged, and untracked changes are all included.
The result is git's standard unified diff format, ready for rendering. Per-file sections larger than maxFileDiffBytes are replaced with a "diff too large" placeholder. (Genuinely binary files stay small because git emits a "Binary files … differ" line for them rather than their content.)
func EnsureGitignoreHas ¶ added in v0.87.0
EnsureGitignoreHas ensures the given path is listed in .gitignore. Returns true if .gitignore was modified.
func EnsureInit ¶ added in v0.88.0
EnsureInit initializes a git repository at path if one does not already exist. If defaultBranch is non-empty, the initial (unborn) branch is named after it. It is a no-op if path already contains a .git entry (a directory in a regular checkout, or a file in a linked worktree).
func Fetch ¶ added in v0.88.0
Fetch fetches the latest changes from the remote described by config, updating the remote-tracking refs under `refs/remotes/<remote-name>/`. If config is nil or carries no credentials, it fetches from origin relying on git's own configuration and credential helpers.
func FetchBranches ¶ added in v0.87.0
FetchBranches fetches the specified branches from the remote repository. If a branch doesn't exist on the remote, it will be skipped without returning an error.
func ForcePush ¶ added in v0.88.0
ForcePush force-pushes HEAD to branch on remote, overwriting the remote ref unconditionally. It uses the refspec HEAD:<branch> so it works even when the local HEAD is detached or points to a different branch. remote may be a remote name or a URL with embedded credentials.
func Hash ¶ added in v0.87.0
Hash returns the commit hash for the given ref. Returns ErrRefNotFound if the ref does not resolve.
func InferRepoRoot ¶ added in v0.88.0
InferRepoRoot returns the root of the git working tree containing path. Returns ErrNotAGitRepository if path is not inside a git working tree.
func InferRepoRootAndSubpath ¶ added in v0.88.0
InferRepoRootAndSubpath infers the root of the Git repository and the subpath from the given path. Since the extraction stops at first .git directory it means that if a subpath in a github monorepo is deployed as a rill managed project it will prevent the subpath from being inferred. This means : - user will need to explicitly set the subpath if they want to connect this to Github. - When finding matching projects it will only list the rill managed projects for that subpath.
func IsCommitHash ¶ added in v0.87.0
IsCommitHash reports whether s is a full hex commit hash (SHA-1 or SHA-256). Use it to validate untrusted hashes before passing them as git CLI arguments: it rules out strings that git would interpret as flags or other revision syntax.
func IsGitRepo ¶ added in v0.87.0
IsGitRepo reports whether path is inside a git working tree. Returns true for the repo root as well as any subdirectory of it.
func MergeWithBailOnConflict ¶
MergeWithBailOnConflict attempts to merge a branch into the current branch and aborts if there are conflicts. Returns true if merge was successful, false if there were conflicts (but abort succeeded). Returns an error if the merge failed for a reason other than conflicts, or if both merge and abort fail.
func MergeWithStrategy ¶ added in v0.87.0
MergeWithStrategy merge a branch into the current branch using the specified strategy.
func NormalizeGithubRemote ¶ added in v0.88.0
NormalizeGithubRemote validates and converts a Git remote to a normalized HTTPS Github URL ending in .git. Any credentials embedded in the remote are stripped.
func Pull ¶ added in v0.88.0
func Pull(ctx context.Context, path string, discardLocal bool, remote, remoteName string) (string, error)
Pull pulls the latest changes from the remote into the current branch. If discardLocal is true, local changes and local commits are stashed away first. If git rejects the pull (e.g. on divergent branches), the (credential-redacted) git error message is returned as the output with a nil error, so callers can surface it to users.
func Push ¶ added in v0.88.0
Push pushes the given refspec (commonly just a branch name) to the remote. remote may be a remote name or a URL, optionally with embedded credentials (which are passed as an argument only and redacted from any error).
func RemoveRemote ¶ added in v0.88.0
RemoveRemote removes the named remote from the repository at path. It is a no-op if the remote does not exist.
func Revert ¶ added in v0.88.0
func Revert(ctx context.Context, path, subpath, remoteName, remoteBranch string, paths []string) ([]string, error)
Revert discards local changes for the given files, resetting them to the target-branch state, i.e. the merge base of HEAD and `<remoteName>/<remoteBranch>` (the same comparison ref used by ChangedFiles and Diff). It mirrors ChangedFiles: a file reverts to the state it has on the target branch, undoing committed, staged, and untracked local changes to it.
paths are subpath-relative, matching the paths returned by ChangedFiles. Paths that are not actually changed relative to the target branch are silently skipped. If paths is empty, all changed files are reverted. The subpath-relative paths that were reverted are returned.
The revert is applied per file according to its change status:
- Modified/Deleted: restored from the merge base (content and index).
- Added: removed from the index (if staged) and deleted from the working tree.
- Renamed: the old path is restored from the merge base and the new path is removed.
func Run ¶ added in v0.87.0
Run executes a git command with the specified arguments in the given path and returns its output or an error. If path is empty, the command runs without -C (use for commands like `clone` that take an explicit destination). Use it to run one-off git commands that don't fit into the other helper functions in this package.
func SetRemote ¶ added in v0.88.0
SetRemote sets the remote named config.RemoteName() for the repository at path to config.Remote. It is a no-op if the remote already has the wanted URL, or if it is not a Rill-managed remote (a user's own remote must never be overwritten).
func SplitGithubRemote ¶ added in v0.88.0
SplitGithubRemote splits a GitHub remote URL into a Github account and repository name.
func UpstreamMerge ¶ added in v0.88.0
UpstreamMerge merges the remote tracking branch `<remoteName>/<branch>` into the current branch. If favourLocal is true, merge conflicts are resolved in favour of local changes.
Types ¶
type ChangedFile ¶ added in v0.88.0
type ChangedFile struct {
Path string
// OldPath is the previous path; only set when Status is ChangedFileStatusRenamed.
OldPath string
Status ChangedFileStatus
}
ChangedFile is a single file that differs from a comparison ref.
func ChangedFiles ¶ added in v0.88.0
func ChangedFiles(ctx context.Context, path, subpath, remoteName, remoteBranch string) ([]ChangedFile, error)
ChangedFiles returns the files that differ between the working tree at path and the comparison ref, i.e. the changes that would land on the ref if merged.
The diff is computed from the merge base of HEAD and the remote ref, not directly against the remote ref. This ensures that commits on the remote that have not been pulled locally do not appear as spurious inverse changes in the result.
Paths are returned relative to subpath (with the subpath prefix stripped). Uncommitted and untracked changes are included, since those are committed before a merge. Renames are reported with status Renamed and the old path, but only when git can detect them (a committed or staged rename); a rename that is still uncommitted in the working tree appears as a deleted old path plus an added new path, because git cannot pair an untracked new file with a deleted old one.
type ChangedFileStatus ¶ added in v0.88.0
type ChangedFileStatus int
ChangedFileStatus describes how a file changed relative to a comparison ref.
const ( ChangedFileStatusUnspecified ChangedFileStatus = iota ChangedFileStatusAdded ChangedFileStatusModified ChangedFileStatusDeleted ChangedFileStatusRenamed )
type Config ¶ added in v0.88.0
type Config struct {
Remote string
Username string
Password string
PasswordExpiresAt time.Time
DefaultBranch string
Subpath string
ManagedRepo bool
}
Config describes a git remote and the (usually ephemeral) credentials to access it.
func (*Config) FullyQualifiedRemote ¶ added in v0.88.0
FullyQualifiedRemote returns the remote URL with the credentials embedded in it. The result may be passed to git commands as an argument but must never be persisted to .git/config.
func (*Config) RemoteName ¶ added in v0.88.0
type GitStatus ¶ added in v0.88.0
type GitStatus struct {
Branch string
RemoteURL string
LocalChanges bool // true if there are local changes (staged, unstaged, or untracked)
LocalCommits int32
RemoteCommits int32
}
func Status ¶ added in v0.88.0
Status returns the status of the git repo at path. If subpath is non-empty, local changes and ahead/behind counts are scoped to it. If remoteBranch is non-empty, ahead/behind counts compare the local branch against `<remoteName>/<remoteBranch>` instead of `<remoteName>/<localBranch>`.
type Remote ¶ added in v0.88.0
Remote represents a Git remote with its name and URL.
func ExtractGitRemote ¶ added in v0.88.0
ExtractGitRemote extracts the first Git remote from the Git repository at projectPath. If remoteName is provided, it will return the remote with that name. If detectDotGit is true, it will look for a .git directory in parent directories.
func ExtractRemotes ¶ added in v0.88.0
ExtractRemotes extracts all Git remotes from the Git repository at projectPath. If detectDotGit is true, it will look for a .git directory in parent directories.
type Signature ¶ added in v0.88.0
Signature identifies the author of a git commit.
func UserSignature ¶ added in v0.88.0
UserSignature returns the git author configured for the repository at path, resolved from the combined local, global, and system git config. Returns an error if user.name or user.email is not configured.