From efe3045aaf9fdaa726776d911c6c2fa109c90af9 Mon Sep 17 00:00:00 2001 From: Runxi Yu Date: Sat, 28 Mar 2026 17:52:42 +0000 Subject: repository: Add commit-graph --- repository/close.go | 7 +++++++ repository/commit_graph.go | 37 +++++++++++++++++++++++++++++++++++++ repository/open.go | 7 +++++++ repository/repository.go | 8 +++++--- 4 files changed, 56 insertions(+), 3 deletions(-) create mode 100644 repository/commit_graph.go diff --git a/repository/close.go b/repository/close.go index fa6f8f85..5d728c5b 100644 --- a/repository/close.go +++ b/repository/close.go @@ -22,6 +22,13 @@ func (repo *Repository) Close() error { } } + if repo.commitGraph != nil { + err := repo.commitGraph.Close() + if err != nil { + errs = append(errs, err) + } + } + if repo.objectsPacked != nil { err := repo.objectsPacked.Close() if err != nil { diff --git a/repository/commit_graph.go b/repository/commit_graph.go new file mode 100644 index 00000000..b45d9da0 --- /dev/null +++ b/repository/commit_graph.go @@ -0,0 +1,37 @@ +package repository + +import ( + "errors" + "os" + + commitgraphread "codeberg.org/lindenii/furgit/format/commitgraph/read" + objectid "codeberg.org/lindenii/furgit/object/id" +) + +func openCommitGraph(root *os.Root, algo objectid.Algorithm) (*commitgraphread.Reader, error) { + reader, err := commitgraphread.Open(root, algo, commitgraphread.OpenChain) + if err == nil { + return reader, nil + } + + var malformed *commitgraphread.MalformedError + if errors.As(err, &malformed) && + malformed.Path == "info/commit-graphs/commit-graph-chain" && + malformed.Reason == "missing commit-graph-chain" { + reader, err = commitgraphread.Open(root, algo, commitgraphread.OpenSingle) + if errors.Is(err, os.ErrNotExist) { + return nil, nil + } + + return reader, err + } + + return nil, err +} + +// CommitGraph returns the configured commit-graph reader, if available. +// +// Labels: Life-Parent, Close-No. +func (repo *Repository) CommitGraph() *commitgraphread.Reader { + return repo.commitGraph +} diff --git a/repository/open.go b/repository/open.go index 0e47ba83..f4dd78f8 100644 --- a/repository/open.go +++ b/repository/open.go @@ -44,6 +44,13 @@ func Open(root *os.Root) (repo *Repository, err error) { repo.objectsLoose = objectsLoose repo.objectsPacked = objectsPacked + commitGraph, err := openCommitGraph(objectsRoot, algo) + if err != nil { + return nil, err + } + + repo.commitGraph = commitGraph + refRoot, err := root.OpenRoot(".") if err != nil { return nil, fmt.Errorf("repository: open root for refs: %w", err) diff --git a/repository/repository.go b/repository/repository.go index 8c7c091f..b60e0023 100644 --- a/repository/repository.go +++ b/repository/repository.go @@ -5,6 +5,7 @@ import ( "os" "codeberg.org/lindenii/furgit/config" + commitgraphread "codeberg.org/lindenii/furgit/format/commitgraph/read" objectid "codeberg.org/lindenii/furgit/object/id" objectstore "codeberg.org/lindenii/furgit/object/store" objectloose "codeberg.org/lindenii/furgit/object/store/loose" @@ -18,9 +19,9 @@ import ( // Open expects a root for the Git directory itself: // a bare repository root or a non-bare ".git" directory. // -// Accessors such as [Repository.Objects], [Repository.Refs], -// [Repository.Fetcher], and [Repository.LooseStoreForWriting] return -// repository-backed views. +// Accessors such as [Repository.Objects], [Repository.CommitGraph], +// [Repository.Refs], [Repository.Fetcher], and +// [Repository.LooseStoreForWriting] return repository-backed views. // // Labels: MT-Safe, Close-Caller. type Repository struct { @@ -32,6 +33,7 @@ type Repository struct { objectsPackRoot *os.Root objectsLoose *objectloose.Store objectsPacked *objectpacked.Store + commitGraph *commitgraphread.Reader refRoot *os.Root refs refstore.ReadWriteStore } -- cgit v1.3.1-10-gc9f91