diff options
27 files changed, 8 insertions, 1493 deletions
@@ -67,7 +67,6 @@ GITALY_PACKAGE := $(shell go list -m 2>/dev/null || echo unknown) GITALY_VERSION := $(shell ${GIT} describe --match v* 2>/dev/null | sed 's/^v//' || cat ${SOURCE_DIR}/VERSION 2>/dev/null || echo unknown) GO_LDFLAGS := -X ${GITALY_PACKAGE}/internal/version.version=${GITALY_VERSION} SERVER_BUILD_TAGS := tracer_static,tracer_static_jaeger,tracer_static_stackdriver,continuous_profiler_stackdriver -GIT2GO_BUILD_TAGS := static,system_libgit2 # Temporary GNU build ID used as a placeholder value so that we can replace it # with our own one after binaries have been built. This is the ASCII encoding @@ -80,7 +79,6 @@ FIPS_MODE ?= ifdef FIPS_MODE SERVER_BUILD_TAGS := ${SERVER_BUILD_TAGS},fips - GIT2GO_BUILD_TAGS := ${GIT2GO_BUILD_TAGS},fips # Build Git with the OpenSSL backend for SHA256 in case FIPS-mode is # requested. Note that we explicitly don't do the same for SHA1: we @@ -236,7 +234,7 @@ BUILD_GEM_OPTIONS ?= # All executables provided by Gitaly. GITALY_EXECUTABLES = $(addprefix ${BUILD_DIR}/bin/,$(notdir $(shell find ${SOURCE_DIR}/cmd -mindepth 1 -maxdepth 1 -type d -print))) # All executables packed inside the Gitaly binary. -GITALY_PACKED_EXECUTABLES = $(filter %gitaly-hooks %gitaly-gpg %gitaly-git2go %gitaly-ssh %gitaly-lfs-smudge, ${GITALY_EXECUTABLES}) +GITALY_PACKED_EXECUTABLES = $(filter %gitaly-hooks %gitaly-gpg %gitaly-ssh %gitaly-lfs-smudge, ${GITALY_EXECUTABLES}) # All executables that should be installed. GITALY_INSTALLED_EXECUTABLES = $(filter-out ${GITALY_PACKED_EXECUTABLES}, ${GITALY_EXECUTABLES}) # Find all Go source files. @@ -251,7 +249,7 @@ find_go_sources = $(shell find ${SOURCE_DIR} -type d \( -path "${SO run_go_tests = PATH='${SOURCE_DIR}/internal/testhelper/testdata/home/bin:${PATH}' \ TEST_TMP_DIR='${TEST_TMP_DIR}' \ TEST_LOG_DIR='${TEST_LOG_DIR}' \ - ${GOTESTSUM} --format ${TEST_FORMAT} --junitfile '${TEST_JUNIT_REPORT}' --jsonfile '${TEST_JSON_REPORT}' -- -ldflags '${GO_LDFLAGS}' -tags '${SERVER_BUILD_TAGS},${GIT2GO_BUILD_TAGS}' ${TEST_OPTIONS} ${TEST_PACKAGES} + ${GOTESTSUM} --format ${TEST_FORMAT} --junitfile '${TEST_JUNIT_REPORT}' --jsonfile '${TEST_JSON_REPORT}' -- -ldflags '${GO_LDFLAGS}' -tags '${SERVER_BUILD_TAGS}' ${TEST_OPTIONS} ${TEST_PACKAGES} ## Test options passed to `dlv test`. DEBUG_OPTIONS ?= $(patsubst -%,-test.%,${TEST_OPTIONS}) @@ -262,7 +260,7 @@ DEBUG_OPTIONS ?= $(patsubst -%,-test.%,${TEST_OPTIONS}) # DEBUG_OPTIONS: any additional options, will default to TEST_OPTIONS if not set. debug_go_tests = PATH='${SOURCE_DIR}/internal/testhelper/testdata/home/bin:${PATH}' \ TEST_TMP_DIR='${TEST_TMP_DIR}' \ - ${DELVE} test --build-flags="-ldflags '${GO_LDFLAGS}' -tags '${SERVER_BUILD_TAGS},${GIT2GO_BUILD_TAGS}'" ${TEST_PACKAGES} -- ${DEBUG_OPTIONS} + ${DELVE} test --build-flags="-ldflags '${GO_LDFLAGS}' -tags '${SERVER_BUILD_TAGS}'" ${TEST_PACKAGES} -- ${DEBUG_OPTIONS} unexport GOROOT ## GOCACHE_MAX_SIZE_KB is the maximum size of Go's build cache in kilobytes before it is cleaned up. @@ -445,12 +443,12 @@ ${TOOLS_DIR}/gitaly-linters.so: ${SOURCE_DIR}/tools/golangci-lint/go.sum $(wildc .PHONY: lint ## Run Go linter. lint: ${GOLANGCI_LINT} libgit2 ${GITALY_PACKED_EXECUTABLES} ${TOOLS_DIR}/gitaly-linters.so lint-gitaly-linters - ${Q}${GOLANGCI_LINT} run --build-tags "${SERVER_BUILD_TAGS},${GIT2GO_BUILD_TAGS}" --out-format tab --config ${GOLANGCI_LINT_CONFIG} ${GOLANGCI_LINT_OPTIONS} + ${Q}${GOLANGCI_LINT} run --build-tags "${SERVER_BUILD_TAGS}" --out-format tab --config ${GOLANGCI_LINT_CONFIG} ${GOLANGCI_LINT_OPTIONS} .PHONY: lint-fix ## Run Go linter and write back fixes to the files (not supported by all linters). lint-fix: ${GOLANGCI_LINT} libgit2 ${GITALY_PACKED_EXECUTABLES} ${TOOLS_DIR}/gitaly-linters.so - ${Q}${GOLANGCI_LINT} run --fix --build-tags "${SERVER_BUILD_TAGS},${GIT2GO_BUILD_TAGS}" --out-format tab --config ${GOLANGCI_LINT_CONFIG} ${GOLANGCI_LINT_OPTIONS} + ${Q}${GOLANGCI_LINT} run --fix --build-tags "${SERVER_BUILD_TAGS}" --out-format tab --config ${GOLANGCI_LINT_CONFIG} ${GOLANGCI_LINT_OPTIONS} .PHONY: lint-docs ## Run markdownlint-cli2-config to lint the documentation. @@ -561,7 +559,7 @@ ${SOURCE_DIR}/NOTICE: ${BUILD_DIR}/NOTICE ${BUILD_DIR}/NOTICE: ${GO_LICENSES} ${GITALY_PACKED_EXECUTABLES} ${Q}rm -rf ${BUILD_DIR}/licenses - ${Q}GOOS=linux GOFLAGS="-tags=${SERVER_BUILD_TAGS},${GIT2GO_BUILD_TAGS}" ${GO_LICENSES} save ${SOURCE_DIR}/... --save_path=${BUILD_DIR}/licenses + ${Q}GOOS=linux GOFLAGS="-tags=${SERVER_BUILD_TAGS}" ${GO_LICENSES} save ${SOURCE_DIR}/... --save_path=${BUILD_DIR}/licenses ${Q}go run ${SOURCE_DIR}/tools/noticegen/noticegen.go -source ${BUILD_DIR}/licenses -template ${SOURCE_DIR}/tools/noticegen/notice.template > ${BUILD_DIR}/NOTICE ${BUILD_DIR}: @@ -612,8 +610,6 @@ clear-go-build-cache-if-needed: ${BUILD_DIR}/intermediate/gitaly: GO_BUILD_TAGS = ${SERVER_BUILD_TAGS} ${BUILD_DIR}/intermediate/gitaly: ${GITALY_PACKED_EXECUTABLES} ${BUILD_DIR}/intermediate/praefect: GO_BUILD_TAGS = ${SERVER_BUILD_TAGS} -${BUILD_DIR}/intermediate/gitaly-git2go: GO_BUILD_TAGS = ${GIT2GO_BUILD_TAGS} -${BUILD_DIR}/intermediate/gitaly-git2go: libgit2 ${BUILD_DIR}/intermediate/%: clear-go-build-cache-if-needed .FORCE @ # We're building intermediate binaries first which contain a fixed build ID @ # of "TEMP_GITALY_BUILD_ID". In the final binary we replace this build ID with @@ -21175,30 +21175,6 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -LICENSE - github.com/libgit2/git2go/v34 -The MIT License - -Copyright (c) 2013 The git2go contributors - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ LICENSE - github.com/mattn/go-isatty Copyright (c) Yasuhiro MATSUMOTO <mattn.jp@gmail.com> diff --git a/cmd/gitaly-git2go/featureflags.go b/cmd/gitaly-git2go/featureflags.go deleted file mode 100644 index 055f18be9..000000000 --- a/cmd/gitaly-git2go/featureflags.go +++ /dev/null @@ -1,41 +0,0 @@ -//go:build static && system_libgit2 && gitaly_test - -package main - -import ( - "context" - "encoding/gob" - "flag" - - "gitlab.com/gitlab-org/gitaly/v16/internal/featureflag" - "gitlab.com/gitlab-org/gitaly/v16/internal/git2go" -) - -// This subcommand is only called in tests, so we don't want to register it like -// the other subcommands but instead will do it in an init block. The gitaly_test build -// flag will guarantee that this is not built and registered in the -// gitaly-git2go binary -func init() { - subcommands["feature-flags"] = &featureFlagsSubcommand{} -} - -type featureFlagsSubcommand struct{} - -func (featureFlagsSubcommand) Flags() *flag.FlagSet { - return flag.NewFlagSet("feature-flags", flag.ExitOnError) -} - -func (featureFlagsSubcommand) Run(ctx context.Context, decoder *gob.Decoder, encoder *gob.Encoder) error { - var flags []git2go.FeatureFlag - for flag, value := range featureflag.FromContext(ctx) { - flags = append(flags, git2go.FeatureFlag{ - Name: flag.Name, - MetadataKey: flag.MetadataKey(), - Value: value, - }) - } - - return encoder.Encode(git2go.FeatureFlags{ - Flags: flags, - }) -} diff --git a/cmd/gitaly-git2go/git2goutil/commit.go b/cmd/gitaly-git2go/git2goutil/commit.go deleted file mode 100644 index 804715884..000000000 --- a/cmd/gitaly-git2go/git2goutil/commit.go +++ /dev/null @@ -1,47 +0,0 @@ -package git2goutil - -import ( - "fmt" - - git "github.com/libgit2/git2go/v34" -) - -// CommitSubmitter is the helper struct to make signed Commits conveniently. -type CommitSubmitter struct { - Repo *git.Repository - SigningKeyPath string -} - -// NewCommitSubmitter creates a new CommitSubmitter. -func NewCommitSubmitter(repo *git.Repository, signingKeyPath string) *CommitSubmitter { - return &CommitSubmitter{ - Repo: repo, - SigningKeyPath: signingKeyPath, - } -} - -// Commit commits a commit with or without signature depends on SigningKeyPath value. -func (cs *CommitSubmitter) Commit( - author, committer *git.Signature, - messageEncoding git.MessageEncoding, - message string, - tree *git.Tree, - parents ...*git.Commit, -) (*git.Oid, error) { - commitBytes, err := cs.Repo.CreateCommitBuffer(author, committer, messageEncoding, message, tree, parents...) - if err != nil { - return nil, err - } - - signature, err := CreateCommitSignature(cs.SigningKeyPath, commitBytes) - if err != nil { - return nil, fmt.Errorf("create commit signature: %w", err) - } - - commitID, err := cs.Repo.CreateCommitWithSignature(string(commitBytes), string(signature), "") - if err != nil { - return nil, err - } - - return commitID, nil -} diff --git a/cmd/gitaly-git2go/git2goutil/repo.go b/cmd/gitaly-git2go/git2goutil/repo.go deleted file mode 100644 index 1a1c4ede2..000000000 --- a/cmd/gitaly-git2go/git2goutil/repo.go +++ /dev/null @@ -1,10 +0,0 @@ -package git2goutil - -import ( - git "github.com/libgit2/git2go/v34" -) - -// OpenRepository opens the repository located at path as a Git2Go repository. -func OpenRepository(path string) (*git.Repository, error) { - return git.OpenRepositoryExtended(path, git.RepositoryOpenFromEnv, "") -} diff --git a/cmd/gitaly-git2go/git2goutil/sign.go b/cmd/gitaly-git2go/git2goutil/sign.go deleted file mode 100644 index efa8d1b1d..000000000 --- a/cmd/gitaly-git2go/git2goutil/sign.go +++ /dev/null @@ -1,22 +0,0 @@ -package git2goutil - -import ( - "fmt" - - "gitlab.com/gitlab-org/gitaly/v16/internal/signature" -) - -// CreateCommitSignature reads the given signing key and produces PKCS#7 detached signature. -// When the path to the signing key is not present, an empty signature is returned. -func CreateCommitSignature(signingKeyPath string, contentToSign []byte) ([]byte, error) { - if signingKeyPath == "" { - return nil, nil - } - - signingKeys, err := signature.ParseSigningKeys(signingKeyPath) - if err != nil { - return nil, fmt.Errorf("failed to parse signing key: %w", err) - } - - return signingKeys.CreateSignature(contentToSign) -} diff --git a/cmd/gitaly-git2go/main.go b/cmd/gitaly-git2go/main.go deleted file mode 100644 index 9c5c4009e..000000000 --- a/cmd/gitaly-git2go/main.go +++ /dev/null @@ -1,165 +0,0 @@ -//go:build static && system_libgit2 - -package main - -import ( - "context" - "encoding/gob" - "flag" - "fmt" - "os" - "strings" - - "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus" - git "github.com/libgit2/git2go/v34" - "github.com/sirupsen/logrus" - "gitlab.com/gitlab-org/gitaly/v16/internal/featureflag" - "gitlab.com/gitlab-org/gitaly/v16/internal/git2go" - glog "gitlab.com/gitlab-org/gitaly/v16/internal/log" - "gitlab.com/gitlab-org/labkit/correlation" -) - -type subcmd interface { - Flags() *flag.FlagSet - Run(ctx context.Context, decoder *gob.Decoder, encoder *gob.Encoder) error -} - -var subcommands = map[string]subcmd{ - "rebase": &rebaseSubcommand{}, -} - -func fatalf(logger logrus.FieldLogger, encoder *gob.Encoder, format string, args ...interface{}) { - err := encoder.Encode(git2go.Result{ - Err: git2go.SerializableError(fmt.Errorf(format, args...)), - }) - if err != nil { - logger.WithError(err).Error("encode to gob failed") - } - // An exit code of 1 would indicate an error over stderr. Since our errors - // are encoded over gob, we need to exit cleanly - os.Exit(0) -} - -func main() { - decoder := gob.NewDecoder(os.Stdin) - encoder := gob.NewEncoder(os.Stdout) - - var logFormat, logLevel, correlationID string - var enabledFeatureFlags, disabledFeatureFlags featureFlagArg - - flags := flag.NewFlagSet(git2go.BinaryName, flag.PanicOnError) - flags.StringVar(&logFormat, "log-format", "", "logging format") - flags.StringVar(&logLevel, "log-level", "", "logging level") - flags.StringVar(&correlationID, "correlation-id", "", "correlation ID used for request tracing") - flags.Var( - &enabledFeatureFlags, - "enabled-feature-flags", - "comma separated list of explicitly enabled feature flags", - ) - flags.Var( - &disabledFeatureFlags, - "disabled-feature-flags", - "comma separated list of explicitly disabled feature flags", - ) - _ = flags.Parse(os.Args[1:]) - - if correlationID == "" { - correlationID = correlation.SafeRandomID() - } - - ctx := correlation.ContextWithCorrelation(context.Background(), correlationID) - - logger, err := glog.Configure(os.Stderr, logFormat, logLevel) - if err != nil { - fmt.Printf("configuring logger failed: %v", err) - os.Exit(1) - } - - logger = logger.WithFields(logrus.Fields{ - "command.name": git2go.BinaryName, - "correlation_id": correlationID, - "enabled_feature_flags": enabledFeatureFlags, - "disabled_feature_flags": disabledFeatureFlags, - }) - - if flags.NArg() < 1 { - fatalf(logger, encoder, "missing subcommand") - } - - subcmd, ok := subcommands[flags.Arg(0)] - if !ok { - fatalf(logger, encoder, "unknown subcommand: %q", flags.Arg(0)) - } - - subcmdFlags := subcmd.Flags() - if err := subcmdFlags.Parse(flags.Args()[1:]); err != nil { - fatalf(logger, encoder, "parsing flags of %q: %s", subcmdFlags.Name(), err) - } - - if subcmdFlags.NArg() != 0 { - fatalf(logger, encoder, "%s: trailing arguments", subcmdFlags.Name()) - } - - if err := git.EnableFsyncGitDir(true); err != nil { - fatalf(logger, encoder, "enable fsync: %s", err) - } - - for _, configLevel := range []git.ConfigLevel{ - git.ConfigLevelSystem, - git.ConfigLevelXDG, - git.ConfigLevelGlobal, - } { - if err := git.SetSearchPath(configLevel, "/dev/null"); err != nil { - fatalf(logger, encoder, "setting search path: %s", err) - } - } - - subcmdLogger := logger.WithField("command.subcommand", subcmdFlags.Name()) - subcmdLogger.Infof("starting %s command", subcmdFlags.Name()) - - ctx = ctxlogrus.ToContext(ctx, subcmdLogger) - ctx = enabledFeatureFlags.ToContext(ctx, true) - ctx = disabledFeatureFlags.ToContext(ctx, false) - - if err := subcmd.Run(ctx, decoder, encoder); err != nil { - subcmdLogger.WithError(err).Errorf("%s command failed", subcmdFlags.Name()) - fatalf(logger, encoder, "%s: %s", subcmdFlags.Name(), err) - } - - subcmdLogger.Infof("%s command finished", subcmdFlags.Name()) -} - -type featureFlagArg []featureflag.FeatureFlag - -func (v *featureFlagArg) String() string { - metadataKeys := make([]string, 0, len(*v)) - for _, flag := range *v { - metadataKeys = append(metadataKeys, flag.MetadataKey()) - } - return strings.Join(metadataKeys, ",") -} - -func (v *featureFlagArg) Set(s string) error { - if s == "" { - return nil - } - - for _, metadataKey := range strings.Split(s, ",") { - flag, err := featureflag.FromMetadataKey(metadataKey) - if err != nil { - return err - } - - *v = append(*v, flag) - } - - return nil -} - -func (v featureFlagArg) ToContext(ctx context.Context, enabled bool) context.Context { - for _, flag := range v { - ctx = featureflag.IncomingCtxWithFeatureFlag(ctx, flag, enabled) - } - - return ctx -} diff --git a/cmd/gitaly-git2go/merge.go b/cmd/gitaly-git2go/merge.go deleted file mode 100644 index 92f0f53fb..000000000 --- a/cmd/gitaly-git2go/merge.go +++ /dev/null @@ -1,57 +0,0 @@ -//go:build static && system_libgit2 - -package main - -import ( - "errors" - "fmt" - - git "github.com/libgit2/git2go/v34" -) - -func getConflictingFiles(index *git.Index) ([]string, error) { - conflicts, err := getConflicts(index) - if err != nil { - return nil, fmt.Errorf("getting conflicts: %w", err) - } - - conflictingFiles := make([]string, 0, len(conflicts)) - for _, conflict := range conflicts { - switch { - case conflict.Our != nil: - conflictingFiles = append(conflictingFiles, conflict.Our.Path) - case conflict.Ancestor != nil: - conflictingFiles = append(conflictingFiles, conflict.Ancestor.Path) - case conflict.Their != nil: - conflictingFiles = append(conflictingFiles, conflict.Their.Path) - default: - return nil, errors.New("invalid conflict") - } - } - - return conflictingFiles, nil -} - -func getConflicts(index *git.Index) ([]git.IndexConflict, error) { - var conflicts []git.IndexConflict - - iterator, err := index.ConflictIterator() - if err != nil { - return nil, err - } - defer iterator.Free() - - for { - conflict, err := iterator.Next() - if err != nil { - if git.IsErrorCode(err, git.ErrorCodeIterOver) { - break - } - return nil, err - } - - conflicts = append(conflicts, conflict) - } - - return conflicts, nil -} diff --git a/cmd/gitaly-git2go/rebase.go b/cmd/gitaly-git2go/rebase.go deleted file mode 100644 index cf221007f..000000000 --- a/cmd/gitaly-git2go/rebase.go +++ /dev/null @@ -1,192 +0,0 @@ -//go:build static && system_libgit2 - -package main - -import ( - "context" - "encoding/gob" - "errors" - "flag" - "fmt" - - git "github.com/libgit2/git2go/v34" - "gitlab.com/gitlab-org/gitaly/v16/cmd/gitaly-git2go/git2goutil" - "gitlab.com/gitlab-org/gitaly/v16/internal/git2go" -) - -type rebaseSubcommand struct{} - -func (cmd *rebaseSubcommand) Flags() *flag.FlagSet { - return flag.NewFlagSet("rebase", flag.ExitOnError) -} - -func (cmd *rebaseSubcommand) Run(ctx context.Context, decoder *gob.Decoder, encoder *gob.Encoder) error { - var request git2go.RebaseCommand - if err := decoder.Decode(&request); err != nil { - return err - } - - commitID, err := cmd.rebase(ctx, &request) - return encoder.Encode(git2go.Result{ - CommitID: commitID, - Err: git2go.SerializableError(err), - }) -} - -func (cmd *rebaseSubcommand) verify(ctx context.Context, r *git2go.RebaseCommand) error { - if r.Repository == "" { - return errors.New("missing repository") - } - if r.Committer.Name == "" { - return errors.New("missing committer name") - } - if r.Committer.Email == "" { - return errors.New("missing committer email") - } - if r.BranchName == "" && r.CommitID == "" { - return errors.New("missing branch name") - } - if r.BranchName != "" && r.CommitID != "" { - return errors.New("both branch name and commit ID") - } - if r.UpstreamRevision == "" && r.UpstreamCommitID == "" { - return errors.New("missing upstream revision") - } - if r.UpstreamRevision != "" && r.UpstreamCommitID != "" { - return errors.New("both upstream revision and upstream commit ID") - } - return nil -} - -func (cmd *rebaseSubcommand) rebase(ctx context.Context, request *git2go.RebaseCommand) (string, error) { - if err := cmd.verify(ctx, request); err != nil { - return "", err - } - - repo, err := git2goutil.OpenRepository(request.Repository) - if err != nil { - return "", fmt.Errorf("open repository: %w", err) - } - - opts, err := git.DefaultRebaseOptions() - if err != nil { - return "", fmt.Errorf("get rebase options: %w", err) - } - opts.InMemory = 1 - opts.CommitCreateCallback = git2goutil.NewCommitSubmitter(repo, request.SigningKey).Commit - - var commit *git.AnnotatedCommit - if request.BranchName != "" { - commit, err = repo.AnnotatedCommitFromRevspec(fmt.Sprintf("refs/heads/%s", request.BranchName)) - if err != nil { - return "", fmt.Errorf("look up branch %q: %w", request.BranchName, err) - } - } else { - commitOid, err := git.NewOid(request.CommitID.String()) - if err != nil { - return "", fmt.Errorf("parse commit %q: %w", request.CommitID, err) - } - - commit, err = repo.LookupAnnotatedCommit(commitOid) - if err != nil { - return "", fmt.Errorf("look up commit %q: %w", request.CommitID, err) - } - } - - upstreamCommitParam := request.UpstreamRevision - if upstreamCommitParam == "" { - upstreamCommitParam = request.UpstreamCommitID.String() - } - - upstreamCommitOID, err := git.NewOid(upstreamCommitParam) - if err != nil { - return "", fmt.Errorf("parse upstream revision %q: %w", upstreamCommitParam, err) - } - - upstreamCommit, err := repo.LookupAnnotatedCommit(upstreamCommitOID) - if err != nil { - return "", fmt.Errorf("look up upstream revision %q: %w", upstreamCommitParam, err) - } - - mergeBase, err := repo.MergeBase(upstreamCommit.Id(), commit.Id()) - if err != nil { - return "", fmt.Errorf("find merge base: %w", err) - } - - if mergeBase.Equal(upstreamCommit.Id()) { - // Branch is zero commits behind, so do not rebase - return commit.Id().String(), nil - } - - if mergeBase.Equal(commit.Id()) { - // Branch is merged, so fast-forward to upstream - return upstreamCommit.Id().String(), nil - } - - mergeCommit, err := repo.LookupAnnotatedCommit(mergeBase) - if err != nil { - return "", fmt.Errorf("look up merge base: %w", err) - } - - rebase, err := repo.InitRebase(commit, mergeCommit, upstreamCommit, &opts) - if err != nil { - return "", fmt.Errorf("initiate rebase: %w", err) - } - - committer := git.Signature(request.Committer) - var oid *git.Oid - for { - op, err := rebase.Next() - if git.IsErrorCode(err, git.ErrorCodeIterOver) { - break - } else if err != nil { - return "", fmt.Errorf("rebase iterate: %w", err) - } - - commit, err := repo.LookupCommit(op.Id) - if err != nil { - return "", fmt.Errorf("lookup commit: %w", err) - } - - if err := rebase.Commit(op.Id, nil, &committer, commit.Message()); err != nil { - if git.IsErrorCode(err, git.ErrorCodeUnmerged) { - index, err := rebase.InmemoryIndex() - if err != nil { - return "", fmt.Errorf("getting conflicting index: %w", err) - } - - conflictingFiles, err := getConflictingFiles(index) - if err != nil { - return "", fmt.Errorf("getting conflicting files: %w", err) - } - - return "", fmt.Errorf("commit %q: %w", op.Id.String(), git2go.ConflictingFilesError{ - ConflictingFiles: conflictingFiles, - }) - } - - // If the commit has already been applied on the target branch then we can - // skip it if we were told to. - if request.SkipEmptyCommits && git.IsErrorCode(err, git.ErrorCodeApplied) { - continue - } - - return "", fmt.Errorf("commit %q: %w", op.Id.String(), err) - } - - oid = op.Id.Copy() - } - - // When the OID is unset here, then we didn't have to rebase any commits at all. We can - // thus return the upstream commit directly: rebasing nothing onto the upstream commit is - // the same as the upstream commit itself. - if oid == nil { - return upstreamCommit.Id().String(), nil - } - - if err = rebase.Finish(); err != nil { - return "", fmt.Errorf("finish rebase: %w", err) - } - - return oid.String(), nil -} diff --git a/cmd/gitaly-git2go/rebase_test.go b/cmd/gitaly-git2go/rebase_test.go deleted file mode 100644 index 6de901e32..000000000 --- a/cmd/gitaly-git2go/rebase_test.go +++ /dev/null @@ -1,423 +0,0 @@ -//go:build static && system_libgit2 - -package main - -import ( - "fmt" - "testing" - "time" - - "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v16/cmd/gitaly-git2go/git2goutil" - "gitlab.com/gitlab-org/gitaly/v16/internal/git" - "gitlab.com/gitlab-org/gitaly/v16/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v16/internal/git2go" - "gitlab.com/gitlab-org/gitaly/v16/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v16/internal/testhelper/testcfg" -) - -var masterRevision = "1e292f8fedd741b75372e19097c76d327140c312" - -func TestRebase_validation(t *testing.T) { - gittest.SkipWithSHA256(t) - - ctx := testhelper.Context(t) - cfg := testcfg.Build(t) - - testcfg.BuildGitalyGit2Go(t, cfg) - - repo, repoPath := gittest.CreateRepository(t, ctx, cfg, gittest.CreateRepositoryConfig{ - SkipCreationViaService: true, - }) - - committer := git2go.NewSignature("Foo", "foo@example.com", time.Now()) - executor := buildExecutor(t, cfg) - - testcases := []struct { - desc string - request git2go.RebaseCommand - expectedErr string - }{ - { - desc: "no arguments", - expectedErr: "rebase: missing repository", - }, - { - desc: "missing repository", - request: git2go.RebaseCommand{Committer: committer, BranchName: "feature", UpstreamRevision: masterRevision}, - expectedErr: "rebase: missing repository", - }, - { - desc: "missing committer name", - request: git2go.RebaseCommand{Repository: repoPath, Committer: git2go.Signature{Email: "foo@example.com"}, BranchName: "feature", UpstreamRevision: masterRevision}, - expectedErr: "rebase: missing committer name", - }, - { - desc: "missing committer email", - request: git2go.RebaseCommand{Repository: repoPath, Committer: git2go.Signature{Name: "Foo"}, BranchName: "feature", UpstreamRevision: masterRevision}, - expectedErr: "rebase: missing committer email", - }, - { - desc: "missing branch name", - request: git2go.RebaseCommand{Repository: repoPath, Committer: committer, UpstreamRevision: masterRevision}, - expectedErr: "rebase: missing branch name", - }, - { - desc: "missing upstream branch", - request: git2go.RebaseCommand{Repository: repoPath, Committer: committer, BranchName: "feature"}, - expectedErr: "rebase: missing upstream revision", - }, - { - desc: "both branch name and commit ID", - request: git2go.RebaseCommand{Repository: repoPath, Committer: committer, BranchName: "feature", CommitID: "a"}, - expectedErr: "rebase: both branch name and commit ID", - }, - { - desc: "both upstream revision and upstream commit ID", - request: git2go.RebaseCommand{Repository: repoPath, Committer: committer, BranchName: "feature", UpstreamRevision: "a", UpstreamCommitID: "a"}, - expectedErr: "rebase: both upstream revision and upstream commit ID", - }, - } - for _, tc := range testcases { - t.Run(tc.desc, func(t *testing.T) { - _, err := executor.Rebase(ctx, repo, tc.request) - require.EqualError(t, err, tc.expectedErr) - }) - } -} - -func TestRebase_rebase(t *testing.T) { - gittest.SkipWithSHA256(t) - - t.Parallel() - - ctx := testhelper.Context(t) - cfg := testcfg.Build(t) - testcfg.BuildGitalyGit2Go(t, cfg) - executor := buildExecutor(t, cfg) - - committer := git2go.NewSignature( - string(gittest.TestUser.Name), - string(gittest.TestUser.Email), - time.Date(2021, 3, 1, 13, 45, 50, 0, time.FixedZone("", +2*60*60)), - ) - - type setup struct { - base, upstream, downstream git.ObjectID - expecetedCommitsAhead int - expectedObjectID git.ObjectID - expectedErr string - } - - testcases := []struct { - desc string - setup func(testing.TB, string) setup - }{ - { - desc: "Single commit rebase", - setup: func(tb testing.TB, repoPath string) setup { - base := gittest.WriteCommit(t, cfg, repoPath, gittest.WithTreeEntries( - gittest.TreeEntry{Path: "path", Mode: "100644", Content: "a\nb\nc\nd\ne\nf\ng\n"}, - )) - upstream := gittest.WriteCommit(t, cfg, repoPath, gittest.WithMessage("upstream"), gittest.WithParents(base), gittest.WithTreeEntries( - gittest.TreeEntry{Path: "path", Mode: "100644", Content: "upstream\nb\nc\nd\ne\nf\ng\n"}, - )) - downstream := gittest.WriteCommit(t, cfg, repoPath, gittest.WithMessage("downstream"), gittest.WithParents(base), gittest.WithTreeEntries( - gittest.TreeEntry{Path: "path", Mode: "100644", Content: "a\nb\nc\nd\ne\nf\ndownstream\n"}, - )) - - return setup{ - base: base, - upstream: upstream, - downstream: downstream, - expectedObjectID: "ef018adb419cd97453a0624c28271fafe622b83e", - expecetedCommitsAhead: 1, - } - }, - }, - { - desc: "Multiple commits", - setup: func(tb testing.TB, repoPath string) setup { - base := gittest.WriteCommit(t, cfg, repoPath, gittest.WithTreeEntries( - gittest.TreeEntry{Path: "path", Mode: "100644", Content: "a\nb\nc\nd\ne\nf\ng\n"}, - )) - upstream := gittest.WriteCommit(t, cfg, repoPath, gittest.WithMessage("upstream"), gittest.WithParents(base), gittest.WithTreeEntries( - gittest.TreeEntry{Path: "path", Mode: "100644", Content: "upstream\nb\nc\nd\ne\nf\ng\n"}, - )) - downstream1 := gittest.WriteCommit(t, cfg, repoPath, gittest.WithMessage("downstream-1"), gittest.WithParents(base), gittest.WithTreeEntries( - gittest.TreeEntry{Path: "path", Mode: "100644", Content: "a\nb\nc\nd\ne\nf\ndownstream-1\n"}, - )) - downstream2 := gittest.WriteCommit(t, cfg, repoPath, gittest.WithMessage("downstream-2"), gittest.WithParents(downstream1), gittest.WithTreeEntries( - gittest.TreeEntry{Path: "path", Mode: "100644", Content: "a\nb\nc\nd\ne\nf\ndownstream-2\n"}, - )) - downstream3 := gittest.WriteCommit(t, cfg, repoPath, gittest.WithMessage("downstream-3"), gittest.WithParents(downstream2), gittest.WithTreeEntries( - gittest.TreeEntry{Path: "path", Mode: "100644", Content: "a\nb\nc\nd\ne\nf\ndownstream-3\n"}, - )) - - return setup{ - base: base, - upstream: upstream, - downstream: downstream3, - expectedObjectID: "d3c737fdb3a0c4da3a371fc01de6df4cbb5bc3e4", - expecetedCommitsAhead: 3, - } - }, - }, - { - desc: "Branch zero commits behind", - setup: func(tb testing.TB, repoPath string) setup { - base := gittest.WriteCommit(t, cfg, repoPath, gittest.WithTreeEntries( - gittest.TreeEntry{Path: "path", Mode: "100644", Content: "a\nb\nc\nd\ne\nf\ng\n"}, - )) - downstream := gittest.WriteCommit(t, cfg, repoPath, gittest.WithMessage("downstream"), gittest.WithParents(base), gittest.WithTreeEntries( - gittest.TreeEntry{Path: "path", Mode: "100644", Content: "a\nb\nc\nd\ne\nf\ndownstream\n"}, - )) - - return setup{ - base: base, - upstream: base, - downstream: downstream, - expectedObjectID: downstream, - expecetedCommitsAhead: 1, - } - }, - }, - { - desc: "Merged branch", - setup: func(tb testing.TB, repoPath string) setup { - base := gittest.WriteCommit(t, cfg, repoPath, gittest.WithTreeEntries( - gittest.TreeEntry{Path: "path", Mode: "100644", Content: "a\nb\nc\nd\ne\nf\ng\n"}, - )) - downstream := gittest.WriteCommit(t, cfg, repoPath, gittest.WithParents(base), gittest.WithTreeEntries( - gittest.TreeEntry{Path: "path", Mode: "100644", Content: "a\nb\nc\nd\ne\nf\ndownstream\n"}, - )) - merge := gittest.WriteCommit(t, cfg, repoPath, gittest.WithParents(base, downstream), gittest.WithTreeEntries( - gittest.TreeEntry{Path: "path", Mode: "100644", Content: "a\nb\nc\nd\ne\nf\ndownstream\n"}, - )) - - return setup{ - base: base, upstream: merge, downstream: downstream, - expectedObjectID: merge, - } - }, - }, - { - desc: "Partially merged branch", - setup: func(tb testing.TB, repoPath string) setup { - base := gittest.WriteCommit(t, cfg, repoPath, gittest.WithTreeEntries( - gittest.TreeEntry{Path: "path", Mode: "100644", Content: "a\nb\nc\nd\ne\nf\ng\n"}, - )) - downstream1 := gittest.WriteCommit(t, cfg, repoPath, gittest.WithParents(base), gittest.WithTreeEntries( - gittest.TreeEntry{Path: "path", Mode: "100644", Content: "a\nb\nc\nd\ne\nf\ndownstream-1\n"}, - )) - downstream2 := gittest.WriteCommit(t, cfg, repoPath, gittest.WithParents(downstream1), gittest.WithTreeEntries( - gittest.TreeEntry{Path: "path", Mode: "100644", Content: "a\nb\nc\nd\ne\nf\ndownstream-2\n"}, - )) - merge := gittest.WriteCommit(t, cfg, repoPath, gittest.WithParents(base, downstream1), gittest.WithTreeEntries( - gittest.TreeEntry{Path: "path", Mode: "100644", Content: "a\nb\nc\nd\ne\nf\ndownstream-1\n"}, - )) - - return setup{ - base: base, - upstream: merge, - downstream: downstream2, - expectedObjectID: "721e8bd36a394a7cc243b8c3960b44c5520c6246", - expecetedCommitsAhead: 1, - } - }, - }, - { - desc: "With upstream merged into", - setup: func(tb testing.TB, repoPath string) setup { - base := gittest.WriteCommit(t, cfg, repoPath, gittest.WithTreeEntries( - gittest.TreeEntry{Path: "path", Mode: "100644", Content: "a\nb\nc\nd\ne\nf\ng\n"}, - )) - upstream := gittest.WriteCommit(t, cfg, repoPath, gittest.WithMessage("upstream"), gittest.WithParents(base), gittest.WithTreeEntries( - gittest.TreeEntry{Path: "path", Mode: "100644", Content: "upstream\nb\nc\nd\ne\nf\ng\n"}, - )) - downstream := gittest.WriteCommit(t, cfg, repoPath, gittest.WithMessage("downstream"), gittest.WithParents(base), gittest.WithTreeEntries( - gittest.TreeEntry{Path: "path", Mode: "100644", Content: "a\nb\nc\nd\ne\nf\ndownstream\n"}, - )) - downstreamMerge := gittest.WriteCommit(t, cfg, repoPath, gittest.WithParents(downstream, upstream), gittest.WithTreeEntries( - gittest.TreeEntry{Path: "path", Mode: "100644", Content: "upstream\nb\nc\nd\ne\nf\ndownstream\n"}, - )) - - return setup{ - base: base, - upstream: upstream, - downstream: downstreamMerge, - expectedObjectID: "aa375bc059fa8830d9489d89af1278632722407d", - expecetedCommitsAhead: 2, - } - }, - }, - { - desc: "Rebase with conflict", - setup: func(tb testing.TB, repoPath string) setup { - base := gittest.WriteCommit(t, cfg, repoPath, gittest.WithTreeEntries( - gittest.TreeEntry{Path: "path", Mode: "100644", Content: "base\n"}, - )) - upstream := gittest.WriteCommit(t, cfg, repoPath, gittest.WithParents(base), gittest.WithTreeEntries( - gittest.TreeEntry{Path: "path", Mode: "100644", Content: "upstream\n"}, - )) - downstream := gittest.WriteCommit(t, cfg, repoPath, gittest.WithParents(base), gittest.WithTreeEntries( - gittest.TreeEntry{Path: "path", Mode: "100644", Content: "downstream\n"}, - )) - - return setup{ - upstream: upstream, - downstream: downstream, - expectedErr: fmt.Sprintf("rebase: commit %q: there are conflicting files", downstream), - } - }, - }, - { - desc: "Orphaned branch", - setup: func(tb testing.TB, repoPath string) setup { - upstream := gittest.WriteCommit(t, cfg, repoPath, gittest.WithTreeEntries( - gittest.TreeEntry{Path: "path", Mode: "100644", Content: "upstream\n"}, - )) - downstream := gittest.WriteCommit(t, cfg, repoPath, gittest.WithTreeEntries( - gittest.TreeEntry{Path: "path", Mode: "100644", Content: "downstream\n"}, - )) - - return setup{ - upstream: upstream, - downstream: downstream, - expectedErr: "rebase: find merge base: no merge base found", - } - }, - }, - } - - for _, tc := range testcases { - tc := tc - - t.Run(tc.desc, func(t *testing.T) { - t.Parallel() - - repoProto, repoPath := gittest.CreateRepository(t, ctx, cfg, gittest.CreateRepositoryConfig{ - SkipCreationViaService: true, - }) - setup := tc.setup(t, repoPath) - - gittest.WriteRef(t, cfg, repoPath, "refs/heads/upstream", setup.upstream) - gittest.WriteRef(t, cfg, repoPath, "refs/heads/downstream", setup.downstream) - - repo, err := git2goutil.OpenRepository(repoPath) - require.NoError(t, err) - - for desc, request := range map[string]git2go.RebaseCommand{ - "with branch and upstream": { - Repository: repoPath, - Committer: committer, - BranchName: "downstream", - UpstreamRevision: setup.upstream.String(), - }, - "with branch and upstream commit ID": { - Repository: repoPath, - Committer: committer, - BranchName: "downstream", - UpstreamCommitID: setup.upstream, - }, - "with commit ID and upstream": { - Repository: repoPath, - Committer: committer, - CommitID: setup.downstream, - UpstreamRevision: setup.upstream.String(), - }, - "with commit ID and upstream commit ID": { - Repository: repoPath, - Committer: committer, - CommitID: setup.downstream, - UpstreamCommitID: setup.upstream, - }, - } { - t.Run(desc, func(t *testing.T) { - response, err := executor.Rebase(ctx, repoProto, request) - if setup.expectedErr != "" { - require.EqualError(t, err, setup.expectedErr) - } else { - require.NoError(t, err) - require.Equal(t, setup.expectedObjectID, response) - - commit, err := lookupCommit(repo, response.String()) - require.NoError(t, err) - - for i := setup.expecetedCommitsAhead; i > 0; i-- { - commit = commit.Parent(0) - } - baseCommit, err := lookupCommit(repo, setup.base.String()) - require.NoError(t, err) - require.Equal(t, baseCommit, commit) - } - }) - } - }) - } -} - -func TestRebase_skipEmptyCommit(t *testing.T) { - gittest.SkipWithSHA256(t) - - ctx := testhelper.Context(t) - cfg := testcfg.Build(t) - - testcfg.BuildGitalyGit2Go(t, cfg) - - repoProto, repoPath := gittest.CreateRepository(t, ctx, cfg, gittest.CreateRepositoryConfig{ - SkipCreationViaService: true, - }) - - // Set up history with two diverging lines of branches, where both sides have implemented - // the same changes. During rebase, the diff will thus become empty. - base := gittest.WriteCommit(t, cfg, repoPath, - gittest.WithTreeEntries(gittest.TreeEntry{ - Path: "a", Content: "base", Mode: "100644", - }), - ) - theirs := gittest.WriteCommit(t, cfg, repoPath, gittest.WithMessage("theirs"), - gittest.WithParents(base), gittest.WithTreeEntries(gittest.TreeEntry{ - Path: "a", Content: "changed", Mode: "100644", - }), - ) - ours := gittest.WriteCommit(t, cfg, repoPath, gittest.WithMessage("ours"), - gittest.WithParents(base), gittest.WithTreeEntries(gittest.TreeEntry{ - Path: "a", Content: "changed", Mode: "100644", - }), - ) - - for _, tc := range []struct { - desc string - skipEmptyCommits bool - expectedErr string - expectedResponse git.ObjectID - }{ - { - desc: "do not skip empty commit", - skipEmptyCommits: false, - expectedErr: fmt.Sprintf("rebase: commit %q: this patch has already been applied", ours), - }, - { - desc: "skip empty commit", - skipEmptyCommits: true, - expectedResponse: theirs, - }, - } { - t.Run(tc.desc, func(t *testing.T) { - response, err := buildExecutor(t, cfg).Rebase(ctx, repoProto, git2go.RebaseCommand{ - Repository: repoPath, - Committer: git2go.NewSignature("Foo", "foo@example.com", time.Now()), - CommitID: ours, - UpstreamCommitID: theirs, - SkipEmptyCommits: tc.skipEmptyCommits, - }) - if tc.expectedErr == "" { - require.NoError(t, err) - } else { - require.EqualError(t, err, tc.expectedErr) - } - require.Equal(t, tc.expectedResponse, response) - }) - } -} diff --git a/cmd/gitaly-git2go/testhelper_test.go b/cmd/gitaly-git2go/testhelper_test.go deleted file mode 100644 index 0d72bec57..000000000 --- a/cmd/gitaly-git2go/testhelper_test.go +++ /dev/null @@ -1,44 +0,0 @@ -//go:build static && system_libgit2 - -package main - -import ( - "fmt" - "testing" - - git "github.com/libgit2/git2go/v34" - "gitlab.com/gitlab-org/gitaly/v16/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v16/internal/git2go" - "gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v16/internal/testhelper" -) - -// DefaultAuthor is the author used by BuildCommit -var DefaultAuthor = git.Signature{ - Name: gittest.DefaultCommitterName, - Email: gittest.DefaultCommitterMail, - When: gittest.DefaultCommitTime, -} - -func TestMain(m *testing.M) { - testhelper.Run(m, testhelper.WithSetup(func() error { - // We use Git2go to access repositories in our tests, so we must tell it to ignore - // any configuration files that happen to exist. We do the same in `main()`, so - // this is not only specific to tests. - for _, configLevel := range []git.ConfigLevel{ - git.ConfigLevelSystem, - git.ConfigLevelXDG, - git.ConfigLevelGlobal, - } { - if err := git.SetSearchPath(configLevel, "/dev/null"); err != nil { - return fmt.Errorf("setting Git2go search path: %w", err) - } - } - - return nil - })) -} - -func buildExecutor(tb testing.TB, cfg config.Cfg) *git2go.Executor { - return git2go.NewExecutor(cfg, gittest.NewCommandFactory(tb, cfg), config.NewLocator(cfg), testhelper.SharedLogger(tb)) -} diff --git a/cmd/gitaly-git2go/util.go b/cmd/gitaly-git2go/util.go deleted file mode 100644 index c76b9370c..000000000 --- a/cmd/gitaly-git2go/util.go +++ /dev/null @@ -1,32 +0,0 @@ -//go:build static && system_libgit2 - -package main - -import ( - "fmt" - - git "github.com/libgit2/git2go/v34" - "gitlab.com/gitlab-org/gitaly/v16/internal/git2go" -) - -func lookupCommit(repo *git.Repository, ref string) (*git.Commit, error) { - object, err := repo.RevparseSingle(ref) - switch { - case git.IsErrorCode(err, git.ErrorCodeNotFound): - return nil, git2go.CommitNotFoundError{Revision: ref} - case err != nil: - return nil, fmt.Errorf("lookup commit %q: %w", ref, err) - } - - peeled, err := object.Peel(git.ObjectCommit) - if err != nil { - return nil, fmt.Errorf("lookup commit %q: peel: %w", ref, err) - } - - commit, err := peeled.AsCommit() - if err != nil { - return nil, fmt.Errorf("lookup commit %q: as commit: %w", ref, err) - } - - return commit, nil -} diff --git a/doc/serverside_git_usage.md b/doc/serverside_git_usage.md index 889dc0035..c6d0faa70 100644 --- a/doc/serverside_git_usage.md +++ b/doc/serverside_git_usage.md @@ -39,10 +39,3 @@ interfaces. These make sure Gitaly is protected against command injection, the correct `git` is used, and correct setup for observable command invocations are used. When working with `git(1)` in Ruby, please be sure to read the [Ruby shell scripting guide](https://docs.gitlab.com/ee/development/shell_commands.html). - -## Using LibGit2 - -Gitaly uses [Git2Go](https://github.com/libgit2/git2go) for Golang, and -[Rugged](https://github.com/libgit2/rugged) which both are thin adapters to call -the C functions of LibGit2. Git2Go is always invoked through `cmd/gitaly-git2go` -to mitigate issues with context cancellation and the potential for memory leaks. @@ -24,7 +24,6 @@ require ( github.com/hashicorp/yamux v0.1.1 github.com/jackc/pgx/v5 v5.4.3 github.com/kelseyhightower/envconfig v1.4.0 - github.com/libgit2/git2go/v34 v34.0.0 github.com/miekg/dns v1.1.55 github.com/olekukonko/tablewriter v0.0.5 github.com/opencontainers/runtime-spec v1.1.0 @@ -365,8 +365,6 @@ github.com/google/pprof v0.0.0-20230705174524-200ffdc848b8/go.mod h1:Jh3hGz2jkYa github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/s2a-go v0.1.4 h1:1kZ/sQM3srePvKs3tXAvQzo66XfcReoqFpIpIccE7Oc= github.com/google/s2a-go v0.1.4/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkjEwM0A= -github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= -github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= github.com/google/subcommands v1.0.1/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= @@ -458,8 +456,6 @@ github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+ github.com/leonelquinteros/gotext v1.5.0 h1:ODY7LzLpZWWSJdAHnzhreOr6cwLXTAmc914FOauSkBM= github.com/leonelquinteros/gotext v1.5.0/go.mod h1:OCiUVHuhP9LGFBQ1oAmdtNCHJCiHiQA8lf4nAifHkr0= github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= -github.com/libgit2/git2go/v34 v34.0.0 h1:UKoUaKLmiCRbOCD3PtUi2hD6hESSXzME/9OUZrGcgu8= -github.com/libgit2/git2go/v34 v34.0.0/go.mod h1:blVco2jDAw6YTXkErMMqzHLcAjKkwF0aWIRHBqiJkZ0= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20210210170715-a8dfcb80d3a7 h1:YjW+hUb8Fh2S58z4av4t/0cBMK/Q0aP48RocCFsC8yI= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20210210170715-a8dfcb80d3a7/go.mod h1:Spd59icnvRxSKuyijbbwe5AemzvcyXAUBgApa7VybMw= github.com/lightstep/lightstep-tracer-go v0.25.0 h1:sGVnz8h3jTQuHKMbUe2949nXm3Sg09N1UcR3VoQNN5E= @@ -635,7 +631,6 @@ golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201112155050-0c6587e931a9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= @@ -838,7 +833,6 @@ golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= diff --git a/internal/git2go/executor.go b/internal/git2go/executor.go deleted file mode 100644 index f5cca8252..000000000 --- a/internal/git2go/executor.go +++ /dev/null @@ -1,142 +0,0 @@ -package git2go - -import ( - "bytes" - "context" - "encoding/gob" - "errors" - "fmt" - "io" - "strings" - - "github.com/sirupsen/logrus" - "gitlab.com/gitlab-org/gitaly/v16/internal/command" - "gitlab.com/gitlab-org/gitaly/v16/internal/featureflag" - "gitlab.com/gitlab-org/gitaly/v16/internal/git" - "gitlab.com/gitlab-org/gitaly/v16/internal/git/alternates" - "gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/storage" - "gitlab.com/gitlab-org/labkit/correlation" -) - -var ( - // ErrInvalidArgument is returned in case the merge arguments are invalid. - ErrInvalidArgument = errors.New("invalid parameters") - - // BinaryName is the name of the gitaly-git2go binary. - BinaryName = "gitaly-git2go" -) - -// Executor executes gitaly-git2go. -type Executor struct { - binaryPath string - signingKey string - gitCmdFactory git.CommandFactory - locator storage.Locator - logger logrus.FieldLogger - logFormat, logLevel string -} - -// NewExecutor returns a new gitaly-git2go executor using binaries as configured in the given -// configuration. -func NewExecutor(cfg config.Cfg, gitCmdFactory git.CommandFactory, locator storage.Locator, logger logrus.FieldLogger) *Executor { - return &Executor{ - binaryPath: cfg.BinaryPath(BinaryName), - signingKey: cfg.Git.SigningKey, - gitCmdFactory: gitCmdFactory, - locator: locator, - logger: logger, - logFormat: cfg.Logging.Format, - logLevel: cfg.Logging.Level, - } -} - -func (b *Executor) run(ctx context.Context, repo storage.Repository, stdin io.Reader, subcmd string, args ...string) (*bytes.Buffer, error) { - repoPath, err := b.locator.GetRepoPath(repo) - if err != nil { - return nil, fmt.Errorf("gitaly-git2go: %w", err) - } - - var enabledFeatureFlags, disabledFeatureFlags []string - - for flag, value := range featureflag.FromContext(ctx) { - switch value { - case true: - enabledFeatureFlags = append(enabledFeatureFlags, flag.MetadataKey()) - case false: - disabledFeatureFlags = append(disabledFeatureFlags, flag.MetadataKey()) - } - } - - env := alternates.Env(repoPath, repo.GetGitObjectDirectory(), repo.GetGitAlternateObjectDirectories()) - env = append(env, b.gitCmdFactory.GetExecutionEnvironment(ctx).EnvironmentVariables...) - - // Construct a log writer that we pass to gitaly-git2go. Note that this is not exactly pretty: the output - // generated by the logger is not going to be parsed, but will be written to the log without any change as log - // message. - // - // Previously, we would have written these messages to `logrus.Logger.Out` directly. But we have refactored our - // code to get rid of the global logger instance, and thus we cannot access that field anymore. Given that the - // git2go executor is going away next release anyway, let's just live with this ugly workaround here. We still - // have visibility into what the process is doing, but with a bit less comfort. That seems like an acceptable - // tradeoff in order to get rid of the global logger altogether. - logWriter := b.logger.WithField("component", "git2go."+subcmd).Writer() - defer logWriter.Close() - - args = append([]string{ - "-log-format", b.logFormat, - "-log-level", b.logLevel, - "-correlation-id", correlation.ExtractFromContext(ctx), - "-enabled-feature-flags", strings.Join(enabledFeatureFlags, ","), - "-disabled-feature-flags", strings.Join(disabledFeatureFlags, ","), - subcmd, - }, args...) - - var stdout bytes.Buffer - cmd, err := command.New(ctx, append([]string{b.binaryPath}, args...), - command.WithStdin(stdin), - command.WithStdout(&stdout), - command.WithStderr(logWriter), - command.WithEnvironment(env), - command.WithCommandName("gitaly-git2go", subcmd), - ) - if err != nil { - return nil, err - } - - if err := cmd.Wait(); err != nil { - return nil, err - } - - return &stdout, nil -} - -// runWithGob runs the specified gitaly-git2go cmd with the request gob-encoded -// as input and returns the commit ID as string or an error. -func (b *Executor) runWithGob(ctx context.Context, repo storage.Repository, cmd string, request interface{}) (git.ObjectID, error) { - input := &bytes.Buffer{} - if err := gob.NewEncoder(input).Encode(request); err != nil { - return "", fmt.Errorf("%s: %w", cmd, err) - } - - output, err := b.run(ctx, repo, input, cmd) - if err != nil { - return "", fmt.Errorf("%s: %w", cmd, err) - } - - var result Result - if err := gob.NewDecoder(output).Decode(&result); err != nil { - return "", fmt.Errorf("%s: %w", cmd, err) - } - - if result.Err != nil { - return "", fmt.Errorf("%s: %w", cmd, result.Err) - } - - commitID, err := git.ObjectHashSHA1.FromHex(result.CommitID) - if err != nil { - return "", fmt.Errorf("could not parse commit ID: %w", err) - } - - return commitID, nil -} diff --git a/internal/git2go/featureflags.go b/internal/git2go/featureflags.go deleted file mode 100644 index bfde6867b..000000000 --- a/internal/git2go/featureflags.go +++ /dev/null @@ -1,22 +0,0 @@ -package git2go - -// FeatureFlag is a feature flag state as seen by the `gitaly-git2go featureflag` test subcommand. -type FeatureFlag struct { - // MetadataKey is the metadata key of the feature flag. - MetadataKey string - // Name is the name of the feature flag. - Name string - // Value is the value of the feature flag. - Value bool -} - -// FeatureFlags is a struct only used by tests to confirm that feature flags are -// being properly propagated from the git2go Executor to the gitaly-git2go -// binary -type FeatureFlags struct { - // Flags is the set of feature flags observed by the command. - Flags []FeatureFlag - // Err is set if an error occurred. Err must exist on all gob serialized - // results so that any error can be returned. - Err error -} diff --git a/internal/git2go/featureflags_test.go b/internal/git2go/featureflags_test.go deleted file mode 100644 index db2a35992..000000000 --- a/internal/git2go/featureflags_test.go +++ /dev/null @@ -1,72 +0,0 @@ -package git2go - -import ( - "context" - "encoding/gob" - "testing" - - "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v16/internal/featureflag" - "gitlab.com/gitlab-org/gitaly/v16/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v16/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/storage" - "gitlab.com/gitlab-org/gitaly/v16/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v16/internal/testhelper/testcfg" -) - -func (b *Executor) FeatureFlags(ctx context.Context, repo storage.Repository) ([]FeatureFlag, error) { - output, err := b.run(ctx, repo, nil, "feature-flags") - if err != nil { - return nil, err - } - - var result FeatureFlags - if err := gob.NewDecoder(output).Decode(&result); err != nil { - return nil, err - } - - if result.Err != nil { - return nil, result.Err - } - - return result.Flags, err -} - -var ( - featureA = featureflag.NewFeatureFlag("feature_a", "", "", false) - featureB = featureflag.NewFeatureFlag("feature_b", "", "", true) -) - -func TestExecutor_explicitFeatureFlags(t *testing.T) { - testhelper.NewFeatureSets(featureA, featureB).Run(t, testExecutorFeatureFlags) -} - -func testExecutorFeatureFlags(t *testing.T, ctx context.Context) { - cfg := testcfg.Build(t) - testcfg.BuildGitalyGit2Go(t, cfg) - - repoProto, _ := gittest.CreateRepository(t, ctx, cfg, gittest.CreateRepositoryConfig{ - SkipCreationViaService: true, - }) - - repo := localrepo.NewTestRepo(t, cfg, repoProto) - - executor := NewExecutor(cfg, gittest.NewCommandFactory(t, cfg), config.NewLocator(cfg), testhelper.SharedLogger(t)) - - flags, err := executor.FeatureFlags(ctx, repo) - require.NoError(t, err) - - require.Subset(t, flags, []FeatureFlag{ - { - Name: "feature_a", - MetadataKey: "gitaly-feature-feature-a", - Value: featureA.IsEnabled(ctx), - }, - { - Name: "feature_b", - MetadataKey: "gitaly-feature-feature-b", - Value: featureB.IsEnabled(ctx), - }, - }, flags) -} diff --git a/internal/git2go/rebase.go b/internal/git2go/rebase.go deleted file mode 100644 index 3bdc0e9e6..000000000 --- a/internal/git2go/rebase.go +++ /dev/null @@ -1,42 +0,0 @@ -package git2go - -import ( - "context" - - "gitlab.com/gitlab-org/gitaly/v16/internal/git" - "gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/storage" -) - -// RebaseCommand contains parameters to rebase a branch. -type RebaseCommand struct { - // Repository is the path to execute rebase in. - Repository string - // Committer contains the the committer signature. - Committer Signature - // BranchName is the branch that is rebased. Deprecated, can be removed in the next release. - BranchName string - // UpstreamRevision is the revision where the branch is rebased onto. Deprecated, can be - // removed in the next release. - UpstreamRevision string - // CommitID is the object ID of the commit that shall be rebased. Deprecates BranchName. - CommitID git.ObjectID - // UpstreamCommitID is the object ID of the commit which is considered to be the - // upstream branch. This parameter determines both the commit onto which we're - // about to rebase, which is the merge base of the upstream commit and rebased - // commit, and which commits should be rebased, which is the commit range - // upstream..commit. Deprecates the UpstreamRevision. - UpstreamCommitID git.ObjectID - // SkipEmptyCommits will cause commits which have already been applied on the target branch - // and which are thus empty to be skipped. If unset, empty commits will cause the rebase to - // fail. - SkipEmptyCommits bool - // SigningKey is a path to the key to sign commit using OpenPGP - SigningKey string -} - -// Rebase performs the rebase via gitaly-git2go -func (b *Executor) Rebase(ctx context.Context, repo storage.Repository, r RebaseCommand) (git.ObjectID, error) { - r.SigningKey = b.signingKey - - return b.runWithGob(ctx, repo, "rebase", r) -} diff --git a/internal/git2go/serialization.go b/internal/git2go/serialization.go deleted file mode 100644 index a1454e916..000000000 --- a/internal/git2go/serialization.go +++ /dev/null @@ -1,102 +0,0 @@ -package git2go - -import ( - "encoding/gob" - "errors" - "fmt" - "reflect" -) - -func init() { - for typeToRegister := range registeredTypes { - gob.Register(reflect.Zero(typeToRegister).Interface()) - } -} - -var registeredTypes = map[reflect.Type]struct{}{ - reflect.TypeOf(wrapError{}): {}, - reflect.TypeOf(HasConflictsError{}): {}, - reflect.TypeOf(ConflictingFilesError{}): {}, - reflect.TypeOf(EmptyError{}): {}, - reflect.TypeOf(CommitNotFoundError{}): {}, -} - -// Result is the serialized result. -type Result struct { - // CommitID is the result of the call. - CommitID string - // Err is set if an error occurred. Err must exist on all gob serialized - // results so that all errors can be returned. - Err error -} - -// wrapError is used to serialize wrapped errors as fmt.wrapError type only has -// private fields and can't be serialized via gob. It's also used to serialize unregistered -// error types by serializing only their error message. -type wrapError struct { - Message string - Err error -} - -func (err wrapError) Error() string { return err.Message } - -func (err wrapError) Unwrap() error { return err.Err } - -// HasConflictsError is used when a change, for example a revert, could not be -// applied due to a conflict. -type HasConflictsError struct{} - -func (err HasConflictsError) Error() string { - return "could not apply due to conflicts" -} - -// ConflictingFilesError is an error raised when there are conflicting files. -type ConflictingFilesError struct { - // ConflictingFiles is the set of files which have conflicts. - ConflictingFiles []string -} - -func (err ConflictingFilesError) Error() string { - return "there are conflicting files" -} - -// EmptyError indicates the command, for example cherry-pick, did result in no -// changes, so the result is empty. -type EmptyError struct{} - -func (err EmptyError) Error() string { - return "could not apply because the result was empty" -} - -// CommitNotFoundError indicates that the given commit rev could not be found. -type CommitNotFoundError struct { - // Revision used to lookup the commit - Revision string -} - -func (err CommitNotFoundError) Error() string { - return fmt.Sprintf("commit not found: %q", err.Revision) -} - -// SerializableError returns an error that is Gob serializable. -// Registered types are serialized directly. Unregistered types -// are transformed in to an opaque error using their error message. -// Wrapped errors remain unwrappable. -func SerializableError(err error) error { - if err == nil { - return nil - } - - if unwrappedErr := errors.Unwrap(err); unwrappedErr != nil { - return wrapError{ - Message: err.Error(), - Err: SerializableError(unwrappedErr), - } - } - - if _, ok := registeredTypes[reflect.TypeOf(err)]; !ok { - return wrapError{Message: err.Error()} - } - - return err -} diff --git a/internal/git2go/signature.go b/internal/git2go/signature.go deleted file mode 100644 index 1d66ed5e0..000000000 --- a/internal/git2go/signature.go +++ /dev/null @@ -1,9 +0,0 @@ -package git2go - -import "gitlab.com/gitlab-org/gitaly/v16/internal/git" - -// Signature represents a commits signature, synced from internal/git. -type Signature = git.Signature - -// NewSignature creates a new sanitized signature, syned from internal/git. -var NewSignature = git.NewSignature diff --git a/internal/git2go/testhelper_test.go b/internal/git2go/testhelper_test.go deleted file mode 100644 index f4298b718..000000000 --- a/internal/git2go/testhelper_test.go +++ /dev/null @@ -1,11 +0,0 @@ -package git2go - -import ( - "testing" - - "gitlab.com/gitlab-org/gitaly/v16/internal/testhelper" -) - -func TestMain(m *testing.M) { - testhelper.Run(m) -} diff --git a/internal/gitaly/config/config.go b/internal/gitaly/config/config.go index 1b4b7bbe0..a938b7c0c 100644 --- a/internal/gitaly/config/config.go +++ b/internal/gitaly/config/config.go @@ -759,7 +759,6 @@ func validateIsDirectory(path, name string) error { var packedBinaries = map[string]struct{}{ "gitaly-hooks": {}, "gitaly-ssh": {}, - "gitaly-git2go": {}, "gitaly-lfs-smudge": {}, "gitaly-gpg": {}, } diff --git a/internal/gitaly/service/diff/raw_test.go b/internal/gitaly/service/diff/raw_test.go index e88d2210f..43ef42b73 100644 --- a/internal/gitaly/service/diff/raw_test.go +++ b/internal/gitaly/service/diff/raw_test.go @@ -10,7 +10,6 @@ import ( "gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/storage" "gitlab.com/gitlab-org/gitaly/v16/internal/structerr" "gitlab.com/gitlab-org/gitaly/v16/internal/testhelper" - "gitlab.com/gitlab-org/gitaly/v16/internal/testhelper/testcfg" "gitlab.com/gitlab-org/gitaly/v16/proto/go/gitalypb" "gitlab.com/gitlab-org/gitaly/v16/streamio" ) @@ -20,7 +19,6 @@ func TestRawDiff_successful(t *testing.T) { ctx := testhelper.Context(t) cfg, client := setupDiffService(t) - testcfg.BuildGitalyGit2Go(t, cfg) repoProto, repoPath := gittest.CreateRepository(t, ctx, cfg) oldBlob := gittest.WriteBlob(t, cfg, repoPath, []byte("old\n")) diff --git a/internal/gitaly/service/operations/testhelper_test.go b/internal/gitaly/service/operations/testhelper_test.go index e4bb99929..8d0a04074 100644 --- a/internal/gitaly/service/operations/testhelper_test.go +++ b/internal/gitaly/service/operations/testhelper_test.go @@ -41,7 +41,6 @@ func setupOperationsServiceWithCfg( tb testing.TB, ctx context.Context, cfg config.Cfg, options ...testserver.GitalyServerOpt, ) (context.Context, config.Cfg, gitalypb.OperationServiceClient) { testcfg.BuildGitalySSH(tb, cfg) - testcfg.BuildGitalyGit2Go(tb, cfg) testcfg.BuildGitalyHooks(tb, cfg) serverSocketPath := runOperationServiceServer(tb, cfg, options...) @@ -62,7 +61,6 @@ func setupOperationsService( cfg := testcfg.Build(tb) testcfg.BuildGitalySSH(tb, cfg) - testcfg.BuildGitalyGit2Go(tb, cfg) testcfg.BuildGitalyHooks(tb, cfg) serverSocketPath := runOperationServiceServer(tb, cfg, options...) diff --git a/internal/testhelper/testcfg/binaries.go b/internal/testhelper/testcfg/binaries.go index c3d7265c7..5da1a88ea 100644 --- a/internal/testhelper/testcfg/binaries.go +++ b/internal/testhelper/testcfg/binaries.go @@ -18,16 +18,11 @@ import ( var buildOnceByName sync.Map -// BuildGitalyGPG builds the gitaly-git2go command and installs it into the binary directory. +// BuildGitalyGPG builds the gitaly-gpg command and installs it into the binary directory. func BuildGitalyGPG(tb testing.TB, cfg config.Cfg) string { return buildGitalyCommand(tb, cfg, "gitaly-gpg") } -// BuildGitalyGit2Go builds the gitaly-git2go command and installs it into the binary directory. -func BuildGitalyGit2Go(tb testing.TB, cfg config.Cfg) string { - return buildGitalyCommand(tb, cfg, "gitaly-git2go") -} - // BuildGitalyWrapper builds the gitaly-wrapper command and installs it into the binary directory. func BuildGitalyWrapper(tb testing.TB, cfg config.Cfg) string { return buildGitalyCommand(tb, cfg, "gitaly-wrapper") diff --git a/packed_binaries.go b/packed_binaries.go index 1ae1a54a2..f589282c0 100644 --- a/packed_binaries.go +++ b/packed_binaries.go @@ -16,7 +16,7 @@ const buildDir = "_build/bin" // packedBinariesFS contains embedded binaries. If you modify the above embeddings, you must also update // GITALY_PACKED_EXECUTABLES in Makefile and packedBinaries in internal/gitaly/config/config.go. // -//go:embed _build/bin/gitaly-hooks _build/bin/gitaly-ssh _build/bin/gitaly-git2go _build/bin/gitaly-lfs-smudge _build/bin/gitaly-gpg +//go:embed _build/bin/gitaly-hooks _build/bin/gitaly-ssh _build/bin/gitaly-lfs-smudge _build/bin/gitaly-gpg var packedBinariesFS embed.FS // UnpackAuxiliaryBinaries unpacks the packed auxiliary binaries of Gitaly into destination directory. |