repograph

package
v0.0.0-...-fd7f308 Latest Latest
Warning

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

Go to latest
Published: Apr 19, 2024 License: BSD-3-Clause Imports: 19 Imported by: 17

Documentation

Index

Constants

View Source
const (
	// Name of the file we store inside the Git checkout to speed up the
	// initial Update().
	CACHE_FILE = "sk_gitrepo.gob"
)

Variables

View Source
var (
	ErrStopRecursing = errors.New("Stop recursing")
)

Functions

This section is empty.

Types

type Commit

type Commit struct {
	*vcsinfo.LongCommit
	// contains filtered or unexported fields
}

Commit represents a commit in a Git repo.

func TopologicalSort

func TopologicalSort(commits []*Commit) []*Commit

TopologicalSort returns a slice containing the given commits in reverse topological order, ie. every commit is listed before any of its parents.

func (*Commit) AddParent

func (c *Commit) AddParent(p *Commit)

AddParent adds the given commit to the list of parents.

func (*Commit) AllCommits

func (c *Commit) AllCommits() ([]string, error)

AllCommits returns the hashes of all commits reachable from this Commit, in reverse topological order.

func (*Commit) GetParents

func (c *Commit) GetParents() []*Commit

GetParents returns the parents of this commit.

func (*Commit) HasAncestor

func (c *Commit) HasAncestor(other string) bool

HasAncestor returns true iff the given commit is an ancestor of this commit.

func (*Commit) Less

func (c *Commit) Less(other *Commit) bool

Less compares this Commit to the other Commit and returns true if it is considered "less" than the other. This is used as a helper function in sorting to ensure stability. Uses the timestamp as the primary sort function and the hash as a tie breaker. Note that, because we sort in reverse chronological order, this has the opposite meaning that it seems it should.

func (*Commit) Recurse

func (c *Commit) Recurse(f func(*Commit) error) error

Recurse runs the given function recursively over commit history, starting at the given commit. The function accepts the current Commit as a parameter. Returning ErrStopRecursing from the function indicates that recursion should stop for the current branch, however, recursion will continue for any other branches until they are similarly terminated. Returning any other error causes recursion to stop without properly terminating other branches. The error will bubble to the top and be returned. Here's an example of printing out the entire ancestry of a given commit:

commit.Recurse(func(c *Commit) error {
	sklog.Info(c.Hash)
	return nil
})

If the passed-in function returns no errors other than ErrStopRecursing, Recurse() will never return an error.

func (*Commit) RecurseFirstParent

func (c *Commit) RecurseFirstParent(f func(*Commit) error) error

RecurseFirstParent is like Recurse, but it only follows the first parent of each commit. Like Recurse, if the passed-in function returns no errors other than ErrStopRecursing, RecurseFirstParent() will never return an error.

type CommitSlice

type CommitSlice []*Commit

Helpers for sorting.

func (CommitSlice) Hashes

func (s CommitSlice) Hashes() []string

Hashes returns a slice of commit hashes corresponding to the commits in s.

func (CommitSlice) Len

func (s CommitSlice) Len() int

func (CommitSlice) Less

func (s CommitSlice) Less(a, b int) bool

func (CommitSlice) Swap

func (s CommitSlice) Swap(a, b int)

type Graph

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

Graph represents an entire Git repo.

func NewFromGob

func NewFromGob(ctx context.Context, r io.Reader, ri RepoImpl) (*Graph, error)

NewFromGob reads a Graph from the given Reader in gob format.

func NewLocalGraph

func NewLocalGraph(ctx context.Context, repoUrl, workdir string) (*Graph, error)

NewLocalGraph returns a Graph instance, creating a git.Repo from the repoUrl and workdir. May obtain cached data from a file in the git repo, but does NOT update the Graph; the caller is responsible for doing so before using the Graph if up-to-date data is required.

func NewWithRepoImpl

func NewWithRepoImpl(ctx context.Context, ri RepoImpl) (*Graph, error)

NewWithRepoImpl returns a Graph instance which uses the given RepoImpl. The RepoImpl should be initialized (via Update() or otherwise) before being passed to NewWithRepoImpl.

func (*Graph) BranchHeads

func (r *Graph) BranchHeads() []*git.Branch

BranchHeads returns the set of branch heads from the repo.

func (*Graph) Branches

func (r *Graph) Branches() []string

Branches returns the list of known branches in the repo.

func (*Graph) Get

func (r *Graph) Get(ref string) *Commit

