From 4e43d7207bf91ee759c770de1bcc8562a71b4aca Mon Sep 17 00:00:00 2001 From: Runxi Yu Date: Sun, 22 Mar 2026 18:00:22 +0000 Subject: objectstore/*, repository, receivepack/service: don't take ownership of root --- receivepack/service/quarantine.go | 5 +++ receivepack/service/quarantine_objects.go | 50 --------------------- receivepack/service/run_hook.go | 74 +++++++++++++++++++++++++++---- 3 files changed, 71 insertions(+), 58 deletions(-) delete mode 100644 receivepack/service/quarantine_objects.go (limited to 'receivepack') diff --git a/receivepack/service/quarantine.go b/receivepack/service/quarantine.go index 97a85959..0bd98aeb 100644 --- a/receivepack/service/quarantine.go +++ b/receivepack/service/quarantine.go @@ -14,6 +14,11 @@ import ( // createQuarantineRoot creates one per-push quarantine directory beneath the // permanent objects root. +// +// It returns both the quarantine directory name relative to ObjectsRoot and an +// opened root for that directory. Callers use the name for later promotion or +// removal relative to ObjectsRoot, and use the opened root for capability-based +// access within the quarantine itself. func (service *Service) createQuarantineRoot() (string, *os.Root, error) { name := "tmp_objdir-incoming-" + rand.Text() diff --git a/receivepack/service/quarantine_objects.go b/receivepack/service/quarantine_objects.go deleted file mode 100644 index 0b267531..00000000 --- a/receivepack/service/quarantine_objects.go +++ /dev/null @@ -1,50 +0,0 @@ -package service - -import ( - "os" - - "codeberg.org/lindenii/furgit/objectstore" - "codeberg.org/lindenii/furgit/objectstore/loose" - "codeberg.org/lindenii/furgit/objectstore/memory" - objectmix "codeberg.org/lindenii/furgit/objectstore/mix" - "codeberg.org/lindenii/furgit/objectstore/packed" -) - -func (service *Service) openQuarantinedObjects(quarantineName string) (objectstore.Store, error) { - if quarantineName == "" { - return memory.New(service.opts.Algorithm), nil - } - - looseRoot, err := service.opts.ObjectsRoot.OpenRoot(quarantineName) - if err != nil { - return nil, err - } - - looseStore, err := loose.New(looseRoot, service.opts.Algorithm) - if err != nil { - _ = looseRoot.Close() - - return nil, err - } - - packRoot, err := looseRoot.OpenRoot("pack") - if err == nil { - packedStore, packedErr := packed.New(packRoot, service.opts.Algorithm, packed.Options{}) - if packedErr != nil { - _ = packRoot.Close() - _ = looseStore.Close() - - return nil, packedErr - } - - return objectmix.New(looseStore, packedStore), nil - } - - if !os.IsNotExist(err) { - _ = looseStore.Close() - - return nil, err - } - - return looseStore, nil -} diff --git a/receivepack/service/run_hook.go b/receivepack/service/run_hook.go index 1270a833..bdf7ec8b 100644 --- a/receivepack/service/run_hook.go +++ b/receivepack/service/run_hook.go @@ -2,8 +2,13 @@ package service import ( "context" + "os" "codeberg.org/lindenii/furgit/internal/utils" + "codeberg.org/lindenii/furgit/objectstore" + "codeberg.org/lindenii/furgit/objectstore/loose" + objectmix "codeberg.org/lindenii/furgit/objectstore/mix" + "codeberg.org/lindenii/furgit/objectstore/packed" ) func (service *Service) runHook( @@ -32,16 +37,69 @@ func (service *Service) runHook( utils.BestEffortFprintf(service.opts.Progress, "running hooks...\r") - quarantinedObjects, err := service.openQuarantinedObjects(quarantineName) - if err != nil { - utils.BestEffortFprintf(service.opts.Progress, "running hooks: failed: %v.\n", err) + quarantinedObjects := service.opts.ExistingObjects + var ( + quarantineObjectsStore objectstore.Store + quarantineLooseRoot *os.Root + quarantinePackRoot *os.Root + err error + ) - return nil, nil, nil, false, err.Error() - } + if quarantineName != "" { + quarantineLooseRoot, err = service.opts.ObjectsRoot.OpenRoot(quarantineName) + if err != nil { + utils.BestEffortFprintf(service.opts.Progress, "running hooks: failed: %v.\n", err) + + return nil, nil, nil, false, err.Error() + } + + quarantineLooseStore, err := loose.New(quarantineLooseRoot, service.opts.Algorithm) + if err != nil { + _ = quarantineLooseRoot.Close() + utils.BestEffortFprintf(service.opts.Progress, "running hooks: failed: %v.\n", err) - defer func() { - _ = quarantinedObjects.Close() - }() + return nil, nil, nil, false, err.Error() + } + + quarantineObjectsStore = quarantineLooseStore + quarantinedObjects = quarantineLooseStore + + quarantinePackRoot, err = quarantineLooseRoot.OpenRoot("pack") + if err == nil { + quarantinePackedStore, packedErr := packed.New(quarantinePackRoot, service.opts.Algorithm, packed.Options{}) + if packedErr != nil { + _ = quarantineLooseStore.Close() + _ = quarantinePackRoot.Close() + _ = quarantineLooseRoot.Close() + utils.BestEffortFprintf(service.opts.Progress, "running hooks: failed: %v.\n", packedErr) + + return nil, nil, nil, false, packedErr.Error() + } + + quarantineObjectsStore = objectmix.New(quarantineLooseStore, quarantinePackedStore) + quarantinedObjects = quarantineObjectsStore + } else if !os.IsNotExist(err) { + _ = quarantineLooseStore.Close() + _ = quarantineLooseRoot.Close() + utils.BestEffortFprintf(service.opts.Progress, "running hooks: failed: %v.\n", err) + + return nil, nil, nil, false, err.Error() + } + + defer func() { + if quarantineObjectsStore != nil { + _ = quarantineObjectsStore.Close() + } + + if quarantinePackRoot != nil { + _ = quarantinePackRoot.Close() + } + + if quarantineLooseRoot != nil { + _ = quarantineLooseRoot.Close() + } + }() + } decisions, err := service.opts.Hook(ctx, HookRequest{ Refs: service.opts.Refs, -- cgit v1.3.1-10-gc9f91