Merge pull request #6 from entireio/soph/branch-optimizations · Entire
Merge pull request #6 from entireio/soph/branch-optimizations
4f5fcb1→main·Soph·2mo ago·9 files·+537 added/-61 removed
Trunk-aware batched bootstrap planning
Changes
9
internal
gitproto
Mfetch.go+13/-4
Mfetch_test.go+33/-7
Mrefs.go+53/-13
Mrefs_test.go+24
planner
Mcheckpoint.go+20/-1
Mplanner_test.go+73
strategy/bootstrap
Mbootstrap.go+177/-31
Mbootstrap_test.go+142/-4
syncer
Msyncer.go+2/-1
// FetchCommitGraph fetches only the commit graph (tree:0 filter) for a ref.
// Requires v2 with filter support.
// Requires v2 with filter support. Optional haves let the source skip commits
// already reachable from those hashes, which is valuable when planning later
// branches that share history with an already-planned trunk.
func (s *RefService) FetchCommitGraph(
ctx context.Context,
store storer.Storer,
conn *Conn,
ref DesiredRef,
haves []plumbing.Hash,
) error {
if s.Protocol != "v2" {
return errors.New("commit graph fetch requires protocol v2")
}
cmdArgs := []string{
sortedHaves := SortedUniqueHashes(haves)
cmdArgs := make([]string, 0, 4+len(sortedHaves))
cmdArgs = append(cmdArgs,
"ofs-delta",
"no-progress",
"filter tree:0",
"want " + ref.SourceHash.String(),
"done",
"want " + ref.SourceHash.String(),
)
for _, h := range sortedHaves {
cmdArgs = append(cmdArgs, "have " + h.String())
}
cmdArgs = append(cmdArgs, "done")
body, err := EncodeCommand("fetch", s.V2Caps.RequestCapabilities(), cmdArgs)
if err != nil {
return err
}
- Minternal/gitproto/fetch.go+13/-4
// headTargetFromAdv extracts the branch HEAD points to from v1 advertised
// capabilities. Returns empty when HEAD is detached or when the source
// does not advertise symref information.
func headTargetFromAdv(adv *packp.AdvRefs) plumbing.ReferenceName {
if adv == nil || adv.Capabilities == nil {
return ""
}
for _, value := range adv.Capabilities.Get(capability.SymRef) {
parts := strings.SplitN(value, ":", 2)
if len(parts) != 2 {
continue
}
if plumbing.ReferenceName(parts[0]) == plumbing.HEAD {
return plumbing.ReferenceName(parts[1])
}
}
return ""
}
- Minternal/gitproto/fetch_test.go+33/-7
// The PACK header pre-check and target-rejection retry catch remaining error.
const estimatedBytesPerCommit = 65536
func planCheckpointsFromChain(ctx context.Context, p Params, ref planner.DesiredRef) ([]plumbing.Hash, []plumbing.Hash, error) {
p.log("bootstrap batch fetching commit graph", "branch", ref.TargetRef.String())
...
}
- Minternal/strategy/bootstrap/bootstrap.go+177/-31
func TestOrderTrunkFirstPutsHEADBranchFirst(t *testing.T) {
mainRef := plumbing.NewBranchReferenceName("main")
featureRef := plumbing.NewBranchReferenceName("feature")
desired := []planner.DesiredRef{
{SourceRef: featureRef, TargetRef: featureRef, Label: "feature"},
{SourceRef: mainRef, TargetRef: mainRef, Label: "main"},
}
ordered, trunkIdx := orderTrunkFirst(desired, mainRef)
if trunkIdx != 0 {
t.Fatalf("trunkIdx = %d, want 0", trunkIdx)
}
}
- Final tests and error handling omitted for brevity.