gitea源码

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. // Copyright 2024 The Gitea Authors. All rights reserved.
  2. // SPDX-License-Identifier: MIT
  3. package git
  4. import (
  5. "bufio"
  6. "context"
  7. "fmt"
  8. "os"
  9. "code.gitea.io/gitea/modules/git/gitcmd"
  10. "code.gitea.io/gitea/modules/log"
  11. )
  12. type TemplateSubmoduleCommit struct {
  13. Path string
  14. Commit string
  15. }
  16. // GetTemplateSubmoduleCommits returns a list of submodules paths and their commits from a repository
  17. // This function is only for generating new repos based on existing template, the template couldn't be too large.
  18. func GetTemplateSubmoduleCommits(ctx context.Context, repoPath string) (submoduleCommits []TemplateSubmoduleCommit, _ error) {
  19. stdoutReader, stdoutWriter, err := os.Pipe()
  20. if err != nil {
  21. return nil, err
  22. }
  23. opts := &gitcmd.RunOpts{
  24. Dir: repoPath,
  25. Stdout: stdoutWriter,
  26. PipelineFunc: func(ctx context.Context, cancel context.CancelFunc) error {
  27. _ = stdoutWriter.Close()
  28. defer stdoutReader.Close()
  29. scanner := bufio.NewScanner(stdoutReader)
  30. for scanner.Scan() {
  31. entry, err := parseLsTreeLine(scanner.Bytes())
  32. if err != nil {
  33. cancel()
  34. return err
  35. }
  36. if entry.EntryMode == EntryModeCommit {
  37. submoduleCommits = append(submoduleCommits, TemplateSubmoduleCommit{Path: entry.Name, Commit: entry.ID.String()})
  38. }
  39. }
  40. return scanner.Err()
  41. },
  42. }
  43. err = gitcmd.NewCommand("ls-tree", "-r", "--", "HEAD").Run(ctx, opts)
  44. if err != nil {
  45. return nil, fmt.Errorf("GetTemplateSubmoduleCommits: error running git ls-tree: %v", err)
  46. }
  47. return submoduleCommits, nil
  48. }
  49. // AddTemplateSubmoduleIndexes Adds the given submodules to the git index.
  50. // It is only for generating new repos based on existing template, requires the .gitmodules file to be already present in the work dir.
  51. func AddTemplateSubmoduleIndexes(ctx context.Context, repoPath string, submodules []TemplateSubmoduleCommit) error {
  52. for _, submodule := range submodules {
  53. cmd := gitcmd.NewCommand("update-index", "--add", "--cacheinfo", "160000").AddDynamicArguments(submodule.Commit, submodule.Path)
  54. if stdout, _, err := cmd.RunStdString(ctx, &gitcmd.RunOpts{Dir: repoPath}); err != nil {
  55. log.Error("Unable to add %s as submodule to repo %s: stdout %s\nError: %v", submodule.Path, repoPath, stdout, err)
  56. return err
  57. }
  58. }
  59. return nil
  60. }