GitRoot

craft your forge, build your project, grow your community freely
sprint
""
assignee
null
status
triage
kind
issue
id
"4f8d"
priority
75

Found ancestor rework

Today we need to found acestor when user push a new branch or force push an existing branch. All this code start in ssh.

Problem

This method run through all branches and try to find previous commit. It’s huge in terms of compute and not always true.

Solution

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.

What to do?

In go git:

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)

Remarks

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.