Today we need to found acestor
when user push a new branch or force push an existing branch. All this code start in ssh.
This method run through all branches and try to find previous commit. It’s huge in terms of compute and not always true.
After investigation go-git permit to add an observer on a packfile deserializer to store all data. This does nothing in term of computing and is every time exact.
In go git:
NewServer
with an optional packfile.Observer in go-git/plumbing/server/server.go
NewReceivePackSession
=> s.handler.NewReceivePackSession(sto, s.ob)
NewReceivePackSession
=> return &rpSession{ob:ob,...}
ReceivePack
=> s.writePackfile(r, s.ob)
writePackfile
=> packfile.UpdateObjectStorage(s.storer, r, ob)
plumbing/format/packfile/common.go
with UpdateObjectStorage
=> p := NewParser(packfile, WithStorage(s), WithScannerObservers(ob))
In gitroot:
1type Observer struct {
2 previousType plumbing.ObjectType
3 logger logger.Logger
4}
5
6func (*Observer) OnHeader(count uint32) error {
7 return nil
8}
9
10// OnInflatedObjectHeader is called for each object header read.
11func (o *Observer) OnInflatedObjectHeader(t plumbing.ObjectType, objSize int64, pos int64) error {
12 o.previousType = t
13 if o.previousType == plumbing.CommitObject {
14 o.logger.Warn("header", logger.NewLoggerPair("type", t.String()), logger.NewLoggerPair("pos", pos))
15 }
16 return nil
17}
18
19// OnInflatedObjectContent is called for each decoded object.
20func (o *Observer) OnInflatedObjectContent(h plumbing.Hash, pos int64, crc uint32, content []byte) error {
21 if o.previousType == plumbing.CommitObject {
22 o.logger.Warn("new hash", logger.NewLoggerPair("hash", h.String()), logger.NewLoggerPair("pos", pos))
23 }
24 return nil
25}
26
27// OnFooter is called when decoding is done.
28func (o *Observer) OnFooter(h plumbing.Hash) error {
29 return nil
30}
then use it in ssh handleReceivePack
with:
1o := &Observer{logger: session.logger}
2svr := server.NewServer(ld, o)
I have played with it and it seams to give commits sorted from top to bottom.
Be carreful with multiple branch push because we don’t know what commit is related to what branch.