Get returns a Commit object for the given ref, if such a commit exists. This function does not understand complex ref types (eg. HEAD~3); only branch names and full commit hashes are accepted.

func (*Graph) GetAll

func (r *Graph) GetAll() map[string]*Commit

GetAll returns a map containing all of the stored Commit objects keyed by commit hash.

func (*Graph) GetCommitsNewerThan

func (r *Graph) GetCommitsNewerThan(ts time.Time) ([]*vcsinfo.LongCommit, error)

Return any commits at or after the given timestamp.

func (*Graph) GetLastNCommits

func (r *Graph) GetLastNCommits(n int) ([]*vcsinfo.LongCommit, error)

GetLastNCommits returns the last N commits in the repo.

func (*Graph) IsAncestor

func (r *Graph) IsAncestor(a, b string) (bool, error)

IsAncestor returns true iff A is an ancestor of B, where A and B are either commit hashes or branch names.

func (*Graph) Len

func (r *Graph) Len() int

Len returns the number of commits in the repo.

func (*Graph) LogLinear

func (r *Graph) LogLinear(from, to string) ([]*Commit, error)

LogLinear is equivalent to "git log --first-parent --ancestry-path from..to", ie. it only returns commits which are on the direct path from A to B, and only on the "main" branch. This is as opposed to "git log from..to" which returns all commits which are ancestors of 'to' but not 'from'. The 'from' commit may be the empty string, in which case all commits in the first-parent line are returned.

func (*Graph) RecurseAllBranches

func (r *Graph) RecurseAllBranches(f func(*Commit) error) error

RecurseAllBranches runs the given function recursively over the entire commit history, starting at each of the known branch heads. The function accepts the current Commit as a parameter. Returning ErrStopRecursing from the function indicates that recursion should stop for the current branch, however, recursion will continue for any other branches until they are similarly terminated. Returning any other error causes recursion to stop without properly terminating other branches. The error will bubble to the top and be returned. Here's an example of printing out all of the commits in the repo:

repo.RecurseAllBranches(func(c *Commit) error {
     sklog.Info(c.Hash)
     return nil
})

func (*Graph) RecurseCommits

func (r *Graph) RecurseCommits(commits []string, f func(*Commit) error) error

RecurseCommits runs the given function recursively over the given refs, which can be either commit hashes or branch names. The function accepts the current Commit as a parameter. Returning ErrStopRecursing from the function indicates that recursion should stop for the current branch, however, recursion will continue for any other branches until they are similarly terminated. Returning any other error causes recursion to stop without properly terminating other branches. The error will bubble to the top and be returned. Here's an example of printing out all of the commits reachable from a given set of commits:

commits := []string{...}

err := repo.RecurseCommits(commits, func(c *Commit) error {
	sklog.Info(c.Hash)
	return nil
})

func (*Graph) RevList

func (r *Graph) RevList(from, to string) ([]string, error)

RevList is the equivalent of "git rev-list --topo-order from..to". Each argument is a commit hash or a branch name. The commits are returned in reverse topological order. Per "git rev-list" docs, the returned commit hashes consist of all commits reachable from "to" and not reachable from "from". In the typical case of linear git history, this just means the commits on the line after "from" up through "to", but with branches and merges it's possible that there are entire sub-graphs which are reachable from "to" but not "from".

func (*Graph) Update

func (r *Graph) Update(ctx context.Context) error

Update the Graph.

func (*Graph) UpdateAndReturnCommitDiffs

func (r *Graph) UpdateAndReturnCommitDiffs(ctx context.Context) ([]*vcsinfo.LongCommit, []*vcsinfo.LongCommit, error)

UpdateAndReturnCommitDiffs updates the Graph and returns the added and removed commits, in arbitrary order.

func (*Graph) UpdateBranchInfo

func (r *Graph) UpdateBranchInfo() []*vcsinfo.LongCommit

UpdateBranchInfo updates the membership of all commits in all branches. A commit is considered a member of a branch if and only if it is reachable by tracing the *first parent* lineage backward from the branch head. Notably, this will result in different branch membership than would be obtained by `git branch --all --list --contains <hash>` as is used elsewhere. Modifies the Commit objects stored in the graph and returns the LongCommits associated with the modified Commits. Clients MUST NOT modify the Branches on the returned LongCommits; as a space-saving optimization, we use the same map instance for all commits which belong to the same set of branches.

func (*Graph) UpdateWithCallback

func (r *Graph) UpdateWithCallback(ctx context.Context, cb func(*Graph) error) error

