mirror of
https://github.com/sourcegraph/sourcegraph.git
synced 2026-02-06 16:51:55 +00:00
gitserver: Add OctopusMergeBase RPC method (#63842)
This method can be used to find a common ancestor for many commit SHAs, to be used by code intel for finding visible uploads. Closes SRC-485 Test plan: Added unit tests for the several layers (client, grpc, gitcli).
This commit is contained in:
parent
36d785dc4a
commit
175667db7c
@ -27,7 +27,7 @@ var (
|
||||
"ls-files": {"--with-tree", "-z"},
|
||||
"for-each-ref": {"--format", "--points-at", "--contains", "--sort", "-creatordate", "-refname", "-HEAD"},
|
||||
"tag": {"--list", "--sort", "-creatordate", "--format", "--points-at"},
|
||||
"merge-base": {"--"},
|
||||
"merge-base": {"--octopus", "--"},
|
||||
"show-ref": {"--heads"},
|
||||
"shortlog": {"--summary", "--numbered", "--email", "--no-merges", "--after", "--before"},
|
||||
"cat-file": {"-p", "-t"},
|
||||
|
||||
@ -7,6 +7,7 @@ import (
|
||||
|
||||
"github.com/sourcegraph/sourcegraph/internal/api"
|
||||
"github.com/sourcegraph/sourcegraph/internal/gitserver/gitdomain"
|
||||
"github.com/sourcegraph/sourcegraph/internal/lazyregexp"
|
||||
"github.com/sourcegraph/sourcegraph/lib/errors"
|
||||
)
|
||||
|
||||
@ -47,3 +48,52 @@ func (g *gitCLIBackend) MergeBase(ctx context.Context, baseRevspec, headRevspec
|
||||
|
||||
return api.CommitID(bytes.TrimSpace(stdout)), nil
|
||||
}
|
||||
|
||||
func (g *gitCLIBackend) MergeBaseOctopus(ctx context.Context, revspecs ...string) (api.CommitID, error) {
|
||||
if len(revspecs) < 2 {
|
||||
return "", errors.New("at least two revspecs must be given")
|
||||
}
|
||||
|
||||
args := make([]string, 0, len(revspecs)+3)
|
||||
args = append(args, "merge-base", "--octopus", "--")
|
||||
args = append(args, revspecs...)
|
||||
|
||||
out, err := g.NewCommand(
|
||||
ctx,
|
||||
WithArguments(args...),
|
||||
)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
defer out.Close()
|
||||
|
||||
stdout, err := io.ReadAll(out)
|
||||
if err != nil {
|
||||
// Exit code 1 and empty output most likely means that no common merge-base was found.
|
||||
var e *commandFailedError
|
||||
if errors.As(err, &e) {
|
||||
if e.ExitStatus == 1 {
|
||||
if len(e.Stderr) == 0 {
|
||||
return "", nil
|
||||
}
|
||||
} else if e.ExitStatus == 128 && bytes.Contains(e.Stderr, []byte("fatal: Not a valid object name")) {
|
||||
p := octopusNotAValidObjectRegexp.FindSubmatch(e.Stderr)
|
||||
var spec string
|
||||
if len(p) > 0 {
|
||||
spec = string(p[1])
|
||||
}
|
||||
return "", &gitdomain.RevisionNotFoundError{
|
||||
Repo: g.repoName,
|
||||
Spec: spec,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return "", err
|
||||
}
|
||||
|
||||
return api.CommitID(bytes.TrimSpace(stdout)), nil
|
||||
}
|
||||
|
||||
var octopusNotAValidObjectRegexp = lazyregexp.New(`fatal: Not a valid object name ([^\s]+)`)
|
||||
|
||||
@ -74,3 +74,99 @@ func TestGitCLIBackend_MergeBase(t *testing.T) {
|
||||
require.True(t, errors.HasType[*gitdomain.RevisionNotFoundError](err))
|
||||
})
|
||||
}
|
||||
|
||||
func TestGitCLIBackend_MergeBaseOctopus(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
|
||||
t.Run("resolves", func(t *testing.T) {
|
||||
// Prepare repo state:
|
||||
// Structure:
|
||||
// 1 - 5 master
|
||||
// \ - 2 b2
|
||||
// \ - 3 - 4 b3
|
||||
// Expected merge base of {master, b2, b3}: 1 (aka testbase)
|
||||
backend := BackendWithRepoCommands(t,
|
||||
"echo line1 > f",
|
||||
"git add f",
|
||||
"git commit -m foo --author='Foo Author <foo@sourcegraph.com>'",
|
||||
"git tag testbase",
|
||||
|
||||
"git checkout -b b2",
|
||||
"echo line2 >> f",
|
||||
"git add f",
|
||||
"git commit -m foo --author='Foo Author <foo@sourcegraph.com>'",
|
||||
"git checkout master",
|
||||
|
||||
"git checkout -b b3",
|
||||
"echo line3 >> f",
|
||||
"git add f",
|
||||
"git commit -m foo --author='Foo Author <foo@sourcegraph.com>'",
|
||||
"echo line4 >> f",
|
||||
"git add f",
|
||||
"git commit -m foo --author='Foo Author <foo@sourcegraph.com>'",
|
||||
|
||||
"git checkout master",
|
||||
"echo line2 > f",
|
||||
"git add f",
|
||||
"git commit -m foo --author='Foo Author <foo@sourcegraph.com>'",
|
||||
)
|
||||
|
||||
wantSHA, err := backend.ResolveRevision(ctx, "testbase")
|
||||
require.NoError(t, err)
|
||||
require.NotEmpty(t, wantSHA)
|
||||
|
||||
base, err := backend.MergeBaseOctopus(ctx, "master", "b2", "b3")
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, wantSHA, base)
|
||||
})
|
||||
t.Run("orphan branches", func(t *testing.T) {
|
||||
// Prepare repo state:
|
||||
backend := BackendWithRepoCommands(t,
|
||||
"echo line1 > f",
|
||||
"git add f",
|
||||
"git commit -m foo --author='Foo Author <foo@sourcegraph.com>'",
|
||||
"git checkout --orphan b2",
|
||||
"echo line2 >> f",
|
||||
"git add f",
|
||||
"git commit -m foo --author='Foo Author <foo@sourcegraph.com>'",
|
||||
"git checkout master",
|
||||
"git checkout --orphan b3",
|
||||
"echo line3 >> f",
|
||||
"git add f",
|
||||
"git commit -m foo --author='Foo Author <foo@sourcegraph.com>'",
|
||||
"git checkout master",
|
||||
)
|
||||
|
||||
base, err := backend.MergeBaseOctopus(ctx, "master", "b2", "b3")
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, api.CommitID(""), base)
|
||||
})
|
||||
t.Run("not found revspec", func(t *testing.T) {
|
||||
// Prepare repo state:
|
||||
backend := BackendWithRepoCommands(t,
|
||||
"echo line1 > f",
|
||||
"git add f",
|
||||
"git commit -m foo --author='Foo Author <foo@sourcegraph.com>'",
|
||||
)
|
||||
|
||||
// Last revspec not found
|
||||
_, err := backend.MergeBaseOctopus(ctx, "master", "notfound")
|
||||
require.Error(t, err)
|
||||
require.True(t, errors.HasType[*gitdomain.RevisionNotFoundError](err))
|
||||
require.Equal(t, "notfound", err.(*gitdomain.RevisionNotFoundError).Spec)
|
||||
|
||||
// First revspec not found
|
||||
_, err = backend.MergeBaseOctopus(ctx, "notfound", "master")
|
||||
require.Error(t, err)
|
||||
require.True(t, errors.HasType[*gitdomain.RevisionNotFoundError](err))
|
||||
require.Equal(t, "notfound", err.(*gitdomain.RevisionNotFoundError).Spec)
|
||||
})
|
||||
t.Run("less than two revspecs", func(t *testing.T) {
|
||||
// Prepare repo state:
|
||||
backend := BackendWithRepoCommands(t)
|
||||
|
||||
_, err := backend.MergeBaseOctopus(ctx, "master")
|
||||
require.Error(t, err)
|
||||
require.ErrorContains(t, err, "at least two revspecs must be given")
|
||||
})
|
||||
}
|
||||
|
||||
@ -162,6 +162,25 @@ type GitBackend interface {
|
||||
// This value can be used to determine if a repository changed since the last
|
||||
// time the hash has been computed.
|
||||
RefHash(ctx context.Context) ([]byte, error)
|
||||
|
||||
// MergeBaseOctopus returns the octopus merge base commit sha for the specified
|
||||
// revspecs.
|
||||
// If no common merge base exists, an empty string is returned.
|
||||
// See the following diagrams from git-merge-base docs on what octopus merge bases
|
||||
// are:
|
||||
// Given three commits A, B, and C, MergeBaseOctopus(A, B, C) will compute the
|
||||
// best common ancestor of all commits.
|
||||
// For example, with this topology:
|
||||
// o---o---o---o---C
|
||||
// /
|
||||
// / o---o---o---B
|
||||
// / /
|
||||
// ---2---1---o---o---o---A
|
||||
// The result of MergeBaseOctopus(A, B, C) is 2, because 2 is the
|
||||
// best common ancestor of all commits.
|
||||
//
|
||||
// If one of the given revspecs does not exist, a RevisionNotFoundError is returned.
|
||||
MergeBaseOctopus(ctx context.Context, revspecs ...string) (api.CommitID, error)
|
||||
}
|
||||
|
||||
// CommitLogOrder is the order of the commits returned by CommitLog.
|
||||
|
||||
@ -588,6 +588,9 @@ type MockGitBackend struct {
|
||||
// MergeBaseFunc is an instance of a mock function object controlling
|
||||
// the behavior of the method MergeBase.
|
||||
MergeBaseFunc *GitBackendMergeBaseFunc
|
||||
// MergeBaseOctopusFunc is an instance of a mock function object
|
||||
// controlling the behavior of the method MergeBaseOctopus.
|
||||
MergeBaseOctopusFunc *GitBackendMergeBaseOctopusFunc
|
||||
// RawDiffFunc is an instance of a mock function object controlling the
|
||||
// behavior of the method RawDiff.
|
||||
RawDiffFunc *GitBackendRawDiffFunc
|
||||
@ -686,6 +689,11 @@ func NewMockGitBackend() *MockGitBackend {
|
||||
return
|
||||
},
|
||||
},
|
||||
MergeBaseOctopusFunc: &GitBackendMergeBaseOctopusFunc{
|
||||
defaultHook: func(context.Context, ...string) (r0 api.CommitID, r1 error) {
|
||||
return
|
||||
},
|
||||
},
|
||||
RawDiffFunc: &GitBackendRawDiffFunc{
|
||||
defaultHook: func(context.Context, string, string, GitDiffComparisonType, RawDiffOpts, ...string) (r0 io.ReadCloser, r1 error) {
|
||||
return
|
||||
@ -803,6 +811,11 @@ func NewStrictMockGitBackend() *MockGitBackend {
|
||||
panic("unexpected invocation of MockGitBackend.MergeBase")
|
||||
},
|
||||
},
|
||||
MergeBaseOctopusFunc: &GitBackendMergeBaseOctopusFunc{
|
||||
defaultHook: func(context.Context, ...string) (api.CommitID, error) {
|
||||
panic("unexpected invocation of MockGitBackend.MergeBaseOctopus")
|
||||
},
|
||||
},
|
||||
RawDiffFunc: &GitBackendRawDiffFunc{
|
||||
defaultHook: func(context.Context, string, string, GitDiffComparisonType, RawDiffOpts, ...string) (io.ReadCloser, error) {
|
||||
panic("unexpected invocation of MockGitBackend.RawDiff")
|
||||
@ -894,6 +907,9 @@ func NewMockGitBackendFrom(i GitBackend) *MockGitBackend {
|
||||
MergeBaseFunc: &GitBackendMergeBaseFunc{
|
||||
defaultHook: i.MergeBase,
|
||||
},
|
||||
MergeBaseOctopusFunc: &GitBackendMergeBaseOctopusFunc{
|
||||
defaultHook: i.MergeBaseOctopus,
|
||||
},
|
||||
RawDiffFunc: &GitBackendRawDiffFunc{
|
||||
defaultHook: i.RawDiff,
|
||||
},
|
||||
@ -2339,6 +2355,121 @@ func (c GitBackendMergeBaseFuncCall) Results() []interface{} {
|
||||
return []interface{}{c.Result0, c.Result1}
|
||||
}
|
||||
|
||||
// GitBackendMergeBaseOctopusFunc describes the behavior when the
|
||||
// MergeBaseOctopus method of the parent MockGitBackend instance is invoked.
|
||||
type GitBackendMergeBaseOctopusFunc struct {
|
||||
defaultHook func(context.Context, ...string) (api.CommitID, error)
|
||||
hooks []func(context.Context, ...string) (api.CommitID, error)
|
||||
history []GitBackendMergeBaseOctopusFuncCall
|
||||
mutex sync.Mutex
|
||||
}
|
||||
|
||||
// MergeBaseOctopus delegates to the next hook function in the queue and
|
||||
// stores the parameter and result values of this invocation.
|
||||
func (m *MockGitBackend) MergeBaseOctopus(v0 context.Context, v1 ...string) (api.CommitID, error) {
|
||||
r0, r1 := m.MergeBaseOctopusFunc.nextHook()(v0, v1...)
|
||||
m.MergeBaseOctopusFunc.appendCall(GitBackendMergeBaseOctopusFuncCall{v0, v1, r0, r1})
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// SetDefaultHook sets function that is called when the MergeBaseOctopus
|
||||
// method of the parent MockGitBackend instance is invoked and the hook
|
||||
// queue is empty.
|
||||
func (f *GitBackendMergeBaseOctopusFunc) SetDefaultHook(hook func(context.Context, ...string) (api.CommitID, error)) {
|
||||
f.defaultHook = hook
|
||||
}
|
||||
|
||||
// PushHook adds a function to the end of hook queue. Each invocation of the
|
||||
// MergeBaseOctopus method of the parent MockGitBackend instance invokes the
|
||||
// hook at the front of the queue and discards it. After the queue is empty,
|
||||
// the default hook function is invoked for any future action.
|
||||
func (f *GitBackendMergeBaseOctopusFunc) PushHook(hook func(context.Context, ...string) (api.CommitID, error)) {
|
||||
f.mutex.Lock()
|
||||
f.hooks = append(f.hooks, hook)
|
||||
f.mutex.Unlock()
|
||||
}
|
||||
|
||||
// SetDefaultReturn calls SetDefaultHook with a function that returns the
|
||||
// given values.
|
||||
func (f *GitBackendMergeBaseOctopusFunc) SetDefaultReturn(r0 api.CommitID, r1 error) {
|
||||
f.SetDefaultHook(func(context.Context, ...string) (api.CommitID, error) {
|
||||
return r0, r1
|
||||
})
|
||||
}
|
||||
|
||||
// PushReturn calls PushHook with a function that returns the given values.
|
||||
func (f *GitBackendMergeBaseOctopusFunc) PushReturn(r0 api.CommitID, r1 error) {
|
||||
f.PushHook(func(context.Context, ...string) (api.CommitID, error) {
|
||||
return r0, r1
|
||||
})
|
||||
}
|
||||
|
||||
func (f *GitBackendMergeBaseOctopusFunc) nextHook() func(context.Context, ...string) (api.CommitID, error) {
|
||||
f.mutex.Lock()
|
||||
defer f.mutex.Unlock()
|
||||
|
||||
if len(f.hooks) == 0 {
|
||||
return f.defaultHook
|
||||
}
|
||||
|
||||
hook := f.hooks[0]
|
||||
f.hooks = f.hooks[1:]
|
||||
return hook
|
||||
}
|
||||
|
||||
func (f *GitBackendMergeBaseOctopusFunc) appendCall(r0 GitBackendMergeBaseOctopusFuncCall) {
|
||||
f.mutex.Lock()
|
||||
f.history = append(f.history, r0)
|
||||
f.mutex.Unlock()
|
||||
}
|
||||
|
||||
// History returns a sequence of GitBackendMergeBaseOctopusFuncCall objects
|
||||
// describing the invocations of this function.
|
||||
func (f *GitBackendMergeBaseOctopusFunc) History() []GitBackendMergeBaseOctopusFuncCall {
|
||||
f.mutex.Lock()
|
||||
history := make([]GitBackendMergeBaseOctopusFuncCall, len(f.history))
|
||||
copy(history, f.history)
|
||||
f.mutex.Unlock()
|
||||
|
||||
return history
|
||||
}
|
||||
|
||||
// GitBackendMergeBaseOctopusFuncCall is an object that describes an
|
||||
// invocation of method MergeBaseOctopus on an instance of MockGitBackend.
|
||||
type GitBackendMergeBaseOctopusFuncCall struct {
|
||||
// Arg0 is the value of the 1st argument passed to this method
|
||||
// invocation.
|
||||
Arg0 context.Context
|
||||
// Arg1 is a slice containing the values of the variadic arguments
|
||||
// passed to this method invocation.
|
||||
Arg1 []string
|
||||
// Result0 is the value of the 1st result returned from this method
|
||||
// invocation.
|
||||
Result0 api.CommitID
|
||||
// Result1 is the value of the 2nd result returned from this method
|
||||
// invocation.
|
||||
Result1 error
|
||||
}
|
||||
|
||||
// Args returns an interface slice containing the arguments of this
|
||||
// invocation. The variadic slice argument is flattened in this array such
|
||||
// that one positional argument and three variadic arguments would result in
|
||||
// a slice of four, not two.
|
||||
func (c GitBackendMergeBaseOctopusFuncCall) Args() []interface{} {
|
||||
trailing := []interface{}{}
|
||||
for _, val := range c.Arg1 {
|
||||
trailing = append(trailing, val)
|
||||
}
|
||||
|
||||
return append([]interface{}{c.Arg0}, trailing...)
|
||||
}
|
||||
|
||||
// Results returns an interface slice containing the results of this
|
||||
// invocation.
|
||||
func (c GitBackendMergeBaseOctopusFuncCall) Results() []interface{} {
|
||||
return []interface{}{c.Result0, c.Result1}
|
||||
}
|
||||
|
||||
// GitBackendRawDiffFunc describes the behavior when the RawDiff method of
|
||||
// the parent MockGitBackend instance is invoked.
|
||||
type GitBackendRawDiffFunc struct {
|
||||
|
||||
@ -112,6 +112,16 @@ func (b *observableBackend) MergeBase(ctx context.Context, baseRevspec, headRevs
|
||||
return b.backend.MergeBase(ctx, baseRevspec, headRevspec)
|
||||
}
|
||||
|
||||
func (b *observableBackend) MergeBaseOctopus(ctx context.Context, revspecs ...string) (_ api.CommitID, err error) {
|
||||
ctx, _, endObservation := b.operations.mergeBaseOctopus.With(ctx, &err, observation.Args{})
|
||||
defer endObservation(1, observation.Args{})
|
||||
|
||||
concurrentOps.WithLabelValues("MergeBaseOctopus").Inc()
|
||||
defer concurrentOps.WithLabelValues("MergeBaseOctopus").Dec()
|
||||
|
||||
return b.backend.MergeBaseOctopus(ctx, revspecs...)
|
||||
}
|
||||
|
||||
func (b *observableBackend) Blame(ctx context.Context, commit api.CommitID, path string, opt BlameOptions) (_ BlameHunkReader, err error) {
|
||||
ctx, errCollector, endObservation := b.operations.blame.WithErrors(ctx, &err, observation.Args{})
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
@ -536,6 +546,7 @@ type operations struct {
|
||||
latestCommitTimestamp *observation.Operation
|
||||
refHash *observation.Operation
|
||||
commitLog *observation.Operation
|
||||
mergeBaseOctopus *observation.Operation
|
||||
}
|
||||
|
||||
func newOperations(observationCtx *observation.Context) *operations {
|
||||
@ -588,6 +599,7 @@ func newOperations(observationCtx *observation.Context) *operations {
|
||||
latestCommitTimestamp: op("latest-commit-timestamp"),
|
||||
refHash: op("ref-hash"),
|
||||
commitLog: op("commit-log"),
|
||||
mergeBaseOctopus: op("merge-base-octopus"),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -687,6 +687,54 @@ func (gs *grpcServer) MergeBase(ctx context.Context, req *proto.MergeBaseRequest
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (gs *grpcServer) MergeBaseOctopus(ctx context.Context, req *proto.MergeBaseOctopusRequest) (*proto.MergeBaseOctopusResponse, error) {
|
||||
revspecs := byteSlicesToStrings(req.GetRevspecs())
|
||||
accesslog.Record(
|
||||
ctx,
|
||||
req.GetRepoName(),
|
||||
log.Int("revspecs", len(revspecs)),
|
||||
)
|
||||
|
||||
if req.GetRepoName() == "" {
|
||||
return nil, status.New(codes.InvalidArgument, "repo must be specified").Err()
|
||||
}
|
||||
|
||||
if len(revspecs) < 2 {
|
||||
return nil, status.New(codes.InvalidArgument, "at least 2 revspecs must be specified").Err()
|
||||
}
|
||||
|
||||
repoName := api.RepoName(req.GetRepoName())
|
||||
repoDir := gs.fs.RepoDir(repoName)
|
||||
|
||||
if err := gs.checkRepoExists(repoName); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
backend := gs.gitBackendSource(repoDir, repoName)
|
||||
|
||||
sha, err := backend.MergeBaseOctopus(ctx, revspecs...)
|
||||
if err != nil {
|
||||
var e *gitdomain.RevisionNotFoundError
|
||||
if errors.As(err, &e) {
|
||||
s, err := status.New(codes.NotFound, "revision not found").WithDetails(&proto.RevisionNotFoundPayload{
|
||||
Repo: req.GetRepoName(),
|
||||
Spec: e.Spec,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return nil, s.Err()
|
||||
}
|
||||
|
||||
gs.svc.LogIfCorrupt(ctx, repoName, err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &proto.MergeBaseOctopusResponse{
|
||||
MergeBaseCommitSha: string(sha),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (gs *grpcServer) GetCommit(ctx context.Context, req *proto.GetCommitRequest) (*proto.GetCommitResponse, error) {
|
||||
accesslog.Record(
|
||||
ctx,
|
||||
|
||||
@ -1096,6 +1096,33 @@ func commitLogRequestToLogFields(req *proto.CommitLogRequest) []log.Field {
|
||||
}
|
||||
}
|
||||
|
||||
func (l *loggingGRPCServer) MergeBaseOctopus(ctx context.Context, request *proto.MergeBaseOctopusRequest) (response *proto.MergeBaseOctopusResponse, err error) {
|
||||
start := time.Now()
|
||||
|
||||
defer func() {
|
||||
elapsed := time.Since(start)
|
||||
|
||||
doLog(
|
||||
l.logger,
|
||||
proto.GitserverService_MergeBaseOctopus_FullMethodName,
|
||||
status.Code(err),
|
||||
trace.Context(ctx).TraceID,
|
||||
elapsed,
|
||||
|
||||
mergeBaseOctopusRequestToLogFields(request)...,
|
||||
)
|
||||
}()
|
||||
|
||||
return l.base.MergeBaseOctopus(ctx, request)
|
||||
}
|
||||
|
||||
func mergeBaseOctopusRequestToLogFields(req *proto.MergeBaseOctopusRequest) []log.Field {
|
||||
return []log.Field{
|
||||
log.String("repoName", req.GetRepoName()),
|
||||
log.Strings("revspecs", byteSlicesToStrings(req.GetRevspecs())),
|
||||
}
|
||||
}
|
||||
|
||||
type loggingRepositoryServiceServer struct {
|
||||
base proto.GitserverRepositoryServiceServer
|
||||
logger log.Logger
|
||||
|
||||
@ -1570,6 +1570,81 @@ func TestGRPCServer_CommitLog(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestGRPCServer_MergeBaseOctopus(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
t.Run("argument validation", func(t *testing.T) {
|
||||
gs := &grpcServer{}
|
||||
_, err := gs.MergeBaseOctopus(ctx, &v1.MergeBaseOctopusRequest{RepoName: ""})
|
||||
require.ErrorContains(t, err, "repo must be specified")
|
||||
assertGRPCStatusCode(t, err, codes.InvalidArgument)
|
||||
_, err = gs.MergeBaseOctopus(ctx, &v1.MergeBaseOctopusRequest{RepoName: "therepo", Revspecs: [][]byte{}})
|
||||
require.ErrorContains(t, err, "at least 2 revspecs must be specified")
|
||||
assertGRPCStatusCode(t, err, codes.InvalidArgument)
|
||||
_, err = gs.MergeBaseOctopus(ctx, &v1.MergeBaseOctopusRequest{RepoName: "therepo", Revspecs: [][]byte{[]byte("onlyone")}})
|
||||
require.ErrorContains(t, err, "at least 2 revspecs must be specified")
|
||||
assertGRPCStatusCode(t, err, codes.InvalidArgument)
|
||||
})
|
||||
t.Run("checks for uncloned repo", func(t *testing.T) {
|
||||
fs := gitserverfs.NewMockFS()
|
||||
fs.RepoClonedFunc.SetDefaultReturn(false, nil)
|
||||
locker := NewMockRepositoryLocker()
|
||||
locker.StatusFunc.SetDefaultReturn("cloning", true)
|
||||
gs := &grpcServer{svc: NewMockService(), fs: fs, locker: locker}
|
||||
_, err := gs.MergeBaseOctopus(ctx, &v1.MergeBaseOctopusRequest{RepoName: "therepo", Revspecs: [][]byte{[]byte("one"), []byte("two"), []byte("three")}})
|
||||
require.Error(t, err)
|
||||
assertGRPCStatusCode(t, err, codes.NotFound)
|
||||
assertHasGRPCErrorDetailOfType(t, err, &proto.RepoNotFoundPayload{})
|
||||
require.Contains(t, err.Error(), "repo not found")
|
||||
mockassert.Called(t, fs.RepoClonedFunc)
|
||||
mockassert.Called(t, locker.StatusFunc)
|
||||
})
|
||||
t.Run("revision not found", func(t *testing.T) {
|
||||
fs := gitserverfs.NewMockFS()
|
||||
// Repo is cloned, proceed!
|
||||
fs.RepoClonedFunc.SetDefaultReturn(true, nil)
|
||||
gs := &grpcServer{
|
||||
svc: NewMockService(),
|
||||
fs: fs,
|
||||
gitBackendSource: func(common.GitDir, api.RepoName) git.GitBackend {
|
||||
b := git.NewMockGitBackend()
|
||||
b.MergeBaseOctopusFunc.SetDefaultReturn("", &gitdomain.RevisionNotFoundError{Repo: "therepo"})
|
||||
return b
|
||||
},
|
||||
}
|
||||
_, err := gs.MergeBaseOctopus(ctx, &v1.MergeBaseOctopusRequest{RepoName: "therepo", Revspecs: [][]byte{[]byte("one"), []byte("two"), []byte("three")}})
|
||||
require.Error(t, err)
|
||||
assertGRPCStatusCode(t, err, codes.NotFound)
|
||||
assertHasGRPCErrorDetailOfType(t, err, &proto.RevisionNotFoundPayload{})
|
||||
require.Contains(t, err.Error(), "revision not found")
|
||||
})
|
||||
t.Run("e2e", func(t *testing.T) {
|
||||
fs := gitserverfs.NewMockFS()
|
||||
// Repo is cloned, proceed!
|
||||
fs.RepoClonedFunc.SetDefaultReturn(true, nil)
|
||||
b := git.NewMockGitBackend()
|
||||
b.MergeBaseOctopusFunc.SetDefaultReturn("deadbeef", nil)
|
||||
gs := &grpcServer{
|
||||
svc: NewMockService(),
|
||||
fs: fs,
|
||||
gitBackendSource: func(common.GitDir, api.RepoName) git.GitBackend {
|
||||
return b
|
||||
},
|
||||
}
|
||||
|
||||
cli := spawnServer(t, gs)
|
||||
res, err := cli.MergeBaseOctopus(ctx, &v1.MergeBaseOctopusRequest{
|
||||
RepoName: "therepo",
|
||||
Revspecs: [][]byte{[]byte("one"), []byte("two"), []byte("three")},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
if diff := cmp.Diff(&proto.MergeBaseOctopusResponse{
|
||||
MergeBaseCommitSha: "deadbeef",
|
||||
}, res, cmpopts.IgnoreUnexported(proto.MergeBaseOctopusResponse{})); diff != "" {
|
||||
t.Fatalf("unexpected response (-want +got):\n%s", diff)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func assertGRPCStatusCode(t *testing.T, err error, want codes.Code) {
|
||||
t.Helper()
|
||||
s, ok := status.FromError(err)
|
||||
|
||||
137
internal/batches/sources/mocks_test.go
generated
137
internal/batches/sources/mocks_test.go
generated
@ -11281,6 +11281,9 @@ type MockGitserverClient struct {
|
||||
// MergeBaseFunc is an instance of a mock function object controlling
|
||||
// the behavior of the method MergeBase.
|
||||
MergeBaseFunc *GitserverClientMergeBaseFunc
|
||||
// MergeBaseOctopusFunc is an instance of a mock function object
|
||||
// controlling the behavior of the method MergeBaseOctopus.
|
||||
MergeBaseOctopusFunc *GitserverClientMergeBaseOctopusFunc
|
||||
// NewFileReaderFunc is an instance of a mock function object
|
||||
// controlling the behavior of the method NewFileReader.
|
||||
NewFileReaderFunc *GitserverClientNewFileReaderFunc
|
||||
@ -11430,6 +11433,11 @@ func NewMockGitserverClient() *MockGitserverClient {
|
||||
return
|
||||
},
|
||||
},
|
||||
MergeBaseOctopusFunc: &GitserverClientMergeBaseOctopusFunc{
|
||||
defaultHook: func(context.Context, api.RepoName, ...string) (r0 api.CommitID, r1 error) {
|
||||
return
|
||||
},
|
||||
},
|
||||
NewFileReaderFunc: &GitserverClientNewFileReaderFunc{
|
||||
defaultHook: func(context.Context, api.RepoName, api.CommitID, string) (r0 io.ReadCloser, r1 error) {
|
||||
return
|
||||
@ -11612,6 +11620,11 @@ func NewStrictMockGitserverClient() *MockGitserverClient {
|
||||
panic("unexpected invocation of MockGitserverClient.MergeBase")
|
||||
},
|
||||
},
|
||||
MergeBaseOctopusFunc: &GitserverClientMergeBaseOctopusFunc{
|
||||
defaultHook: func(context.Context, api.RepoName, ...string) (api.CommitID, error) {
|
||||
panic("unexpected invocation of MockGitserverClient.MergeBaseOctopus")
|
||||
},
|
||||
},
|
||||
NewFileReaderFunc: &GitserverClientNewFileReaderFunc{
|
||||
defaultHook: func(context.Context, api.RepoName, api.CommitID, string) (io.ReadCloser, error) {
|
||||
panic("unexpected invocation of MockGitserverClient.NewFileReader")
|
||||
@ -11757,6 +11770,9 @@ func NewMockGitserverClientFrom(i gitserver.Client) *MockGitserverClient {
|
||||
MergeBaseFunc: &GitserverClientMergeBaseFunc{
|
||||
defaultHook: i.MergeBase,
|
||||
},
|
||||
MergeBaseOctopusFunc: &GitserverClientMergeBaseOctopusFunc{
|
||||
defaultHook: i.MergeBaseOctopus,
|
||||
},
|
||||
NewFileReaderFunc: &GitserverClientNewFileReaderFunc{
|
||||
defaultHook: i.NewFileReader,
|
||||
},
|
||||
@ -13923,6 +13939,127 @@ func (c GitserverClientMergeBaseFuncCall) Results() []interface{} {
|
||||
return []interface{}{c.Result0, c.Result1}
|
||||
}
|
||||
|
||||
// GitserverClientMergeBaseOctopusFunc describes the behavior when the
|
||||
// MergeBaseOctopus method of the parent MockGitserverClient instance is
|
||||
// invoked.
|
||||
type GitserverClientMergeBaseOctopusFunc struct {
|
||||
defaultHook func(context.Context, api.RepoName, ...string) (api.CommitID, error)
|
||||
hooks []func(context.Context, api.RepoName, ...string) (api.CommitID, error)
|
||||
history []GitserverClientMergeBaseOctopusFuncCall
|
||||
mutex sync.Mutex
|
||||
}
|
||||
|
||||
// MergeBaseOctopus delegates to the next hook function in the queue and
|
||||
// stores the parameter and result values of this invocation.
|
||||
func (m *MockGitserverClient) MergeBaseOctopus(v0 context.Context, v1 api.RepoName, v2 ...string) (api.CommitID, error) {
|
||||
r0, r1 := m.MergeBaseOctopusFunc.nextHook()(v0, v1, v2...)
|
||||
m.MergeBaseOctopusFunc.appendCall(GitserverClientMergeBaseOctopusFuncCall{v0, v1, v2, r0, r1})
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// SetDefaultHook sets function that is called when the MergeBaseOctopus
|
||||
// method of the parent MockGitserverClient instance is invoked and the hook
|
||||
// queue is empty.
|
||||
func (f *GitserverClientMergeBaseOctopusFunc) SetDefaultHook(hook func(context.Context, api.RepoName, ...string) (api.CommitID, error)) {
|
||||
f.defaultHook = hook
|
||||
}
|
||||
|
||||
// PushHook adds a function to the end of hook queue. Each invocation of the
|
||||
// MergeBaseOctopus method of the parent MockGitserverClient instance
|
||||
// invokes the hook at the front of the queue and discards it. After the
|
||||
// queue is empty, the default hook function is invoked for any future
|
||||
// action.
|
||||
func (f *GitserverClientMergeBaseOctopusFunc) PushHook(hook func(context.Context, api.RepoName, ...string) (api.CommitID, error)) {
|
||||
f.mutex.Lock()
|
||||
f.hooks = append(f.hooks, hook)
|
||||
f.mutex.Unlock()
|
||||
}
|
||||
|
||||
// SetDefaultReturn calls SetDefaultHook with a function that returns the
|
||||
// given values.
|
||||
func (f *GitserverClientMergeBaseOctopusFunc) SetDefaultReturn(r0 api.CommitID, r1 error) {
|
||||
f.SetDefaultHook(func(context.Context, api.RepoName, ...string) (api.CommitID, error) {
|
||||
return r0, r1
|
||||
})
|
||||
}
|
||||
|
||||
// PushReturn calls PushHook with a function that returns the given values.
|
||||
func (f *GitserverClientMergeBaseOctopusFunc) PushReturn(r0 api.CommitID, r1 error) {
|
||||
f.PushHook(func(context.Context, api.RepoName, ...string) (api.CommitID, error) {
|
||||
return r0, r1
|
||||
})
|
||||
}
|
||||
|
||||
func (f *GitserverClientMergeBaseOctopusFunc) nextHook() func(context.Context, api.RepoName, ...string) (api.CommitID, error) {
|
||||
f.mutex.Lock()
|
||||
defer f.mutex.Unlock()
|
||||
|
||||
if len(f.hooks) == 0 {
|
||||
return f.defaultHook
|
||||
}
|
||||
|
||||
hook := f.hooks[0]
|
||||
f.hooks = f.hooks[1:]
|
||||
return hook
|
||||
}
|
||||
|
||||
func (f *GitserverClientMergeBaseOctopusFunc) appendCall(r0 GitserverClientMergeBaseOctopusFuncCall) {
|
||||
f.mutex.Lock()
|
||||
f.history = append(f.history, r0)
|
||||
f.mutex.Unlock()
|
||||
}
|
||||
|
||||
// History returns a sequence of GitserverClientMergeBaseOctopusFuncCall
|
||||
// objects describing the invocations of this function.
|
||||
func (f *GitserverClientMergeBaseOctopusFunc) History() []GitserverClientMergeBaseOctopusFuncCall {
|
||||
f.mutex.Lock()
|
||||
history := make([]GitserverClientMergeBaseOctopusFuncCall, len(f.history))
|
||||
copy(history, f.history)
|
||||
f.mutex.Unlock()
|
||||
|
||||
return history
|
||||
}
|
||||
|
||||
// GitserverClientMergeBaseOctopusFuncCall is an object that describes an
|
||||
// invocation of method MergeBaseOctopus on an instance of
|
||||
// MockGitserverClient.
|
||||
type GitserverClientMergeBaseOctopusFuncCall struct {
|
||||
// Arg0 is the value of the 1st argument passed to this method
|
||||
// invocation.
|
||||
Arg0 context.Context
|
||||
// Arg1 is the value of the 2nd argument passed to this method
|
||||
// invocation.
|
||||
Arg1 api.RepoName
|
||||
// Arg2 is a slice containing the values of the variadic arguments
|
||||
// passed to this method invocation.
|
||||
Arg2 []string
|
||||
// Result0 is the value of the 1st result returned from this method
|
||||
// invocation.
|
||||
Result0 api.CommitID
|
||||
// Result1 is the value of the 2nd result returned from this method
|
||||
// invocation.
|
||||
Result1 error
|
||||
}
|
||||
|
||||
// Args returns an interface slice containing the arguments of this
|
||||
// invocation. The variadic slice argument is flattened in this array such
|
||||
// that one positional argument and three variadic arguments would result in
|
||||
// a slice of four, not two.
|
||||
func (c GitserverClientMergeBaseOctopusFuncCall) Args() []interface{} {
|
||||
trailing := []interface{}{}
|
||||
for _, val := range c.Arg2 {
|
||||
trailing = append(trailing, val)
|
||||
}
|
||||
|
||||
return append([]interface{}{c.Arg0, c.Arg1}, trailing...)
|
||||
}
|
||||
|
||||
// Results returns an interface slice containing the results of this
|
||||
// invocation.
|
||||
func (c GitserverClientMergeBaseOctopusFuncCall) Results() []interface{} {
|
||||
return []interface{}{c.Result0, c.Result1}
|
||||
}
|
||||
|
||||
// GitserverClientNewFileReaderFunc describes the behavior when the
|
||||
// NewFileReader method of the parent MockGitserverClient instance is
|
||||
// invoked.
|
||||
|
||||
@ -387,6 +387,9 @@ type Client interface {
|
||||
// MergeBase returns the merge base commit sha for the specified revspecs.
|
||||
MergeBase(ctx context.Context, repo api.RepoName, base, head string) (api.CommitID, error)
|
||||
|
||||
// MergeBaseOctopus returns the octopus merge base commit sha for the specified revspecs.
|
||||
MergeBaseOctopus(ctx context.Context, repo api.RepoName, revspecs ...string) (api.CommitID, error)
|
||||
|
||||
RepoCloneProgress(context.Context, api.RepoName) (*protocol.RepoCloneProgress, error)
|
||||
|
||||
// ResolveRevision will return the absolute commit for a commit-ish spec. If spec is empty, HEAD is
|
||||
|
||||
@ -714,6 +714,31 @@ func (c *clientImplementor) MergeBase(ctx context.Context, repo api.RepoName, ba
|
||||
return api.CommitID(res.GetMergeBaseCommitSha()), nil
|
||||
}
|
||||
|
||||
func (c *clientImplementor) MergeBaseOctopus(ctx context.Context, repo api.RepoName, revspecs ...string) (_ api.CommitID, err error) {
|
||||
ctx, _, endObservation := c.operations.mergeBaseOctopus.With(ctx, &err, observation.Args{
|
||||
MetricLabelValues: []string{c.scope},
|
||||
Attrs: []attribute.KeyValue{
|
||||
attribute.StringSlice("revspecs", revspecs),
|
||||
},
|
||||
})
|
||||
defer endObservation(1, observation.Args{})
|
||||
|
||||
client, err := c.clientSource.ClientForRepo(ctx, repo)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
res, err := client.MergeBaseOctopus(ctx, &proto.MergeBaseOctopusRequest{
|
||||
RepoName: string(repo),
|
||||
Revspecs: stringsToByteSlices(revspecs),
|
||||
})
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return api.CommitID(res.GetMergeBaseCommitSha()), nil
|
||||
}
|
||||
|
||||
// BehindAhead returns the behind/ahead commit counts information for right vs. left (both Git
|
||||
// revspecs).
|
||||
func (c *clientImplementor) BehindAhead(ctx context.Context, repo api.RepoName, left, right string) (_ *gitdomain.BehindAhead, err error) {
|
||||
|
||||
@ -2098,6 +2098,56 @@ func TestClient_Commits(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestClient_MergeBaseOctopus(t *testing.T) {
|
||||
t.Run("correctly returns server response", func(t *testing.T) {
|
||||
source := NewTestClientSource(t, []string{"gitserver"}, func(o *TestClientSourceOptions) {
|
||||
o.ClientFunc = func(cc *grpc.ClientConn) proto.GitserverServiceClient {
|
||||
c := NewMockGitserverServiceClient()
|
||||
c.MergeBaseOctopusFunc.SetDefaultReturn(&proto.MergeBaseOctopusResponse{MergeBaseCommitSha: "deadbeef"}, nil)
|
||||
return c
|
||||
}
|
||||
})
|
||||
|
||||
c := NewTestClient(t).WithClientSource(source)
|
||||
|
||||
sha, err := c.MergeBaseOctopus(context.Background(), "repo", "master", "b2")
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, api.CommitID("deadbeef"), sha)
|
||||
})
|
||||
t.Run("returns empty for empty merge base", func(t *testing.T) {
|
||||
source := NewTestClientSource(t, []string{"gitserver"}, func(o *TestClientSourceOptions) {
|
||||
o.ClientFunc = func(cc *grpc.ClientConn) proto.GitserverServiceClient {
|
||||
c := NewMockGitserverServiceClient()
|
||||
c.MergeBaseOctopusFunc.SetDefaultReturn(&proto.MergeBaseOctopusResponse{MergeBaseCommitSha: ""}, nil)
|
||||
return c
|
||||
}
|
||||
})
|
||||
|
||||
c := NewTestClient(t).WithClientSource(source)
|
||||
|
||||
sha, err := c.MergeBaseOctopus(context.Background(), "repo", "master", "b2")
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, api.CommitID(""), sha)
|
||||
})
|
||||
t.Run("revision not found", func(t *testing.T) {
|
||||
source := NewTestClientSource(t, []string{"gitserver"}, func(o *TestClientSourceOptions) {
|
||||
o.ClientFunc = func(cc *grpc.ClientConn) proto.GitserverServiceClient {
|
||||
c := NewMockGitserverServiceClient()
|
||||
s, err := status.New(codes.NotFound, "bad revision").WithDetails(&proto.RevisionNotFoundPayload{Repo: "repo"})
|
||||
require.NoError(t, err)
|
||||
c.MergeBaseOctopusFunc.SetDefaultReturn(nil, s.Err())
|
||||
return c
|
||||
}
|
||||
})
|
||||
|
||||
c := NewTestClient(t).WithClientSource(source)
|
||||
|
||||
_, err := c.MergeBaseOctopus(context.Background(), "repo", "master", "b2")
|
||||
require.Error(t, err)
|
||||
require.True(t, errors.HasType[*gitdomain.RevisionNotFoundError](err))
|
||||
})
|
||||
}
|
||||
|
||||
func mustParseTime(layout, value string) time.Time {
|
||||
tm, err := time.Parse(layout, value)
|
||||
if err != nil {
|
||||
|
||||
@ -362,4 +362,9 @@ func (r *errorTranslatingCommitLogClient) Recv() (*proto.CommitLogResponse, erro
|
||||
return res, convertGRPCErrorToGitDomainError(err)
|
||||
}
|
||||
|
||||
func (r *errorTranslatingClient) MergeBaseOctopus(ctx context.Context, in *proto.MergeBaseOctopusRequest, opts ...grpc.CallOption) (*proto.MergeBaseOctopusResponse, error) {
|
||||
res, err := r.base.MergeBaseOctopus(ctx, in, opts...)
|
||||
return res, convertGRPCErrorToGitDomainError(err)
|
||||
}
|
||||
|
||||
var _ proto.GitserverServiceClient = &errorTranslatingClient{}
|
||||
|
||||
@ -78,6 +78,9 @@ type MockGitserverServiceClient struct {
|
||||
// MergeBaseFunc is an instance of a mock function object controlling
|
||||
// the behavior of the method MergeBase.
|
||||
MergeBaseFunc *GitserverServiceClientMergeBaseFunc
|
||||
// MergeBaseOctopusFunc is an instance of a mock function object
|
||||
// controlling the behavior of the method MergeBaseOctopus.
|
||||
MergeBaseOctopusFunc *GitserverServiceClientMergeBaseOctopusFunc
|
||||
// PerforceGetChangelistFunc is an instance of a mock function object
|
||||
// controlling the behavior of the method PerforceGetChangelist.
|
||||
PerforceGetChangelistFunc *GitserverServiceClientPerforceGetChangelistFunc
|
||||
@ -219,6 +222,11 @@ func NewMockGitserverServiceClient() *MockGitserverServiceClient {
|
||||
return
|
||||
},
|
||||
},
|
||||
MergeBaseOctopusFunc: &GitserverServiceClientMergeBaseOctopusFunc{
|
||||
defaultHook: func(context.Context, *v1.MergeBaseOctopusRequest, ...grpc.CallOption) (r0 *v1.MergeBaseOctopusResponse, r1 error) {
|
||||
return
|
||||
},
|
||||
},
|
||||
PerforceGetChangelistFunc: &GitserverServiceClientPerforceGetChangelistFunc{
|
||||
defaultHook: func(context.Context, *v1.PerforceGetChangelistRequest, ...grpc.CallOption) (r0 *v1.PerforceGetChangelistResponse, r1 error) {
|
||||
return
|
||||
@ -387,6 +395,11 @@ func NewStrictMockGitserverServiceClient() *MockGitserverServiceClient {
|
||||
panic("unexpected invocation of MockGitserverServiceClient.MergeBase")
|
||||
},
|
||||
},
|
||||
MergeBaseOctopusFunc: &GitserverServiceClientMergeBaseOctopusFunc{
|
||||
defaultHook: func(context.Context, *v1.MergeBaseOctopusRequest, ...grpc.CallOption) (*v1.MergeBaseOctopusResponse, error) {
|
||||
panic("unexpected invocation of MockGitserverServiceClient.MergeBaseOctopus")
|
||||
},
|
||||
},
|
||||
PerforceGetChangelistFunc: &GitserverServiceClientPerforceGetChangelistFunc{
|
||||
defaultHook: func(context.Context, *v1.PerforceGetChangelistRequest, ...grpc.CallOption) (*v1.PerforceGetChangelistResponse, error) {
|
||||
panic("unexpected invocation of MockGitserverServiceClient.PerforceGetChangelist")
|
||||
@ -517,6 +530,9 @@ func NewMockGitserverServiceClientFrom(i v1.GitserverServiceClient) *MockGitserv
|
||||
MergeBaseFunc: &GitserverServiceClientMergeBaseFunc{
|
||||
defaultHook: i.MergeBase,
|
||||
},
|
||||
MergeBaseOctopusFunc: &GitserverServiceClientMergeBaseOctopusFunc{
|
||||
defaultHook: i.MergeBaseOctopus,
|
||||
},
|
||||
PerforceGetChangelistFunc: &GitserverServiceClientPerforceGetChangelistFunc{
|
||||
defaultHook: i.PerforceGetChangelist,
|
||||
},
|
||||
@ -2856,6 +2872,128 @@ func (c GitserverServiceClientMergeBaseFuncCall) Results() []interface{} {
|
||||
return []interface{}{c.Result0, c.Result1}
|
||||
}
|
||||
|
||||
// GitserverServiceClientMergeBaseOctopusFunc describes the behavior when
|
||||
// the MergeBaseOctopus method of the parent MockGitserverServiceClient
|
||||
// instance is invoked.
|
||||
type GitserverServiceClientMergeBaseOctopusFunc struct {
|
||||
defaultHook func(context.Context, *v1.MergeBaseOctopusRequest, ...grpc.CallOption) (*v1.MergeBaseOctopusResponse, error)
|
||||
hooks []func(context.Context, *v1.MergeBaseOctopusRequest, ...grpc.CallOption) (*v1.MergeBaseOctopusResponse, error)
|
||||
history []GitserverServiceClientMergeBaseOctopusFuncCall
|
||||
mutex sync.Mutex
|
||||
}
|
||||
|
||||
// MergeBaseOctopus delegates to the next hook function in the queue and
|
||||
// stores the parameter and result values of this invocation.
|
||||
func (m *MockGitserverServiceClient) MergeBaseOctopus(v0 context.Context, v1 *v1.MergeBaseOctopusRequest, v2 ...grpc.CallOption) (*v1.MergeBaseOctopusResponse, error) {
|
||||
r0, r1 := m.MergeBaseOctopusFunc.nextHook()(v0, v1, v2...)
|
||||
m.MergeBaseOctopusFunc.appendCall(GitserverServiceClientMergeBaseOctopusFuncCall{v0, v1, v2, r0, r1})
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// SetDefaultHook sets function that is called when the MergeBaseOctopus
|
||||
// method of the parent MockGitserverServiceClient instance is invoked and
|
||||
// the hook queue is empty.
|
||||
func (f *GitserverServiceClientMergeBaseOctopusFunc) SetDefaultHook(hook func(context.Context, *v1.MergeBaseOctopusRequest, ...grpc.CallOption) (*v1.MergeBaseOctopusResponse, error)) {
|
||||
f.defaultHook = hook
|
||||
}
|
||||
|
||||
// PushHook adds a function to the end of hook queue. Each invocation of the
|
||||
// MergeBaseOctopus method of the parent MockGitserverServiceClient instance
|
||||
// invokes the hook at the front of the queue and discards it. After the
|
||||
// queue is empty, the default hook function is invoked for any future
|
||||
// action.
|
||||
func (f *GitserverServiceClientMergeBaseOctopusFunc) PushHook(hook func(context.Context, *v1.MergeBaseOctopusRequest, ...grpc.CallOption) (*v1.MergeBaseOctopusResponse, error)) {
|
||||
f.mutex.Lock()
|
||||
f.hooks = append(f.hooks, hook)
|
||||
f.mutex.Unlock()
|
||||
}
|
||||
|
||||
// SetDefaultReturn calls SetDefaultHook with a function that returns the
|
||||
// given values.
|
||||
func (f *GitserverServiceClientMergeBaseOctopusFunc) SetDefaultReturn(r0 *v1.MergeBaseOctopusResponse, r1 error) {
|
||||
f.SetDefaultHook(func(context.Context, *v1.MergeBaseOctopusRequest, ...grpc.CallOption) (*v1.MergeBaseOctopusResponse, error) {
|
||||
return r0, r1
|
||||
})
|
||||
}
|
||||
|
||||
// PushReturn calls PushHook with a function that returns the given values.
|
||||
func (f *GitserverServiceClientMergeBaseOctopusFunc) PushReturn(r0 *v1.MergeBaseOctopusResponse, r1 error) {
|
||||
f.PushHook(func(context.Context, *v1.MergeBaseOctopusRequest, ...grpc.CallOption) (*v1.MergeBaseOctopusResponse, error) {
|
||||
return r0, r1
|
||||
})
|
||||
}
|
||||
|
||||
func (f *GitserverServiceClientMergeBaseOctopusFunc) nextHook() func(context.Context, *v1.MergeBaseOctopusRequest, ...grpc.CallOption) (*v1.MergeBaseOctopusResponse, error) {
|
||||
f.mutex.Lock()
|
||||
defer f.mutex.Unlock()
|
||||
|
||||
if len(f.hooks) == 0 {
|
||||
return f.defaultHook
|
||||
}
|
||||
|
||||
hook := f.hooks[0]
|
||||
f.hooks = f.hooks[1:]
|
||||
return hook
|
||||
}
|
||||
|
||||
func (f *GitserverServiceClientMergeBaseOctopusFunc) appendCall(r0 GitserverServiceClientMergeBaseOctopusFuncCall) {
|
||||
f.mutex.Lock()
|
||||
f.history = append(f.history, r0)
|
||||
f.mutex.Unlock()
|
||||
}
|
||||
|
||||
// History returns a sequence of
|
||||
// GitserverServiceClientMergeBaseOctopusFuncCall objects describing the
|
||||
// invocations of this function.
|
||||
func (f *GitserverServiceClientMergeBaseOctopusFunc) History() []GitserverServiceClientMergeBaseOctopusFuncCall {
|
||||
f.mutex.Lock()
|
||||
history := make([]GitserverServiceClientMergeBaseOctopusFuncCall, len(f.history))
|
||||
copy(history, f.history)
|
||||
f.mutex.Unlock()
|
||||
|
||||
return history
|
||||
}
|
||||
|
||||
// GitserverServiceClientMergeBaseOctopusFuncCall is an object that
|
||||
// describes an invocation of method MergeBaseOctopus on an instance of
|
||||
// MockGitserverServiceClient.
|
||||
type GitserverServiceClientMergeBaseOctopusFuncCall struct {
|
||||
// Arg0 is the value of the 1st argument passed to this method
|
||||
// invocation.
|
||||
Arg0 context.Context
|
||||
// Arg1 is the value of the 2nd argument passed to this method
|
||||
// invocation.
|
||||
Arg1 *v1.MergeBaseOctopusRequest
|
||||
// Arg2 is a slice containing the values of the variadic arguments
|
||||
// passed to this method invocation.
|
||||
Arg2 []grpc.CallOption
|
||||
// Result0 is the value of the 1st result returned from this method
|
||||
// invocation.
|
||||
Result0 *v1.MergeBaseOctopusResponse
|
||||
// Result1 is the value of the 2nd result returned from this method
|
||||
// invocation.
|
||||
Result1 error
|
||||
}
|
||||
|
||||
// Args returns an interface slice containing the arguments of this
|
||||
// invocation. The variadic slice argument is flattened in this array such
|
||||
// that one positional argument and three variadic arguments would result in
|
||||
// a slice of four, not two.
|
||||
func (c GitserverServiceClientMergeBaseOctopusFuncCall) Args() []interface{} {
|
||||
trailing := []interface{}{}
|
||||
for _, val := range c.Arg2 {
|
||||
trailing = append(trailing, val)
|
||||
}
|
||||
|
||||
return append([]interface{}{c.Arg0, c.Arg1}, trailing...)
|
||||
}
|
||||
|
||||
// Results returns an interface slice containing the results of this
|
||||
// invocation.
|
||||
func (c GitserverServiceClientMergeBaseOctopusFuncCall) Results() []interface{} {
|
||||
return []interface{}{c.Result0, c.Result1}
|
||||
}
|
||||
|
||||
// GitserverServiceClientPerforceGetChangelistFunc describes the behavior
|
||||
// when the PerforceGetChangelist method of the parent
|
||||
// MockGitserverServiceClient instance is invoked.
|
||||
|
||||
@ -81,6 +81,9 @@ type MockClient struct {
|
||||
// MergeBaseFunc is an instance of a mock function object controlling
|
||||
// the behavior of the method MergeBase.
|
||||
MergeBaseFunc *ClientMergeBaseFunc
|
||||
// MergeBaseOctopusFunc is an instance of a mock function object
|
||||
// controlling the behavior of the method MergeBaseOctopus.
|
||||
MergeBaseOctopusFunc *ClientMergeBaseOctopusFunc
|
||||
// NewFileReaderFunc is an instance of a mock function object
|
||||
// controlling the behavior of the method NewFileReader.
|
||||
NewFileReaderFunc *ClientNewFileReaderFunc
|
||||
@ -230,6 +233,11 @@ func NewMockClient() *MockClient {
|
||||
return
|
||||
},
|
||||
},
|
||||
MergeBaseOctopusFunc: &ClientMergeBaseOctopusFunc{
|
||||
defaultHook: func(context.Context, api.RepoName, ...string) (r0 api.CommitID, r1 error) {
|
||||
return
|
||||
},
|
||||
},
|
||||
NewFileReaderFunc: &ClientNewFileReaderFunc{
|
||||
defaultHook: func(context.Context, api.RepoName, api.CommitID, string) (r0 io.ReadCloser, r1 error) {
|
||||
return
|
||||
@ -412,6 +420,11 @@ func NewStrictMockClient() *MockClient {
|
||||
panic("unexpected invocation of MockClient.MergeBase")
|
||||
},
|
||||
},
|
||||
MergeBaseOctopusFunc: &ClientMergeBaseOctopusFunc{
|
||||
defaultHook: func(context.Context, api.RepoName, ...string) (api.CommitID, error) {
|
||||
panic("unexpected invocation of MockClient.MergeBaseOctopus")
|
||||
},
|
||||
},
|
||||
NewFileReaderFunc: &ClientNewFileReaderFunc{
|
||||
defaultHook: func(context.Context, api.RepoName, api.CommitID, string) (io.ReadCloser, error) {
|
||||
panic("unexpected invocation of MockClient.NewFileReader")
|
||||
@ -556,6 +569,9 @@ func NewMockClientFrom(i Client) *MockClient {
|
||||
MergeBaseFunc: &ClientMergeBaseFunc{
|
||||
defaultHook: i.MergeBase,
|
||||
},
|
||||
MergeBaseOctopusFunc: &ClientMergeBaseOctopusFunc{
|
||||
defaultHook: i.MergeBaseOctopus,
|
||||
},
|
||||
NewFileReaderFunc: &ClientNewFileReaderFunc{
|
||||
defaultHook: i.NewFileReader,
|
||||
},
|
||||
@ -2687,6 +2703,124 @@ func (c ClientMergeBaseFuncCall) Results() []interface{} {
|
||||
return []interface{}{c.Result0, c.Result1}
|
||||
}
|
||||
|
||||
// ClientMergeBaseOctopusFunc describes the behavior when the
|
||||
// MergeBaseOctopus method of the parent MockClient instance is invoked.
|
||||
type ClientMergeBaseOctopusFunc struct {
|
||||
defaultHook func(context.Context, api.RepoName, ...string) (api.CommitID, error)
|
||||
hooks []func(context.Context, api.RepoName, ...string) (api.CommitID, error)
|
||||
history []ClientMergeBaseOctopusFuncCall
|
||||
mutex sync.Mutex
|
||||
}
|
||||
|
||||
// MergeBaseOctopus delegates to the next hook function in the queue and
|
||||
// stores the parameter and result values of this invocation.
|
||||
func (m *MockClient) MergeBaseOctopus(v0 context.Context, v1 api.RepoName, v2 ...string) (api.CommitID, error) {
|
||||
r0, r1 := m.MergeBaseOctopusFunc.nextHook()(v0, v1, v2...)
|
||||
m.MergeBaseOctopusFunc.appendCall(ClientMergeBaseOctopusFuncCall{v0, v1, v2, r0, r1})
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// SetDefaultHook sets function that is called when the MergeBaseOctopus
|
||||
// method of the parent MockClient instance is invoked and the hook queue is
|
||||
// empty.
|
||||
func (f *ClientMergeBaseOctopusFunc) SetDefaultHook(hook func(context.Context, api.RepoName, ...string) (api.CommitID, error)) {
|
||||
f.defaultHook = hook
|
||||
}
|
||||
|
||||
// PushHook adds a function to the end of hook queue. Each invocation of the
|
||||
// MergeBaseOctopus method of the parent MockClient instance invokes the
|
||||
// hook at the front of the queue and discards it. After the queue is empty,
|
||||
// the default hook function is invoked for any future action.
|
||||
func (f *ClientMergeBaseOctopusFunc) PushHook(hook func(context.Context, api.RepoName, ...string) (api.CommitID, error)) {
|
||||
f.mutex.Lock()
|
||||
f.hooks = append(f.hooks, hook)
|
||||
f.mutex.Unlock()
|
||||
}
|
||||
|
||||
// SetDefaultReturn calls SetDefaultHook with a function that returns the
|
||||
// given values.
|
||||
func (f *ClientMergeBaseOctopusFunc) SetDefaultReturn(r0 api.CommitID, r1 error) {
|
||||
f.SetDefaultHook(func(context.Context, api.RepoName, ...string) (api.CommitID, error) {
|
||||
return r0, r1
|
||||
})
|
||||
}
|
||||
|
||||
// PushReturn calls PushHook with a function that returns the given values.
|
||||
func (f *ClientMergeBaseOctopusFunc) PushReturn(r0 api.CommitID, r1 error) {
|
||||
f.PushHook(func(context.Context, api.RepoName, ...string) (api.CommitID, error) {
|
||||
return r0, r1
|
||||
})
|
||||
}
|
||||
|
||||
func (f *ClientMergeBaseOctopusFunc) nextHook() func(context.Context, api.RepoName, ...string) (api.CommitID, error) {
|
||||
f.mutex.Lock()
|
||||
defer f.mutex.Unlock()
|
||||
|
||||
if len(f.hooks) == 0 {
|
||||
return f.defaultHook
|
||||
}
|
||||
|
||||
hook := f.hooks[0]
|
||||
f.hooks = f.hooks[1:]
|
||||
return hook
|
||||
}
|
||||
|
||||
func (f *ClientMergeBaseOctopusFunc) appendCall(r0 ClientMergeBaseOctopusFuncCall) {
|
||||
f.mutex.Lock()
|
||||
f.history = append(f.history, r0)
|
||||
f.mutex.Unlock()
|
||||
}
|
||||
|
||||
// History returns a sequence of ClientMergeBaseOctopusFuncCall objects
|
||||
// describing the invocations of this function.
|
||||
func (f *ClientMergeBaseOctopusFunc) History() []ClientMergeBaseOctopusFuncCall {
|
||||
f.mutex.Lock()
|
||||
history := make([]ClientMergeBaseOctopusFuncCall, len(f.history))
|
||||
copy(history, f.history)
|
||||
f.mutex.Unlock()
|
||||
|
||||
return history
|
||||
}
|
||||
|
||||
// ClientMergeBaseOctopusFuncCall is an object that describes an invocation
|
||||
// of method MergeBaseOctopus on an instance of MockClient.
|
||||
type ClientMergeBaseOctopusFuncCall struct {
|
||||
// Arg0 is the value of the 1st argument passed to this method
|
||||
// invocation.
|
||||
Arg0 context.Context
|
||||
// Arg1 is the value of the 2nd argument passed to this method
|
||||
// invocation.
|
||||
Arg1 api.RepoName
|
||||
// Arg2 is a slice containing the values of the variadic arguments
|
||||
// passed to this method invocation.
|
||||
Arg2 []string
|
||||
// Result0 is the value of the 1st result returned from this method
|
||||
// invocation.
|
||||
Result0 api.CommitID
|
||||
// Result1 is the value of the 2nd result returned from this method
|
||||
// invocation.
|
||||
Result1 error
|
||||
}
|
||||
|
||||
// Args returns an interface slice containing the arguments of this
|
||||
// invocation. The variadic slice argument is flattened in this array such
|
||||
// that one positional argument and three variadic arguments would result in
|
||||
// a slice of four, not two.
|
||||
func (c ClientMergeBaseOctopusFuncCall) Args() []interface{} {
|
||||
trailing := []interface{}{}
|
||||
for _, val := range c.Arg2 {
|
||||
trailing = append(trailing, val)
|
||||
}
|
||||
|
||||
return append([]interface{}{c.Arg0, c.Arg1}, trailing...)
|
||||
}
|
||||
|
||||
// Results returns an interface slice containing the results of this
|
||||
// invocation.
|
||||
func (c ClientMergeBaseOctopusFuncCall) Results() []interface{} {
|
||||
return []interface{}{c.Result0, c.Result1}
|
||||
}
|
||||
|
||||
// ClientNewFileReaderFunc describes the behavior when the NewFileReader
|
||||
// method of the parent MockClient instance is invoked.
|
||||
type ClientNewFileReaderFunc struct {
|
||||
|
||||
@ -46,6 +46,7 @@ type operations struct {
|
||||
getDefaultBranch *observation.Operation
|
||||
diff *observation.Operation
|
||||
changedFiles *observation.Operation
|
||||
mergeBaseOctopus *observation.Operation
|
||||
}
|
||||
|
||||
func newOperations(observationCtx *observation.Context) *operations {
|
||||
@ -127,6 +128,7 @@ func newOperations(observationCtx *observation.Context) *operations {
|
||||
getDefaultBranch: op("GetDefaultBranch"),
|
||||
diff: op("Diff"),
|
||||
changedFiles: op("ChangedFiles"),
|
||||
mergeBaseOctopus: op("MergeBaseOctopus"),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -185,4 +185,9 @@ func (r *automaticRetryClient) CommitLog(ctx context.Context, in *proto.CommitLo
|
||||
return r.base.CommitLog(ctx, in, opts...)
|
||||
}
|
||||
|
||||
func (r *automaticRetryClient) MergeBaseOctopus(ctx context.Context, in *proto.MergeBaseOctopusRequest, opts ...grpc.CallOption) (*proto.MergeBaseOctopusResponse, error) {
|
||||
opts = append(defaults.RetryPolicy, opts...)
|
||||
return r.base.MergeBaseOctopus(ctx, in, opts...)
|
||||
}
|
||||
|
||||
var _ proto.GitserverServiceClient = &automaticRetryClient{}
|
||||
|
||||
958
internal/gitserver/v1/gitserver.pb.go
generated
958
internal/gitserver/v1/gitserver.pb.go
generated
File diff suppressed because it is too large
Load Diff
@ -344,6 +344,27 @@ service GitserverService {
|
||||
rpc CommitLog(CommitLogRequest) returns (stream CommitLogResponse) {
|
||||
option idempotency_level = NO_SIDE_EFFECTS;
|
||||
}
|
||||
// MergeBaseOctopus returns the octopus merge base commit sha for the specified
|
||||
// revspecs.
|
||||
// If no common merge base exists, an empty string is returned.
|
||||
// See the following diagrams from git-merge-base docs on what octopus merge bases
|
||||
// are:
|
||||
// Given three commits A, B, and C, MergeBaseOctopus(A, B, C) will compute the
|
||||
// best common ancestor of all commits.
|
||||
// For example, with this topology:
|
||||
// o---o---o---o---C
|
||||
// /
|
||||
// / o---o---o---B
|
||||
// / /
|
||||
// ---2---1---o---o---o---A
|
||||
// The result of MergeBaseOctopus(A, B, C) is 2, because 2 is the
|
||||
// best common ancestor of all commits.
|
||||
//
|
||||
// If the given repo is not cloned, it will be enqueued for cloning and a
|
||||
// NotFound error will be returned, with a RepoNotFoundPayload in the details.
|
||||
rpc MergeBaseOctopus(MergeBaseOctopusRequest) returns (MergeBaseOctopusResponse) {
|
||||
option idempotency_level = NO_SIDE_EFFECTS;
|
||||
}
|
||||
}
|
||||
|
||||
message CommitLogRequest {
|
||||
@ -1265,6 +1286,22 @@ message MergeBaseResponse {
|
||||
string merge_base_commit_sha = 1;
|
||||
}
|
||||
|
||||
// MergeBaseOctopusRequest is a request to find the octopus merge base of revspecs.
|
||||
message MergeBaseOctopusRequest {
|
||||
// repo_name is the name of the repo to get the octopus merge base for.
|
||||
// Note: We use field ID 2 here to reserve 1 for a future repo int32 field.
|
||||
string repo_name = 2;
|
||||
// revspecs are the revspecs to consider for merge-base. For now, we allow non-utf8
|
||||
// revspecs.
|
||||
repeated bytes revspecs = 3;
|
||||
}
|
||||
|
||||
// MergeBaseOctopusResponse is the response from finding the octopus merge base of
|
||||
// the given revspecs.
|
||||
message MergeBaseOctopusResponse {
|
||||
string merge_base_commit_sha = 1;
|
||||
}
|
||||
|
||||
// FirstEverCommitRequest is a request to get the first ever commit in a repo.
|
||||
message FirstEverCommitRequest {
|
||||
// repo_name is the name of the repo to get the first ever commit for.
|
||||
|
||||
95
internal/gitserver/v1/gitserver_grpc.pb.go
generated
95
internal/gitserver/v1/gitserver_grpc.pb.go
generated
@ -226,6 +226,7 @@ const (
|
||||
GitserverService_Stat_FullMethodName = "/gitserver.v1.GitserverService/Stat"
|
||||
GitserverService_ReadDir_FullMethodName = "/gitserver.v1.GitserverService/ReadDir"
|
||||
GitserverService_CommitLog_FullMethodName = "/gitserver.v1.GitserverService/CommitLog"
|
||||
GitserverService_MergeBaseOctopus_FullMethodName = "/gitserver.v1.GitserverService/MergeBaseOctopus"
|
||||
)
|
||||
|
||||
// GitserverServiceClient is the client API for GitserverService service.
|
||||
@ -439,6 +440,36 @@ type GitserverServiceClient interface {
|
||||
// If one of the given ranges doesn't exist, an error with a ReversionNotFoundPayload
|
||||
// is returned.
|
||||
CommitLog(ctx context.Context, in *CommitLogRequest, opts ...grpc.CallOption) (GitserverService_CommitLogClient, error)
|
||||
// MergeBaseOctopus returns the octopus merge base commit sha for the specified
|
||||
// revspecs.
|
||||
// If no common merge base exists, an empty string is returned.
|
||||
// See the following diagrams from git-merge-base docs on what octopus merge bases
|
||||
// are:
|
||||
// Given three commits A, B, and C, git merge-base A B C will compute the merge base between A and a hypothetical commit M, which is a merge between B and C. For example, with this topology:
|
||||
//
|
||||
// o---o---o---o---C
|
||||
// /
|
||||
//
|
||||
// / o---o---o---B
|
||||
// / /
|
||||
// ---2---1---o---o---o---A
|
||||
//
|
||||
// the result of git merge-base A B C is 1. This is because the equivalent topology with a merge commit M between B and C is:
|
||||
//
|
||||
// o---o---o---o---o
|
||||
// / \
|
||||
//
|
||||
// / o---o---o---o---M
|
||||
// / /
|
||||
// ---2---1---o---o---o---A
|
||||
//
|
||||
// and the result of git merge-base A M is 1. Commit 2 is also a common ancestor between A and M, but 1 is a better common ancestor, because 2 is an ancestor of 1. Hence, 2 is not a merge base.
|
||||
//
|
||||
// The result of git merge-base --octopus A B C is 2, because 2 is the best common ancestor of all commits.
|
||||
//
|
||||
// If the given repo is not cloned, it will be enqueued for cloning and a
|
||||
// NotFound error will be returned, with a RepoNotFoundPayload in the details.
|
||||
MergeBaseOctopus(ctx context.Context, in *MergeBaseOctopusRequest, opts ...grpc.CallOption) (*MergeBaseOctopusResponse, error)
|
||||
}
|
||||
|
||||
type gitserverServiceClient struct {
|
||||
@ -969,6 +1000,15 @@ func (x *gitserverServiceCommitLogClient) Recv() (*CommitLogResponse, error) {
|
||||
return m, nil
|
||||
}
|
||||
|
||||
func (c *gitserverServiceClient) MergeBaseOctopus(ctx context.Context, in *MergeBaseOctopusRequest, opts ...grpc.CallOption) (*MergeBaseOctopusResponse, error) {
|
||||
out := new(MergeBaseOctopusResponse)
|
||||
err := c.cc.Invoke(ctx, GitserverService_MergeBaseOctopus_FullMethodName, in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// GitserverServiceServer is the server API for GitserverService service.
|
||||
// All implementations must embed UnimplementedGitserverServiceServer
|
||||
// for forward compatibility
|
||||
@ -1180,6 +1220,36 @@ type GitserverServiceServer interface {
|
||||
// If one of the given ranges doesn't exist, an error with a ReversionNotFoundPayload
|
||||
// is returned.
|
||||
CommitLog(*CommitLogRequest, GitserverService_CommitLogServer) error
|
||||
// MergeBaseOctopus returns the octopus merge base commit sha for the specified
|
||||
// revspecs.
|
||||
// If no common merge base exists, an empty string is returned.
|
||||
// See the following diagrams from git-merge-base docs on what octopus merge bases
|
||||
// are:
|
||||
// Given three commits A, B, and C, git merge-base A B C will compute the merge base between A and a hypothetical commit M, which is a merge between B and C. For example, with this topology:
|
||||
//
|
||||
// o---o---o---o---C
|
||||
// /
|
||||
//
|
||||
// / o---o---o---B
|
||||
// / /
|
||||
// ---2---1---o---o---o---A
|
||||
//
|
||||
// the result of git merge-base A B C is 1. This is because the equivalent topology with a merge commit M between B and C is:
|
||||
//
|
||||
// o---o---o---o---o
|
||||
// / \
|
||||
//
|
||||
// / o---o---o---o---M
|
||||
// / /
|
||||
// ---2---1---o---o---o---A
|
||||
//
|
||||
// and the result of git merge-base A M is 1. Commit 2 is also a common ancestor between A and M, but 1 is a better common ancestor, because 2 is an ancestor of 1. Hence, 2 is not a merge base.
|
||||
//
|
||||
// The result of git merge-base --octopus A B C is 2, because 2 is the best common ancestor of all commits.
|
||||
//
|
||||
// If the given repo is not cloned, it will be enqueued for cloning and a
|
||||
// NotFound error will be returned, with a RepoNotFoundPayload in the details.
|
||||
MergeBaseOctopus(context.Context, *MergeBaseOctopusRequest) (*MergeBaseOctopusResponse, error)
|
||||
mustEmbedUnimplementedGitserverServiceServer()
|
||||
}
|
||||
|
||||
@ -1283,6 +1353,9 @@ func (UnimplementedGitserverServiceServer) ReadDir(*ReadDirRequest, GitserverSer
|
||||
func (UnimplementedGitserverServiceServer) CommitLog(*CommitLogRequest, GitserverService_CommitLogServer) error {
|
||||
return status.Errorf(codes.Unimplemented, "method CommitLog not implemented")
|
||||
}
|
||||
func (UnimplementedGitserverServiceServer) MergeBaseOctopus(context.Context, *MergeBaseOctopusRequest) (*MergeBaseOctopusResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method MergeBaseOctopus not implemented")
|
||||
}
|
||||
func (UnimplementedGitserverServiceServer) mustEmbedUnimplementedGitserverServiceServer() {}
|
||||
|
||||
// UnsafeGitserverServiceServer may be embedded to opt out of forward compatibility for this service.
|
||||
@ -1907,6 +1980,24 @@ func (x *gitserverServiceCommitLogServer) Send(m *CommitLogResponse) error {
|
||||
return x.ServerStream.SendMsg(m)
|
||||
}
|
||||
|
||||
func _GitserverService_MergeBaseOctopus_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(MergeBaseOctopusRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(GitserverServiceServer).MergeBaseOctopus(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: GitserverService_MergeBaseOctopus_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(GitserverServiceServer).MergeBaseOctopus(ctx, req.(*MergeBaseOctopusRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
// GitserverService_ServiceDesc is the grpc.ServiceDesc for GitserverService service.
|
||||
// It's only intended for direct use with grpc.RegisterService,
|
||||
// and not to be introspected or modified (even as a copy)
|
||||
@ -2002,6 +2093,10 @@ var GitserverService_ServiceDesc = grpc.ServiceDesc{
|
||||
MethodName: "Stat",
|
||||
Handler: _GitserverService_Stat_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "MergeBaseOctopus",
|
||||
Handler: _GitserverService_MergeBaseOctopus_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{
|
||||
{
|
||||
|
||||
Loading…
Reference in New Issue
Block a user