aboutsummaryrefslogtreecommitdiff
path: root/receivepack/service
diff options
context:
space:
mode:
authorGravatar Runxi Yu2026-03-22 18:00:22 +0000
committerGravatar Runxi Yu2026-03-22 18:02:10 +0000
commit4e43d7207bf91ee759c770de1bcc8562a71b4aca (patch)
tree2abf7592a88d733b2815fc214ba59c3b209d3fa7 /receivepack/service
parentobjectstore{,/packed}: Document lifetime and integrity behavior (diff)
signatureNo signature
objectstore/*, repository, receivepack/service: don't take ownership of root
Diffstat (limited to 'receivepack/service')
-rw-r--r--receivepack/service/quarantine.go5
-rw-r--r--receivepack/service/quarantine_objects.go50
-rw-r--r--receivepack/service/run_hook.go74
3 files changed, 71 insertions, 58 deletions
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)
+
+ return nil, nil, nil, false, err.Error()
+ }
- defer func() {
- _ = quarantinedObjects.Close()
- }()
+ 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,