--- 9.0.3 2024-12-12 08:06:13.000000000 +0100 +++ aneksajo 2024-12-16 08:23:15.000000000 +0100 @@ -8,11 +8,13 @@ "fmt" "os" "path" + "path/filepath" "strings" git_model "code.gitea.io/gitea/models/git" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" + "code.gitea.io/gitea/modules/annex" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/lfs" "code.gitea.io/gitea/modules/setting" @@ -89,7 +91,7 @@ defer t.Close() hasOldBranch := true - if err = t.Clone(opts.OldBranch, true); err != nil { + if err = t.Clone(opts.OldBranch, false); err != nil { if !git.IsErrBranchNotExist(err) || !repo.IsEmpty { return err } @@ -105,10 +107,30 @@ } } - // Copy uploaded files into repository. - if err := copyUploadedLFSFilesIntoRepository(infos, t, opts.TreePath); err != nil { + r, err := git.OpenRepository(ctx, repo.RepoPath()) + if err != nil { return err } + if annex.IsAnnexRepo(r) { + // Initialize annex privately in temporary clone + if err := t.InitPrivateAnnex(); err != nil { + return err + } + // Copy uploaded files into git-annex repository + if err := copyUploadedFilesIntoAnnexRepository(infos, t, opts.TreePath); err != nil { + return err + } + // Move all annexed content in the temporary repository, i.e. everything we have just added, to the origin + author, committer := GetAuthorAndCommitterUsers(opts.Author, opts.Committer, doer) + if err := moveAnnexedFilesToOrigin(t, author, committer); err != nil { + return err + } + } else { + // Copy uploaded files into repository. + if err := copyUploadedLFSFilesIntoRepository(infos, t, opts.TreePath); err != nil { + return err + } + } // Now write the tree treeHash, err := t.WriteTree() @@ -246,3 +268,38 @@ } return nil } + +func copyUploadedFilesIntoAnnexRepository(infos []uploadInfo, t *TemporaryUploadRepository, treePath string) error { + for i := range len(infos) { + if err := copyUploadedFileIntoAnnexRepository(&infos[i], t, treePath); err != nil { + return err + } + } + return nil +} + +func copyUploadedFileIntoAnnexRepository(info *uploadInfo, t *TemporaryUploadRepository, treePath string) error { + pathInRepo := path.Join(t.basePath, treePath, info.upload.Name) + if err := os.MkdirAll(filepath.Dir(pathInRepo), 0o700); err != nil { + return err + } + if err := os.Rename(info.upload.LocalPath(), pathInRepo); err != nil { + return err + } + return t.AddAnnex(pathInRepo) +} + +func moveAnnexedFilesToOrigin(t *TemporaryUploadRepository, author, committer *user_model.User) error { + authorSig := author.NewGitSig() + committerSig := committer.NewGitSig() + env := append(os.Environ(), + "GIT_AUTHOR_NAME="+authorSig.Name, + "GIT_AUTHOR_EMAIL="+authorSig.Email, + "GIT_COMMITTER_NAME="+committerSig.Name, + "GIT_COMMITTER_EMAIL="+committerSig.Email, + ) + if _, _, err := git.NewCommand(t.ctx, "annex", "move", "--to", "origin").RunStdString(&git.RunOpts{Dir: t.basePath, Env: env}); err != nil { + return err + } + return nil +}