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-04-10 16:48:24 +0300
committerJohn Cai <jcai@gitlab.com>2023-04-10 16:48:24 +0300
commita61c5cd57aac953befa3e989c6bc4ed18ff9f15b (patch)
tree64f7292140796ad6e4bea8b95802eb0560aceb5b
parent7c6af7a406815232ec1673a7e04c2be06443399c (diff)
wip: making tree helpers work with commit filesjc/commit-files-with-git-new
-rw-r--r--internal/git/localrepo/tree.go22
-rw-r--r--internal/gitaly/service/operations/commit_files.go167
2 files changed, 130 insertions, 59 deletions
diff --git a/internal/git/localrepo/tree.go b/internal/git/localrepo/tree.go
index 06fe7a67e..fa200ce0f 100644
--- a/internal/git/localrepo/tree.go
+++ b/internal/git/localrepo/tree.go
@@ -97,6 +97,8 @@ var (
ErrEntryExists = errors.New("entry already exists")
// ErrPathTraversal indicates a path contains a traversal.
ErrPathTraversal = errors.New("path contains traversal")
+ ErrDirExists = errors.New("directory already exists")
+ ErrInvalidPath = errors.New("invalid path")
)
func validateFileCreationPath(path string) error {
@@ -299,6 +301,26 @@ func (t *TreeEntry) Delete(
})
}
+// Exists deletes the entry of a current tree based on the path.
+func (t *TreeEntry) Get(
+ path string,
+) (*TreeEntry, error) {
+ if err := validateFileCreationPath(path); err != nil {
+ return nil, err
+ }
+
+ var result *TreeEntry
+
+ if err := t.recurse(path, func(currentTree, entry *TreeEntry, i int) error {
+ result = entry
+ return nil
+ }); err != nil {
+ return nil, err
+ }
+
+ return result, nil
+}
+
// Modify modifies an existing TreeEntry based on a path and a function to
// modify an entry.
func (t *TreeEntry) Modify(
diff --git a/internal/gitaly/service/operations/commit_files.go b/internal/gitaly/service/operations/commit_files.go
index 21318765b..fc06168a9 100644
--- a/internal/gitaly/service/operations/commit_files.go
+++ b/internal/gitaly/service/operations/commit_files.go
@@ -130,17 +130,19 @@ func validatePath(rootPath, relPath string) (string, error) {
// ErrNotFile indicates an error when a file was expected.
var ErrNotFile = errors.New("not a file")
-func applyAction(ctx context.Context, action git2go.Action, treeish git.ObjectID, repo *localrepo.Repo) (git.ObjectID, error) {
- var treeID git.ObjectID
+func applyAction(
+ ctx context.Context,
+ action git2go.Action,
+ root *localrepo.TreeEntry,
+ repo *localrepo.Repo,
+) error {
var err error
var path string
switch action := action.(type) {
case git2go.ChangeFileMode:
path = action.Path
- treeID, err = repo.ModifyTreeEntry(
- ctx,
- git.Revision(treeish),
+ err = root.Modify(
action.Path,
func(entry *localrepo.TreeEntry) error {
if action.ExecutableMode {
@@ -157,9 +159,7 @@ func applyAction(ctx context.Context, action git2go.Action, treeish git.ObjectID
})
case git2go.UpdateFile:
path = action.Path
- treeID, err = repo.ModifyTreeEntry(
- ctx,
- git.Revision(treeish),
+ err = root.Modify(
action.Path,
func(entry *localrepo.TreeEntry) error {
entry.OID = git.ObjectID(action.OID)
@@ -167,63 +167,85 @@ func applyAction(ctx context.Context, action git2go.Action, treeish git.ObjectID
})
case git2go.MoveFile:
path = action.NewPath
- treeID, err = repo.DeleteTreeEntry(
- ctx,
- git.Revision(treeish),
+ err = root.Delete(
action.Path,
)
if err != nil {
- return "", translateToGit2GoError(err, action.Path)
+ return translateToGit2GoError(err, action.Path)
}
- if action.OID == "" {
- info, err := repo.ReadObjectInfo(
- ctx,
- git.Revision(
- fmt.Sprintf(
- "%s:%s",
- treeish,
- action.Path,
+ /*
+ if action.OID == "" {
+ info, err := repo.ReadObjectInfo(
+ ctx,
+ git.Revision(
+ fmt.Sprintf(
+ "%s:%s",
+ treeish,
+ action.Path,
+ ),
),
- ),
- )
- if err != nil {
- return "", err
- }
+ )
+ if err != nil {
+ return err
+ }
- if !info.IsBlob() {
- return "", translateToGit2GoError(ErrNotFile, action.Path)
+ if !info.IsBlob() {
+ return translateToGit2GoError(ErrNotFile, action.Path)
+ }
+ action.OID = string(info.ObjectID())
}
- action.OID = string(info.ObjectID())
- }
+ */
- treeID, err = repo.AddTreeEntry(
- ctx,
- git.Revision(treeID),
+ err = root.Add(
action.NewPath,
- &localrepo.TreeEntry{
+ localrepo.TreeEntry{
OID: git.ObjectID(action.OID),
Mode: "100644",
Path: filepath.Base(action.NewPath),
},
- false,
- true,
+ localrepo.WithOverwriteDirectory(),
)
case git2go.CreateDirectory:
path = action.Path
- treeID, err = repo.AddTreeEntry(
- ctx,
- git.Revision(treeish),
- path,
- &localrepo.TreeEntry{
- Mode: "040000",
- Path: filepath.Base(path),
- Type: localrepo.Tree,
+ if entry, err := root.Get(path); err != nil && !errors.Is(err, localrepo.ErrEntryNotFound) {
+ return err
+ } else if entry != nil {
+ switch entry.Type {
+ case localrepo.Blob:
+ return git2go.IndexError{
+ Path: path,
+ Type: git2go.ErrFileExists,
+ }
+ case localrepo.Tree:
+ return git2go.IndexError{
+ Path: path,
+ Type: git2go.ErrDirectoryExists,
+ }
+ }
+ }
+
+ blobID, err := repo.WriteBlob(ctx, filepath.Join(path, ".gitkeep"), strings.NewReader(""))
+ if err != nil {
+ return err
+ }
+
+ err = root.Add(
+ filepath.Join(path, ".gitkeep"),
+ localrepo.TreeEntry{
+ Mode: "100644",
+ Path: ".gitkeep",
+ Type: localrepo.Blob,
+ OID: blobID,
},
- false,
- false,
)
+ if errors.Is(err, localrepo.ErrEntryExists) {
+ return git2go.IndexError{
+ Path: path,
+ Type: git2go.ErrDirectoryExists,
+ }
+ }
case git2go.CreateFile:
path = action.Path
mode := "100644"
@@ -231,30 +253,25 @@ func applyAction(ctx context.Context, action git2go.Action, treeish git.ObjectID
mode = "100755"
}
- treeID, err = repo.AddTreeEntry(
- ctx,
- git.Revision(treeish),
+ err = root.Add(
action.Path,
- &localrepo.TreeEntry{
+ localrepo.TreeEntry{
OID: git.ObjectID(action.OID),
Path: filepath.Base(action.Path),
Mode: mode,
},
- false,
- true,
+ localrepo.WithOverwriteDirectory(),
)
case git2go.DeleteFile:
path = action.Path
- treeID, err = repo.DeleteTreeEntry(
- ctx,
- git.Revision(treeish),
+ err = root.Delete(
action.Path,
)
default:
- return "", errors.New("unsupported action")
+ return errors.New("unsupported action")
}
- return treeID, translateToGit2GoError(err, path)
+ return translateToGit2GoError(err, path)
}
func translateToGit2GoError(err error, path string) error {
@@ -324,12 +341,44 @@ func (s *Server) userCommitFilesGit(
}
}
+ treeEntry := &localrepo.TreeEntry{
+ Mode: "040000",
+ Type: localrepo.Tree,
+ }
+
+ if treeish != "" {
+ treeEntry, err = quarantineRepo.GetFullTree(ctx, git.Revision(treeish))
+ if err != nil {
+ fmt.Printf("Err %s\n", err)
+ return "", err
+ }
+ }
+
+ fmt.Printf("actions %d\n", len(actions))
+
for _, action := range actions {
- if treeish, err = applyAction(
+ if err = applyAction(
ctx,
action,
- treeish,
- quarantineRepo); err != nil {
+ treeEntry,
+ quarantineRepo,
+ ); err != nil {
+ fmt.Printf("error: %s\n", err)
+ return "", err
+ }
+ }
+
+ fmt.Printf("Tree: %+v %d\n", treeEntry, len(treeEntry.Entries))
+ if len(actions) > 0 {
+ fmt.Println("writing actions")
+ treeish, err = quarantineRepo.WriteTreeRecursively(
+ ctx,
+ treeEntry,
+ )
+
+ fmt.Printf("treeish %s\n", treeish)
+ if err != nil {
+ fmt.Printf("ERRRRRR %s\n", err)
return "", err
}
}