Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitaly.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Cai <jcai@gitlab.com>2023-06-28 18:43:48 +0300
committerJohn Cai <jcai@gitlab.com>2023-07-07 18:37:18 +0300
commit3a4954a025bab668293aecaa8927ea0a356913e6 (patch)
tree662188aceaff318085ddc0a5c7c15534fb009a3a
parent480dc8a814e6bc56a547f8207d4d1f19b812dc2e (diff)
git2go: Remove Commit codejc/remove-git2go-commit
Now that we no longer create commits with git2go, let's remove all associated code.
-rw-r--r--cmd/gitaly-git2go/commit.go21
-rw-r--r--cmd/gitaly-git2go/commit/change_file_mode.go30
-rw-r--r--cmd/gitaly-git2go/commit/commit.go116
-rw-r--r--cmd/gitaly-git2go/commit/create_directory.go30
-rw-r--r--cmd/gitaly-git2go/commit/create_file.go30
-rw-r--r--cmd/gitaly-git2go/commit/delete_file.go16
-rw-r--r--cmd/gitaly-git2go/commit/move_file.go41
-rw-r--r--cmd/gitaly-git2go/commit/update_file.go30
-rw-r--r--cmd/gitaly-git2go/commit/validate.go48
-rw-r--r--cmd/gitaly-git2go/main.go1
-rw-r--r--internal/git2go/commit.go29
-rw-r--r--internal/git2go/commit_test.go623
12 files changed, 0 insertions, 1015 deletions
diff --git a/cmd/gitaly-git2go/commit.go b/cmd/gitaly-git2go/commit.go
deleted file mode 100644
index f418a864a..000000000
--- a/cmd/gitaly-git2go/commit.go
+++ /dev/null
@@ -1,21 +0,0 @@
-//go:build static && system_libgit2
-
-package main
-
-import (
- "context"
- "encoding/gob"
- "flag"
-
- "gitlab.com/gitlab-org/gitaly/v16/cmd/gitaly-git2go/commit"
-)
-
-type commitSubcommand struct{}
-
-func (cmd *commitSubcommand) Flags() *flag.FlagSet {
- return flag.NewFlagSet("commit", flag.ExitOnError)
-}
-
-func (cmd *commitSubcommand) Run(ctx context.Context, decoder *gob.Decoder, encoder *gob.Encoder) error {
- return commit.Run(ctx, decoder, encoder)
-}
diff --git a/cmd/gitaly-git2go/commit/change_file_mode.go b/cmd/gitaly-git2go/commit/change_file_mode.go
deleted file mode 100644
index b36445688..000000000
--- a/cmd/gitaly-git2go/commit/change_file_mode.go
+++ /dev/null
@@ -1,30 +0,0 @@
-//go:build static && system_libgit2
-
-package commit
-
-import (
- git "github.com/libgit2/git2go/v34"
- "gitlab.com/gitlab-org/gitaly/v16/internal/git2go"
-)
-
-func applyChangeFileMode(action git2go.ChangeFileMode, index *git.Index) error {
- entry, err := index.EntryByPath(action.Path, 0)
- if err != nil {
- if git.IsErrorCode(err, git.ErrorCodeNotFound) {
- return git2go.IndexError{Type: git2go.ErrFileNotFound, Path: action.Path}
- }
-
- return err
- }
-
- mode := git.FilemodeBlob
- if action.ExecutableMode {
- mode = git.FilemodeBlobExecutable
- }
-
- return index.Add(&git.IndexEntry{
- Path: action.Path,
- Mode: mode,
- Id: entry.Id,
- })
-}
diff --git a/cmd/gitaly-git2go/commit/commit.go b/cmd/gitaly-git2go/commit/commit.go
deleted file mode 100644
index a6964692c..000000000
--- a/cmd/gitaly-git2go/commit/commit.go
+++ /dev/null
@@ -1,116 +0,0 @@
-//go:build static && system_libgit2
-
-package commit
-
-import (
- "context"
- "encoding/gob"
- "errors"
- "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"
-)
-
-// Run runs the commit subcommand.
-func Run(ctx context.Context, decoder *gob.Decoder, encoder *gob.Encoder) error {
- var params git2go.CommitCommand
- if err := decoder.Decode(&params); err != nil {
- return err
- }
-
- commitID, err := commit(ctx, params)
- return encoder.Encode(git2go.Result{
- CommitID: commitID,
- Err: git2go.SerializableError(err),
- })
-}
-
-func commit(ctx context.Context, request git2go.CommitCommand) (string, error) {
- repo, err := git2goutil.OpenRepository(request.Repository)
- if err != nil {
- return "", fmt.Errorf("open repository: %w", err)
- }
-
- index, err := git.NewIndex()
- if err != nil {
- return "", fmt.Errorf("new index: %w", err)
- }
-
- var parents []*git.Commit
- if request.Parent != "" {
- parentOID, err := git.NewOid(request.Parent)
- if err != nil {
- return "", fmt.Errorf("parse base commit oid: %w", err)
- }
-
- baseCommit, err := repo.LookupCommit(parentOID)
- if err != nil {
- return "", fmt.Errorf("lookup commit: %w", err)
- }
-
- parents = []*git.Commit{baseCommit}
-
- baseTree, err := baseCommit.Tree()
- if err != nil {
- return "", fmt.Errorf("lookup tree: %w", err)
- }
-
- if err := index.ReadTree(baseTree); err != nil {
- return "", fmt.Errorf("read tree: %w", err)
- }
- }
-
- for _, action := range request.Actions {
- if err := apply(action, repo, index); err != nil {
- if git.IsErrorClass(err, git.ErrorClassIndex) {
- err = git2go.UnknownIndexError(err.Error())
- }
-
- return "", fmt.Errorf("apply action %T: %w", action, err)
- }
- }
-
- treeOID, err := index.WriteTreeTo(repo)
- if err != nil {
- return "", fmt.Errorf("write tree: %w", err)
- }
- tree, err := repo.LookupTree(treeOID)
- if err != nil {
- return "", fmt.Errorf("lookup tree: %w", err)
- }
-
- author := git.Signature(request.Author)
- committer := git.Signature(request.Committer)
- commitID, err := git2goutil.NewCommitSubmitter(repo, request.SigningKey).
- Commit(&author, &committer, git.MessageEncodingUTF8, request.Message, tree, parents...)
- if err != nil {
- if git.IsErrorClass(err, git.ErrorClassInvalid) {
- return "", git2go.InvalidArgumentError(err.Error())
- }
-
- return "", fmt.Errorf("create commit: %w", err)
- }
-
- return commitID.String(), nil
-}
-
-func apply(action git2go.Action, repo *git.Repository, index *git.Index) error {
- switch action := action.(type) {
- case git2go.ChangeFileMode:
- return applyChangeFileMode(action, index)
- case git2go.CreateDirectory:
- return applyCreateDirectory(action, repo, index)
- case git2go.CreateFile:
- return applyCreateFile(action, index)
- case git2go.DeleteFile:
- return applyDeleteFile(action, index)
- case git2go.MoveFile:
- return applyMoveFile(action, index)
- case git2go.UpdateFile:
- return applyUpdateFile(action, index)
- default:
- return errors.New("unsupported action")
- }
-}
diff --git a/cmd/gitaly-git2go/commit/create_directory.go b/cmd/gitaly-git2go/commit/create_directory.go
deleted file mode 100644
index c990933be..000000000
--- a/cmd/gitaly-git2go/commit/create_directory.go
+++ /dev/null
@@ -1,30 +0,0 @@
-//go:build static && system_libgit2
-
-package commit
-
-import (
- "fmt"
- "path/filepath"
-
- git "github.com/libgit2/git2go/v34"
- "gitlab.com/gitlab-org/gitaly/v16/internal/git2go"
-)
-
-func applyCreateDirectory(action git2go.CreateDirectory, repo *git.Repository, index *git.Index) error {
- if err := validateFileDoesNotExist(index, action.Path); err != nil {
- return err
- } else if err := validateDirectoryDoesNotExist(index, action.Path); err != nil {
- return err
- }
-
- emptyBlobOID, err := repo.CreateBlobFromBuffer([]byte{})
- if err != nil {
- return fmt.Errorf("create blob from buffer: %w", err)
- }
-
- return index.Add(&git.IndexEntry{
- Path: filepath.Join(action.Path, ".gitkeep"),
- Mode: git.FilemodeBlob,
- Id: emptyBlobOID,
- })
-}
diff --git a/cmd/gitaly-git2go/commit/create_file.go b/cmd/gitaly-git2go/commit/create_file.go
deleted file mode 100644
index 9862973d0..000000000
--- a/cmd/gitaly-git2go/commit/create_file.go
+++ /dev/null
@@ -1,30 +0,0 @@
-//go:build static && system_libgit2
-
-package commit
-
-import (
- git "github.com/libgit2/git2go/v34"
- "gitlab.com/gitlab-org/gitaly/v16/internal/git2go"
-)
-
-func applyCreateFile(action git2go.CreateFile, index *git.Index) error {
- if err := validateFileDoesNotExist(index, action.Path); err != nil {
- return err
- }
-
- oid, err := git.NewOid(action.OID)
- if err != nil {
- return err
- }
-
- mode := git.FilemodeBlob
- if action.ExecutableMode {
- mode = git.FilemodeBlobExecutable
- }
-
- return index.Add(&git.IndexEntry{
- Path: action.Path,
- Mode: mode,
- Id: oid,
- })
-}
diff --git a/cmd/gitaly-git2go/commit/delete_file.go b/cmd/gitaly-git2go/commit/delete_file.go
deleted file mode 100644
index 507297266..000000000
--- a/cmd/gitaly-git2go/commit/delete_file.go
+++ /dev/null
@@ -1,16 +0,0 @@
-//go:build static && system_libgit2
-
-package commit
-
-import (
- git "github.com/libgit2/git2go/v34"
- "gitlab.com/gitlab-org/gitaly/v16/internal/git2go"
-)
-
-func applyDeleteFile(action git2go.DeleteFile, index *git.Index) error {
- if err := validateFileExists(index, action.Path); err != nil {
- return err
- }
-
- return index.RemoveByPath(action.Path)
-}
diff --git a/cmd/gitaly-git2go/commit/move_file.go b/cmd/gitaly-git2go/commit/move_file.go
deleted file mode 100644
index 4c0294c5f..000000000
--- a/cmd/gitaly-git2go/commit/move_file.go
+++ /dev/null
@@ -1,41 +0,0 @@
-//go:build static && system_libgit2
-
-package commit
-
-import (
- git "github.com/libgit2/git2go/v34"
- "gitlab.com/gitlab-org/gitaly/v16/internal/git2go"
-)
-
-func applyMoveFile(action git2go.MoveFile, index *git.Index) error {
- entry, err := index.EntryByPath(action.Path, 0)
- if err != nil {
- if git.IsErrorCode(err, git.ErrorCodeNotFound) {
- return git2go.IndexError{Type: git2go.ErrFileNotFound, Path: action.Path}
- }
-
- return err
- }
-
- if err := validateFileDoesNotExist(index, action.NewPath); err != nil {
- return err
- }
-
- oid := entry.Id
- if action.OID != "" {
- oid, err = git.NewOid(action.OID)
- if err != nil {
- return err
- }
- }
-
- if err := index.Add(&git.IndexEntry{
- Path: action.NewPath,
- Mode: entry.Mode,
- Id: oid,
- }); err != nil {
- return err
- }
-
- return index.RemoveByPath(entry.Path)
-}
diff --git a/cmd/gitaly-git2go/commit/update_file.go b/cmd/gitaly-git2go/commit/update_file.go
deleted file mode 100644
index d4236a2ab..000000000
--- a/cmd/gitaly-git2go/commit/update_file.go
+++ /dev/null
@@ -1,30 +0,0 @@
-//go:build static && system_libgit2
-
-package commit
-
-import (
- git "github.com/libgit2/git2go/v34"
- "gitlab.com/gitlab-org/gitaly/v16/internal/git2go"
-)
-
-func applyUpdateFile(action git2go.UpdateFile, index *git.Index) error {
- entry, err := index.EntryByPath(action.Path, 0)
- if err != nil {
- if git.IsErrorCode(err, git.ErrorCodeNotFound) {
- return git2go.IndexError{Type: git2go.ErrFileNotFound, Path: action.Path}
- }
-
- return err
- }
-
- oid, err := git.NewOid(action.OID)
- if err != nil {
- return err
- }
-
- return index.Add(&git.IndexEntry{
- Path: action.Path,
- Mode: entry.Mode,
- Id: oid,
- })
-}
diff --git a/cmd/gitaly-git2go/commit/validate.go b/cmd/gitaly-git2go/commit/validate.go
deleted file mode 100644
index 7dbe43794..000000000
--- a/cmd/gitaly-git2go/commit/validate.go
+++ /dev/null
@@ -1,48 +0,0 @@
-//go:build static && system_libgit2
-
-package commit
-
-import (
- "os"
-
- git "github.com/libgit2/git2go/v34"
- "gitlab.com/gitlab-org/gitaly/v16/internal/git2go"
-)
-
-func validateFileExists(index *git.Index, path string) error {
- if _, err := index.Find(path); err != nil {
- if git.IsErrorCode(err, git.ErrorCodeNotFound) {
- return git2go.IndexError{Type: git2go.ErrFileNotFound, Path: path}
- }
-
- return err
- }
-
- return nil
-}
-
-func validateFileDoesNotExist(index *git.Index, path string) error {
- _, err := index.Find(path)
- if err == nil {
- return git2go.IndexError{Type: git2go.ErrFileExists, Path: path}
- }
-
- if !git.IsErrorCode(err, git.ErrorCodeNotFound) {
- return err
- }
-
- return nil
-}
-
-func validateDirectoryDoesNotExist(index *git.Index, path string) error {
- _, err := index.FindPrefix(path + string(os.PathSeparator))
- if err == nil {
- return git2go.IndexError{Type: git2go.ErrDirectoryExists, Path: path}
- }
-
- if !git.IsErrorCode(err, git.ErrorCodeNotFound) {
- return err
- }
-
- return nil
-}
diff --git a/cmd/gitaly-git2go/main.go b/cmd/gitaly-git2go/main.go
index ac050c427..132c8db1d 100644
--- a/cmd/gitaly-git2go/main.go
+++ b/cmd/gitaly-git2go/main.go
@@ -27,7 +27,6 @@ type subcmd interface {
var subcommands = map[string]subcmd{
"apply": &applySubcommand{},
"cherry-pick": &cherryPickSubcommand{},
- "commit": &commitSubcommand{},
"merge": &mergeSubcommand{},
"rebase": &rebaseSubcommand{},
"revert": &revertSubcommand{},
diff --git a/internal/git2go/commit.go b/internal/git2go/commit.go
index 2fb7232ea..4325cd930 100644
--- a/internal/git2go/commit.go
+++ b/internal/git2go/commit.go
@@ -1,12 +1,9 @@
package git2go
import (
- "context"
"errors"
"fmt"
- "gitlab.com/gitlab-org/gitaly/v16/internal/git"
- "gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/storage"
"gitlab.com/gitlab-org/gitaly/v16/internal/structerr"
"gitlab.com/gitlab-org/gitaly/v16/proto/go/gitalypb"
)
@@ -104,29 +101,3 @@ func (err IndexError) StructuredError() structerr.Error {
type InvalidArgumentError string
func (err InvalidArgumentError) Error() string { return string(err) }
-
-// CommitCommand contains the information and the steps to build a commit.
-type CommitCommand struct {
- // Repository is the path of the repository to operate on.
- Repository string
- // Author is the author of the commit.
- Author Signature
- // Committer is the committer of the commit.
- Committer Signature
- // Message is message of the commit.
- Message string
- // Parent is the OID of the commit to use as the parent of this commit.
- Parent string
- // Actions are the steps to build the commit.
- Actions []Action
- // SigningKey is a path to the key to sign commit using OpenPGP
- SigningKey string
-}
-
-// Commit builds a commit from the actions, writes it to the object database and
-// returns its object id.
-func (b *Executor) Commit(ctx context.Context, repo storage.Repository, c CommitCommand) (git.ObjectID, error) {
- c.SigningKey = b.signingKey
-
- return b.runWithGob(ctx, repo, "commit", c)
-}
diff --git a/internal/git2go/commit_test.go b/internal/git2go/commit_test.go
deleted file mode 100644
index aff97419e..000000000
--- a/internal/git2go/commit_test.go
+++ /dev/null
@@ -1,623 +0,0 @@
-//go:build !gitaly_test_sha256
-
-package git2go
-
-import (
- "bytes"
- "context"
- "errors"
- "fmt"
- "os"
- "testing"
-
- "github.com/stretchr/testify/require"
- "gitlab.com/gitlab-org/gitaly/v16/internal/git"
- "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/signature"
- "gitlab.com/gitlab-org/gitaly/v16/internal/testhelper"
- "gitlab.com/gitlab-org/gitaly/v16/internal/testhelper/testcfg"
-)
-
-func TestMain(m *testing.M) {
- testhelper.Run(m)
-}
-
-//go:generate rm testdata/signing_ssh_key_ed25519
-//go:generate ssh-keygen -t ed25519 -f testdata/signing_ssh_key_ed25519 -q -N ""
-//go:generate ssh-keygen -Y sign -n git -f testdata/signing_ssh_key_ed25519 testdata/commit
-//go:generate mv testdata/commit.sig testdata/signing_ssh_key_ed25519.sig
-//go:generate rm testdata/signing_ssh_key_rsa
-//go:generate ssh-keygen -t rsa -b 4096 -f testdata/signing_ssh_key_rsa -q -N ""
-//go:generate ssh-keygen -Y sign -n git -f testdata/signing_ssh_key_rsa testdata/commit
-//go:generate mv testdata/commit.sig testdata/signing_ssh_key_rsa.sig
-//go:generate rm testdata/signing_ssh_key_ecdsa
-//go:generate ssh-keygen -t ecdsa -f testdata/signing_ssh_key_ecdsa -q -N ""
-func TestExecutor_Commit(t *testing.T) {
- const (
- DefaultMode = "100644"
- ExecutableMode = "100755"
- )
-
- type signingKey struct {
- path string
- sigPath string
- }
- type step struct {
- actions []Action
- error error
- treeEntries []gittest.TreeEntry
- testCommit func(testing.TB, git.ObjectID, signingKey)
- }
- ctx := testhelper.Context(t)
-
- cfg := testcfg.Build(t)
- testcfg.BuildGitalyGit2Go(t, cfg)
-
- repoProto, repoPath := gittest.CreateRepository(t, ctx, cfg, gittest.CreateRepositoryConfig{
- SkipCreationViaService: true,
- })
-
- repo := localrepo.NewTestRepo(t, cfg, repoProto)
-
- originalFile, err := repo.WriteBlob(ctx, "file", bytes.NewBufferString("original"))
- require.NoError(t, err)
-
- updatedFile, err := repo.WriteBlob(ctx, "file", bytes.NewBufferString("updated"))
- require.NoError(t, err)
-
- executor := NewExecutor(cfg, gittest.NewCommandFactory(t, cfg), config.NewLocator(cfg))
-
- author := defaultCommitAuthorSignature()
- committer := defaultCommitAuthorSignature()
-
- for _, tc := range []struct {
- desc string
- steps []step
- }{
- {
- desc: "create directory",
- steps: []step{
- {
- actions: []Action{
- CreateDirectory{Path: "directory"},
- },
- treeEntries: []gittest.TreeEntry{
- {Mode: DefaultMode, Path: "directory/.gitkeep"},
- },
- },
- },
- },
- {
- desc: "create directory created duplicate",
- steps: []step{
- {
- actions: []Action{
- CreateDirectory{Path: "directory"},
- CreateDirectory{Path: "directory"},
- },
- error: IndexError{Type: ErrDirectoryExists, Path: "directory"},
- },
- },
- },
- {
- desc: "create directory existing duplicate",
- steps: []step{
- {
- actions: []Action{
- CreateDirectory{Path: "directory"},
- },
- treeEntries: []gittest.TreeEntry{
- {Mode: DefaultMode, Path: "directory/.gitkeep"},
- },
- },
- {
- actions: []Action{
- CreateDirectory{Path: "directory"},
- },
- error: IndexError{Type: ErrDirectoryExists, Path: "directory"},
- },
- },
- },
- {
- desc: "create directory with a files name",
- steps: []step{
- {
- actions: []Action{
- CreateFile{Path: "file", OID: originalFile.String()},
- },
- treeEntries: []gittest.TreeEntry{
- {Mode: DefaultMode, Path: "file", Content: "original"},
- },
- },
- {
- actions: []Action{
- CreateDirectory{Path: "file"},
- },
- error: IndexError{Type: ErrFileExists, Path: "file"},
- },
- },
- },
- {
- desc: "create file",
- steps: []step{
- {
- actions: []Action{
- CreateFile{Path: "file", OID: originalFile.String()},
- },
- treeEntries: []gittest.TreeEntry{
- {Mode: DefaultMode, Path: "file", Content: "original"},
- },
- },
- },
- },
- {
- desc: "create duplicate file",
- steps: []step{
- {
- actions: []Action{
- CreateFile{Path: "file", OID: originalFile.String()},
- CreateFile{Path: "file", OID: updatedFile.String()},
- },
- error: IndexError{Type: ErrFileExists, Path: "file"},
- },
- },
- },
- {
- desc: "create file overwrites directory",
- steps: []step{
- {
- actions: []Action{
- CreateDirectory{Path: "directory"},
- CreateFile{Path: "directory", OID: originalFile.String()},
- },
- treeEntries: []gittest.TreeEntry{
- {Mode: DefaultMode, Path: "directory", Content: "original"},
- },
- },
- },
- },
- {
- desc: "update created file",
- steps: []step{
- {
- actions: []Action{
- CreateFile{Path: "file", OID: originalFile.String()},
- UpdateFile{Path: "file", OID: updatedFile.String()},
- },
- treeEntries: []gittest.TreeEntry{
- {Mode: DefaultMode, Path: "file", Content: "updated"},
- },
- },
- },
- },
- {
- desc: "update existing file",
- steps: []step{
- {
- actions: []Action{
- CreateFile{Path: "file", OID: originalFile.String()},
- },
- treeEntries: []gittest.TreeEntry{
- {Mode: DefaultMode, Path: "file", Content: "original"},
- },
- },
- {
- actions: []Action{
- UpdateFile{Path: "file", OID: updatedFile.String()},
- },
- treeEntries: []gittest.TreeEntry{
- {Mode: DefaultMode, Path: "file", Content: "updated"},
- },
- },
- },
- },
- {
- desc: "update non-existing file",
- steps: []step{
- {
- actions: []Action{
- UpdateFile{Path: "non-existing", OID: updatedFile.String()},
- },
- error: IndexError{Type: ErrFileNotFound, Path: "non-existing"},
- },
- },
- },
- {
- desc: "move created file",
- steps: []step{
- {
- actions: []Action{
- CreateFile{Path: "original-file", OID: originalFile.String()},
- MoveFile{Path: "original-file", NewPath: "moved-file", OID: originalFile.String()},
- },
- treeEntries: []gittest.TreeEntry{
- {Mode: DefaultMode, Path: "moved-file", Content: "original"},
- },
- },
- },
- },
- {
- desc: "moving directory fails",
- steps: []step{
- {
- actions: []Action{
- CreateDirectory{Path: "directory"},
- MoveFile{Path: "directory", NewPath: "moved-directory"},
- },
- error: IndexError{Type: ErrFileNotFound, Path: "directory"},
- },
- },
- },
- {
- desc: "move file inferring content",
- steps: []step{
- {
- actions: []Action{
- CreateFile{Path: "original-file", OID: originalFile.String()},
- },
- treeEntries: []gittest.TreeEntry{
- {Mode: DefaultMode, Path: "original-file", Content: "original"},
- },
- },
- {
- actions: []Action{
- MoveFile{Path: "original-file", NewPath: "moved-file"},
- },
- treeEntries: []gittest.TreeEntry{
- {Mode: DefaultMode, Path: "moved-file", Content: "original"},
- },
- },
- },
- },
- {
- desc: "move file with non-existing source",
- steps: []step{
- {
- actions: []Action{
- MoveFile{Path: "non-existing", NewPath: "destination-file"},
- },
- error: IndexError{Type: ErrFileNotFound, Path: "non-existing"},
- },
- },
- },
- {
- desc: "move file with already existing destination file",
- steps: []step{
- {
- actions: []Action{
- CreateFile{Path: "source-file", OID: originalFile.String()},
- CreateFile{Path: "already-existing", OID: updatedFile.String()},
- MoveFile{Path: "source-file", NewPath: "already-existing"},
- },
- error: IndexError{Type: ErrFileExists, Path: "already-existing"},
- },
- },
- },
- {
- // seems like a bug in the original implementation to allow overwriting a
- // directory
- desc: "move file with already existing destination directory",
- steps: []step{
- {
- actions: []Action{
- CreateFile{Path: "file", OID: originalFile.String()},
- CreateDirectory{Path: "already-existing"},
- MoveFile{Path: "file", NewPath: "already-existing"},
- },
- treeEntries: []gittest.TreeEntry{
- {Mode: DefaultMode, Path: "already-existing", Content: "original"},
- },
- },
- },
- },
- {
- desc: "move file providing content",
- steps: []step{
- {
- actions: []Action{
- CreateFile{Path: "original-file", OID: originalFile.String()},
- },
- treeEntries: []gittest.TreeEntry{
- {Mode: DefaultMode, Path: "original-file", Content: "original"},
- },
- },
- {
- actions: []Action{
- MoveFile{Path: "original-file", NewPath: "moved-file", OID: updatedFile.String()},
- },
- treeEntries: []gittest.TreeEntry{
- {Mode: DefaultMode, Path: "moved-file", Content: "updated"},
- },
- },
- },
- },
- {
- desc: "mark non-existing file executable",
- steps: []step{
- {
- actions: []Action{
- ChangeFileMode{Path: "non-existing"},
- },
- error: IndexError{Type: ErrFileNotFound, Path: "non-existing"},
- },
- },
- },
- {
- desc: "mark executable file executable",
- steps: []step{
- {
- actions: []Action{
- CreateFile{Path: "file-1", OID: originalFile.String()},
- ChangeFileMode{Path: "file-1", ExecutableMode: true},
- },
- treeEntries: []gittest.TreeEntry{
- {Mode: ExecutableMode, Path: "file-1", Content: "original"},
- },
- },
- {
- actions: []Action{
- ChangeFileMode{Path: "file-1", ExecutableMode: true},
- },
- treeEntries: []gittest.TreeEntry{
- {Mode: ExecutableMode, Path: "file-1", Content: "original"},
- },
- },
- },
- },
- {
- desc: "mark created file executable",
- steps: []step{
- {
- actions: []Action{
- CreateFile{Path: "file-1", OID: originalFile.String()},
- ChangeFileMode{Path: "file-1", ExecutableMode: true},
- },
- treeEntries: []gittest.TreeEntry{
- {Mode: ExecutableMode, Path: "file-1", Content: "original"},
- },
- },
- },
- },
- {
- desc: "mark existing file executable",
- steps: []step{
- {
- actions: []Action{
- CreateFile{Path: "file-1", OID: originalFile.String()},
- },
- treeEntries: []gittest.TreeEntry{
- {Mode: DefaultMode, Path: "file-1", Content: "original"},
- },
- },
- {
- actions: []Action{
- ChangeFileMode{Path: "file-1", ExecutableMode: true},
- },
- treeEntries: []gittest.TreeEntry{
- {Mode: ExecutableMode, Path: "file-1", Content: "original"},
- },
- },
- },
- },
- {
- desc: "move non-existing file",
- steps: []step{
- {
- actions: []Action{
- MoveFile{Path: "non-existing", NewPath: "destination"},
- },
- error: IndexError{Type: ErrFileNotFound, Path: "non-existing"},
- },
- },
- },
- {
- desc: "move doesn't overwrite a file",
- steps: []step{
- {
- actions: []Action{
- CreateFile{Path: "file-1", OID: originalFile.String()},
- CreateFile{Path: "file-2", OID: updatedFile.String()},
- MoveFile{Path: "file-1", NewPath: "file-2"},
- },
- error: IndexError{Type: ErrFileExists, Path: "file-2"},
- },
- },
- },
- {
- desc: "delete non-existing file",
- steps: []step{
- {
- actions: []Action{
- DeleteFile{Path: "non-existing"},
- },
- error: IndexError{Type: ErrFileNotFound, Path: "non-existing"},
- },
- },
- },
- {
- desc: "delete created file",
- steps: []step{
- {
- actions: []Action{
- CreateFile{Path: "file-1", OID: originalFile.String()},
- DeleteFile{Path: "file-1"},
- },
- },
- },
- },
- {
- desc: "delete existing file",
- steps: []step{
- {
- actions: []Action{
- CreateFile{Path: "file-1", OID: originalFile.String()},
- },
- treeEntries: []gittest.TreeEntry{
- {Mode: DefaultMode, Path: "file-1", Content: "original"},
- },
- },
- {
- actions: []Action{
- DeleteFile{Path: "file-1"},
- },
- },
- },
- },
- } {
- t.Run(tc.desc, func(t *testing.T) {
- var parentCommit git.ObjectID
- var parentIds []string
- for i, step := range tc.steps {
- message := fmt.Sprintf("commit %d", i+1)
- commitID, err := executor.Commit(ctx, repo, CommitCommand{
- Repository: repoPath,
- Author: author,
- Committer: committer,
- Message: message,
- Parent: parentCommit.String(),
- Actions: step.actions,
- })
-
- if step.error != nil {
- require.True(t, errors.Is(err, step.error), "expected: %q, actual: %q", step.error, err)
- continue
- } else {
- require.NoError(t, err)
- }
-
- commit, err := repo.ReadCommit(ctx, commitID.Revision())
- require.NoError(t, err)
-
- require.Equal(t, parentIds, commit.ParentIds)
- require.Equal(t, gittest.DefaultCommitAuthor, commit.Author)
- require.Equal(t, gittest.DefaultCommitAuthor, commit.Committer)
- require.Equal(t, []byte(message), commit.Body)
-
- gittest.RequireTree(t, cfg, repoPath, commitID.String(), step.treeEntries)
- parentCommit = commitID
- parentIds = []string{string(commitID)}
- }
- })
- }
-
- for _, tc := range []struct {
- desc string
- steps []step
- signingKeys []signingKey
- }{
- {
- desc: "update created file, sign commit and verify signature using SSH signing key",
- steps: []step{
- {
- actions: []Action{
- CreateFile{Path: "file", OID: originalFile.String()},
- UpdateFile{Path: "file", OID: updatedFile.String()},
- },
- treeEntries: []gittest.TreeEntry{
- {Mode: DefaultMode, Path: "file", Content: "updated"},
- },
- testCommit: func(tb testing.TB, commitID git.ObjectID, key signingKey) {
- sshsig, dataWithoutSSHSig := extractSignature(t, ctx, repo, commitID)
-
- signingKey, err := signature.ParseSigningKey(key.path)
- require.NoError(tb, err)
- require.NoError(tb, signingKey.Verify([]byte(sshsig), []byte(dataWithoutSSHSig)))
-
- // Verify that the generated signature equals the one generated by Git for the identical content.
- if key.sigPath != "" {
- expectedSig, err := os.ReadFile(key.sigPath)
- require.NoError(tb, err)
- require.Equal(tb, string(expectedSig), sshsig)
- }
- },
- },
- },
- // Keys that are used to sign commits using SSH
- signingKeys: []signingKey{
- {
- path: "testdata/signing_ssh_key_ed25519",
- sigPath: "testdata/signing_ssh_key_ed25519.sig",
- }, {
- path: "testdata/signing_ssh_key_rsa",
- sigPath: "testdata/signing_ssh_key_rsa.sig",
- }, {
- path: "testdata/signing_ssh_key_ecdsa",
- },
- },
- },
- {
- desc: "update created file, sign commit and verify signature using GPG signing key",
- steps: []step{
- {
- actions: []Action{
- CreateFile{Path: "file", OID: originalFile.String()},
- UpdateFile{Path: "file", OID: updatedFile.String()},
- },
- treeEntries: []gittest.TreeEntry{
- {Mode: DefaultMode, Path: "file", Content: "updated"},
- },
- testCommit: func(tb testing.TB, commitID git.ObjectID, key signingKey) {
- gpgsig, dataWithoutGpgSig := extractSignature(t, ctx, repo, commitID)
-
- signingKey, err := signature.ParseSigningKey(key.path)
- require.NoError(tb, err)
- require.NoError(tb, signingKey.Verify([]byte(gpgsig), []byte(dataWithoutGpgSig)))
- },
- },
- },
- // Keys that are used to sign commits using GPG
- // Can be generated by the following command: gpg --gen-key
- signingKeys: []signingKey{
- {
- path: "testdata/signing_gpg_key",
- },
- },
- },
- } {
- for _, signingKey := range tc.signingKeys {
- t.Run(tc.desc+" with "+signingKey.path, func(t *testing.T) {
- executor.signingKey = signingKey.path
-
- for i, step := range tc.steps {
- message := fmt.Sprintf("commit %d", i+1)
- commitID, err := executor.Commit(ctx, repo, CommitCommand{
- Repository: repoPath,
- Author: author,
- Committer: committer,
- Message: message,
- Actions: step.actions,
- })
- require.NoError(t, err)
-
- commit, err := repo.ReadCommit(ctx, commitID.Revision())
- require.NoError(t, err)
-
- require.Equal(t, gittest.DefaultCommitAuthor, commit.Author)
- require.Equal(t, gittest.DefaultCommitAuthor, commit.Committer)
- require.Equal(t, []byte(message), commit.Body)
-
- step.testCommit(t, commitID, signingKey)
-
- gittest.RequireTree(t, cfg, repoPath, commitID.String(), step.treeEntries)
- }
- })
- }
- }
-}
-
-func extractSignature(tb testing.TB, ctx context.Context, repo *localrepo.Repo, oid git.ObjectID) (string, string) {
- data, err := repo.ReadObject(ctx, oid)
- require.NoError(tb, err)
-
- return signature.ExtractSignature(tb, ctx, data)
-}
-
-func defaultCommitAuthorSignature() Signature {
- return NewSignature(
- gittest.DefaultCommitterName,
- gittest.DefaultCommitterMail,
- gittest.DefaultCommitTime,
- )
-}