UpdateWithCallback updates the Graph and runs the given function before the changes are committed. If the function returns an error, the changes are not committed. The function is allowed to call non-Update methods of the Graph.

func (*Graph) WriteGob

func (r *Graph) WriteGob(w io.Writer) error

WriteGob writes the Graph to the given Writer using gob format.

type Map

type Map map[string]*Graph

Map is a convenience type for dealing with multiple Graphs for different repos. The keys are repository URLs.

func NewLocalMap

func NewLocalMap(ctx context.Context, repos []string, workdir string) (Map, error)

NewLocalMap returns a Map instance with Graphs for the given repo URLs. May obtain cached data from a file in the git repo, but does NOT update the Map; the caller is responsible for doing so before using the Map if up-to-date data is required.

func (Map) FindCommit

func (m Map) FindCommit(commit string) (*Commit, string, *Graph, error)

FindCommit returns the Commit object, repo URL, and Graph object for the given commit hash if it exists in any of the Graphs in the Map and an error otherwise.

func (Map) RepoURLs

func (m Map) RepoURLs() []string

RepoURLs returns the list of repositories in the Map.

func (Map) Update

func (m Map) Update(ctx context.Context) error

Update all Graphs in the Map.

func (Map) UpdateAndReturnCommitDiffs

func (m Map) UpdateAndReturnCommitDiffs(ctx context.Context) (map[string][]*vcsinfo.LongCommit, map[string][]*vcsinfo.LongCommit, error)

UpdateAndReturnCommitDiffs updates all Graphs in the Map. Returns maps of repo URLs to slices of added commits, repo URLs to slices of removed commits, or any error which was encountered. If any Graph failed to update, no changes are committed.

func (Map) UpdateWithCallback

func (m Map) UpdateWithCallback(ctx context.Context, cb func(string, *Graph) error) error

UpdateWithCallback updates the Graphs in the Map and runs the given function on each Graph before the changes are committed. If the function returns an error for any Graph, no changes are committed. The function is allowed to call non-Update methods of the Graph.

type MemCacheRepoImpl

type MemCacheRepoImpl struct {
	Commits    map[string]*vcsinfo.LongCommit
	BranchList []*git.Branch
}

MemCacheRepoImpl is a RepoImpl which just caches commits in memory.

func NewMemCacheRepoImpl

func NewMemCacheRepoImpl(commits map[string]*vcsinfo.LongCommit, branches []*git.Branch) *MemCacheRepoImpl

NewMemCacheRepoImpl returns a RepoImpl implementation which just caches commits in memory. The commits map must contain all commits needed by the given branch heads.

func (*MemCacheRepoImpl) Branches

func (ri *MemCacheRepoImpl) Branches(_ context.Context) ([]*git.Branch, error)

See documentation for RepoImpl interface.

func (*MemCacheRepoImpl) Details

func (ri *MemCacheRepoImpl) Details(_ context.Context, hash string) (*vcsinfo.LongCommit, error)

See documentation for RepoImpl interface.

func (*MemCacheRepoImpl) Update

func (ri *MemCacheRepoImpl) Update(_ context.Context) error

See documentation for RepoImpl interface.

func (*MemCacheRepoImpl) UpdateCallback

func (ri *MemCacheRepoImpl) UpdateCallback(_ context.Context, _, _ []*vcsinfo.LongCommit, _ *Graph) error

See documentation for RepoImpl interface.

type RepoImpl

type RepoImpl interface {
	// Update the local view of the repo.
	Update(context.Context) error

	// Return the details for the given commit. The Graph takes ownership
	// of the returned LongCommit and may modify it.
	Details(context.Context, string) (*vcsinfo.LongCommit, error)

	// Return the branch heads, as of the last call to Update().
	Branches(context.Context) ([]*git.Branch, error)

	// UpdateCallback is a function which is called after the Graph is
	// updated but before the changes are committed. If UpdateCallback
	// returns an error, the changes are not committed. This allows the
	// RepoImpl to perform caching, for example. The parameters are the
	// list of commits which were added during the current Update, the
	// list of commits which were removed, and the new state of the Graph.
	UpdateCallback(context.Context, []*vcsinfo.LongCommit, []*vcsinfo.LongCommit, *Graph) error
}

RepoImpl provides methods for interacting with a git repo, agnostic of how the repo is actually accessed. It is used when updating a Graph. It should not be used concurrently.

func NewLocalRepoImpl

func NewLocalRepoImpl(ctx context.Context, repo *git.Repo) (RepoImpl, error)

NewLocalRepoImpl returns a RepoImpl backed by a local git repo.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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