aboutsummaryrefslogtreecommitdiffstats
path: root/plumbing/format/packfile
diff options
context:
space:
mode:
authorZauberNerd <zaubernerd@zaubernerd.de>2022-03-15 17:02:30 +0000
committerZauberNerd <zaubernerd@zaubernerd.de>2023-03-23 19:49:00 +0100
commitcdd1e5562d10c6bb19f979ca32f3ae7ef646024f (patch)
treebf1afc93f0245323589c5f8715718533c794b5b1 /plumbing/format/packfile
parent3f1cfde283c93f33218c807602e93d47f72f7b90 (diff)
downloadgo-git-cdd1e5562d10c6bb19f979ca32f3ae7ef646024f.tar.gz
plumbing: resolve non-external delta references
In a self-contained pack file delta references might point to base objects stored later in the file. In this case we need to replace placeholders for external refs with the actual base object and update the children references. Fixes: #484 Co-authored-by: Markus Wolf <mail@markus-wolf.de>
Diffstat (limited to 'plumbing/format/packfile')
-rw-r--r--plumbing/format/packfile/parser.go9
-rw-r--r--plumbing/format/packfile/parser_test.go13
2 files changed, 22 insertions, 0 deletions
diff --git a/plumbing/format/packfile/parser.go b/plumbing/format/packfile/parser.go
index 522c146..6012b04 100644
--- a/plumbing/format/packfile/parser.go
+++ b/plumbing/format/packfile/parser.go
@@ -237,6 +237,15 @@ func (p *Parser) indexObjects() error {
return err
}
+ // Move children of placeholder parent into actual parent, in case this
+ // was a non-external delta reference.
+ if placeholder, ok := p.oiByHash[sha1]; ok {
+ ota.Children = placeholder.Children
+ for _, c := range ota.Children {
+ c.Parent = ota
+ }
+ }
+
ota.SHA1 = sha1
p.oiByHash[ota.SHA1] = ota
}
diff --git a/plumbing/format/packfile/parser_test.go b/plumbing/format/packfile/parser_test.go
index 651d05f..b8d080f 100644
--- a/plumbing/format/packfile/parser_test.go
+++ b/plumbing/format/packfile/parser_test.go
@@ -147,6 +147,19 @@ func (s *ParserSuite) TestResolveExternalRefsInThinPack(c *C) {
c.Assert(err, IsNil)
}
+func (s *ParserSuite) TestResolveExternalRefs(c *C) {
+ extRefsThinPack := fixtures.ByTag("delta-before-base").One()
+
+ scanner := packfile.NewScanner(extRefsThinPack.Packfile())
+
+ obs := new(testObserver)
+ parser, err := packfile.NewParser(scanner, obs)
+ c.Assert(err, IsNil)
+
+ _, err = parser.Parse()
+ c.Assert(err, IsNil)
+}
+
type observerObject struct {
hash string
otype plumbing.ObjectType