mirror of
https://github.com/go-gitea/gitea.git
synced 2025-10-13 12:16:09 +00:00
Move some functions to gitrepo package (#35543)
Refactor Git command functions to use WithXXX methods instead of exposing RunOpts. This change simplifies reuse across gitrepo and improves consistency, encapsulation, and maintainability of command options. --------- Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
This commit is contained in:
@@ -121,7 +121,7 @@ func runRepoSyncReleases(ctx context.Context, _ *cli.Command) error {
|
|||||||
}
|
}
|
||||||
log.Trace("Processing next %d repos of %d", len(repos), count)
|
log.Trace("Processing next %d repos of %d", len(repos), count)
|
||||||
for _, repo := range repos {
|
for _, repo := range repos {
|
||||||
log.Trace("Synchronizing repo %s with path %s", repo.FullName(), repo.RepoPath())
|
log.Trace("Synchronizing repo %s with path %s", repo.FullName(), repo.RelativePath())
|
||||||
gitRepo, err := gitrepo.OpenRepository(ctx, repo)
|
gitRepo, err := gitrepo.OpenRepository(ctx, repo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warn("OpenRepository: %v", err)
|
log.Warn("OpenRepository: %v", err)
|
||||||
@@ -147,7 +147,7 @@ func runRepoSyncReleases(ctx context.Context, _ *cli.Command) error {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Trace(" repo %s releases synchronized to tags: from %d to %d",
|
log.Trace("repo %s releases synchronized to tags: from %d to %d",
|
||||||
repo.FullName(), oldnum, count)
|
repo.FullName(), oldnum, count)
|
||||||
gitRepo.Close()
|
gitRepo.Close()
|
||||||
}
|
}
|
||||||
|
@@ -313,7 +313,7 @@ func runHookPostReceive(ctx context.Context, c *cli.Command) error {
|
|||||||
setup(ctx, c.Bool("debug"))
|
setup(ctx, c.Bool("debug"))
|
||||||
|
|
||||||
// First of all run update-server-info no matter what
|
// First of all run update-server-info no matter what
|
||||||
if _, _, err := gitcmd.NewCommand("update-server-info").RunStdString(ctx, nil); err != nil {
|
if _, _, err := gitcmd.NewCommand("update-server-info").RunStdString(ctx); err != nil {
|
||||||
return fmt.Errorf("failed to call 'git update-server-info': %w", err)
|
return fmt.Errorf("failed to call 'git update-server-info': %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -84,17 +84,17 @@ func FixMergeBase(ctx context.Context, x *xorm.Engine) error {
|
|||||||
|
|
||||||
if !pr.HasMerged {
|
if !pr.HasMerged {
|
||||||
var err error
|
var err error
|
||||||
pr.MergeBase, _, err = gitcmd.NewCommand("merge-base").AddDashesAndList(pr.BaseBranch, gitRefName).RunStdString(ctx, &gitcmd.RunOpts{Dir: repoPath})
|
pr.MergeBase, _, err = gitcmd.NewCommand("merge-base").AddDashesAndList(pr.BaseBranch, gitRefName).WithDir(repoPath).RunStdString(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
var err2 error
|
var err2 error
|
||||||
pr.MergeBase, _, err2 = gitcmd.NewCommand("rev-parse").AddDynamicArguments(git.BranchPrefix+pr.BaseBranch).RunStdString(ctx, &gitcmd.RunOpts{Dir: repoPath})
|
pr.MergeBase, _, err2 = gitcmd.NewCommand("rev-parse").AddDynamicArguments(git.BranchPrefix + pr.BaseBranch).WithDir(repoPath).RunStdString(ctx)
|
||||||
if err2 != nil {
|
if err2 != nil {
|
||||||
log.Error("Unable to get merge base for PR ID %d, Index %d in %s/%s. Error: %v & %v", pr.ID, pr.Index, baseRepo.OwnerName, baseRepo.Name, err, err2)
|
log.Error("Unable to get merge base for PR ID %d, Index %d in %s/%s. Error: %v & %v", pr.ID, pr.Index, baseRepo.OwnerName, baseRepo.Name, err, err2)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
parentsString, _, err := gitcmd.NewCommand("rev-list", "--parents", "-n", "1").AddDynamicArguments(pr.MergedCommitID).RunStdString(ctx, &gitcmd.RunOpts{Dir: repoPath})
|
parentsString, _, err := gitcmd.NewCommand("rev-list", "--parents", "-n", "1").AddDynamicArguments(pr.MergedCommitID).WithDir(repoPath).RunStdString(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Unable to get parents for merged PR ID %d, Index %d in %s/%s. Error: %v", pr.ID, pr.Index, baseRepo.OwnerName, baseRepo.Name, err)
|
log.Error("Unable to get parents for merged PR ID %d, Index %d in %s/%s. Error: %v", pr.ID, pr.Index, baseRepo.OwnerName, baseRepo.Name, err)
|
||||||
continue
|
continue
|
||||||
@@ -108,7 +108,7 @@ func FixMergeBase(ctx context.Context, x *xorm.Engine) error {
|
|||||||
refs = append(refs, gitRefName)
|
refs = append(refs, gitRefName)
|
||||||
cmd := gitcmd.NewCommand("merge-base").AddDashesAndList(refs...)
|
cmd := gitcmd.NewCommand("merge-base").AddDashesAndList(refs...)
|
||||||
|
|
||||||
pr.MergeBase, _, err = cmd.RunStdString(ctx, &gitcmd.RunOpts{Dir: repoPath})
|
pr.MergeBase, _, err = cmd.WithDir(repoPath).RunStdString(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Unable to get merge base for merged PR ID %d, Index %d in %s/%s. Error: %v", pr.ID, pr.Index, baseRepo.OwnerName, baseRepo.Name, err)
|
log.Error("Unable to get merge base for merged PR ID %d, Index %d in %s/%s. Error: %v", pr.ID, pr.Index, baseRepo.OwnerName, baseRepo.Name, err)
|
||||||
continue
|
continue
|
||||||
|
@@ -80,7 +80,7 @@ func RefixMergeBase(ctx context.Context, x *xorm.Engine) error {
|
|||||||
|
|
||||||
gitRefName := fmt.Sprintf("refs/pull/%d/head", pr.Index)
|
gitRefName := fmt.Sprintf("refs/pull/%d/head", pr.Index)
|
||||||
|
|
||||||
parentsString, _, err := gitcmd.NewCommand("rev-list", "--parents", "-n", "1").AddDynamicArguments(pr.MergedCommitID).RunStdString(ctx, &gitcmd.RunOpts{Dir: repoPath})
|
parentsString, _, err := gitcmd.NewCommand("rev-list", "--parents", "-n", "1").AddDynamicArguments(pr.MergedCommitID).WithDir(repoPath).RunStdString(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Unable to get parents for merged PR ID %d, Index %d in %s/%s. Error: %v", pr.ID, pr.Index, baseRepo.OwnerName, baseRepo.Name, err)
|
log.Error("Unable to get parents for merged PR ID %d, Index %d in %s/%s. Error: %v", pr.ID, pr.Index, baseRepo.OwnerName, baseRepo.Name, err)
|
||||||
continue
|
continue
|
||||||
@@ -95,7 +95,7 @@ func RefixMergeBase(ctx context.Context, x *xorm.Engine) error {
|
|||||||
refs = append(refs, gitRefName)
|
refs = append(refs, gitRefName)
|
||||||
cmd := gitcmd.NewCommand("merge-base").AddDashesAndList(refs...)
|
cmd := gitcmd.NewCommand("merge-base").AddDashesAndList(refs...)
|
||||||
|
|
||||||
pr.MergeBase, _, err = cmd.RunStdString(ctx, &gitcmd.RunOpts{Dir: repoPath})
|
pr.MergeBase, _, err = cmd.WithDir(repoPath).RunStdString(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Unable to get merge base for merged PR ID %d, Index %d in %s/%s. Error: %v", pr.ID, pr.Index, baseRepo.OwnerName, baseRepo.Name, err)
|
log.Error("Unable to get merge base for merged PR ID %d, Index %d in %s/%s. Error: %v", pr.ID, pr.Index, baseRepo.OwnerName, baseRepo.Name, err)
|
||||||
continue
|
continue
|
||||||
|
@@ -77,13 +77,12 @@ func NewBatchChecker(repo *git.Repository, treeish string, attributes []string)
|
|||||||
_ = lw.Close()
|
_ = lw.Close()
|
||||||
}()
|
}()
|
||||||
stdErr := new(bytes.Buffer)
|
stdErr := new(bytes.Buffer)
|
||||||
err := cmd.Run(ctx, &gitcmd.RunOpts{
|
err := cmd.WithEnv(envs).
|
||||||
Env: envs,
|
WithDir(repo.Path).
|
||||||
Dir: repo.Path,
|
WithStdin(stdinReader).
|
||||||
Stdin: stdinReader,
|
WithStdout(lw).
|
||||||
Stdout: lw,
|
WithStderr(stdErr).
|
||||||
Stderr: stdErr,
|
Run(ctx)
|
||||||
})
|
|
||||||
|
|
||||||
if err != nil && !git.IsErrCanceledOrKilled(err) {
|
if err != nil && !git.IsErrCanceledOrKilled(err) {
|
||||||
log.Error("Attribute checker for commit %s exits with error: %v", treeish, err)
|
log.Error("Attribute checker for commit %s exits with error: %v", treeish, err)
|
||||||
|
@@ -71,12 +71,11 @@ func CheckAttributes(ctx context.Context, gitRepo *git.Repository, treeish strin
|
|||||||
stdOut := new(bytes.Buffer)
|
stdOut := new(bytes.Buffer)
|
||||||
stdErr := new(bytes.Buffer)
|
stdErr := new(bytes.Buffer)
|
||||||
|
|
||||||
if err := cmd.Run(ctx, &gitcmd.RunOpts{
|
if err := cmd.WithEnv(append(os.Environ(), envs...)).
|
||||||
Env: append(os.Environ(), envs...),
|
WithDir(gitRepo.Path).
|
||||||
Dir: gitRepo.Path,
|
WithStdout(stdOut).
|
||||||
Stdout: stdOut,
|
WithStderr(stdErr).
|
||||||
Stderr: stdErr,
|
Run(ctx); err != nil {
|
||||||
}); err != nil {
|
|
||||||
return nil, fmt.Errorf("failed to run check-attr: %w\n%s\n%s", err, stdOut.String(), stdErr.String())
|
return nil, fmt.Errorf("failed to run check-attr: %w\n%s\n%s", err, stdOut.String(), stdErr.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -31,10 +31,9 @@ type WriteCloserError interface {
|
|||||||
func ensureValidGitRepository(ctx context.Context, repoPath string) error {
|
func ensureValidGitRepository(ctx context.Context, repoPath string) error {
|
||||||
stderr := strings.Builder{}
|
stderr := strings.Builder{}
|
||||||
err := gitcmd.NewCommand("rev-parse").
|
err := gitcmd.NewCommand("rev-parse").
|
||||||
Run(ctx, &gitcmd.RunOpts{
|
WithDir(repoPath).
|
||||||
Dir: repoPath,
|
WithStderr(&stderr).
|
||||||
Stderr: &stderr,
|
Run(ctx)
|
||||||
})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return gitcmd.ConcatenateError(err, (&stderr).String())
|
return gitcmd.ConcatenateError(err, (&stderr).String())
|
||||||
}
|
}
|
||||||
@@ -63,14 +62,12 @@ func catFileBatchCheck(ctx context.Context, repoPath string) (WriteCloserError,
|
|||||||
go func() {
|
go func() {
|
||||||
stderr := strings.Builder{}
|
stderr := strings.Builder{}
|
||||||
err := gitcmd.NewCommand("cat-file", "--batch-check").
|
err := gitcmd.NewCommand("cat-file", "--batch-check").
|
||||||
Run(ctx, &gitcmd.RunOpts{
|
WithDir(repoPath).
|
||||||
Dir: repoPath,
|
WithStdin(batchStdinReader).
|
||||||
Stdin: batchStdinReader,
|
WithStdout(batchStdoutWriter).
|
||||||
Stdout: batchStdoutWriter,
|
WithStderr(&stderr).
|
||||||
Stderr: &stderr,
|
WithUseContextTimeout(true).
|
||||||
|
Run(ctx)
|
||||||
UseContextTimeout: true,
|
|
||||||
})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
_ = batchStdoutWriter.CloseWithError(gitcmd.ConcatenateError(err, (&stderr).String()))
|
_ = batchStdoutWriter.CloseWithError(gitcmd.ConcatenateError(err, (&stderr).String()))
|
||||||
_ = batchStdinReader.CloseWithError(gitcmd.ConcatenateError(err, (&stderr).String()))
|
_ = batchStdinReader.CloseWithError(gitcmd.ConcatenateError(err, (&stderr).String()))
|
||||||
@@ -111,14 +108,12 @@ func catFileBatch(ctx context.Context, repoPath string) (WriteCloserError, *bufi
|
|||||||
go func() {
|
go func() {
|
||||||
stderr := strings.Builder{}
|
stderr := strings.Builder{}
|
||||||
err := gitcmd.NewCommand("cat-file", "--batch").
|
err := gitcmd.NewCommand("cat-file", "--batch").
|
||||||
Run(ctx, &gitcmd.RunOpts{
|
WithDir(repoPath).
|
||||||
Dir: repoPath,
|
WithStdin(batchStdinReader).
|
||||||
Stdin: batchStdinReader,
|
WithStdout(batchStdoutWriter).
|
||||||
Stdout: batchStdoutWriter,
|
WithStderr(&stderr).
|
||||||
Stderr: &stderr,
|
WithUseContextTimeout(true).
|
||||||
|
Run(ctx)
|
||||||
UseContextTimeout: true,
|
|
||||||
})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
_ = batchStdoutWriter.CloseWithError(gitcmd.ConcatenateError(err, (&stderr).String()))
|
_ = batchStdoutWriter.CloseWithError(gitcmd.ConcatenateError(err, (&stderr).String()))
|
||||||
_ = batchStdinReader.CloseWithError(gitcmd.ConcatenateError(err, (&stderr).String()))
|
_ = batchStdinReader.CloseWithError(gitcmd.ConcatenateError(err, (&stderr).String()))
|
||||||
|
@@ -166,12 +166,11 @@ func CreateBlameReader(ctx context.Context, objectFormat ObjectFormat, repoPath
|
|||||||
go func() {
|
go func() {
|
||||||
stderr := bytes.Buffer{}
|
stderr := bytes.Buffer{}
|
||||||
// TODO: it doesn't work for directories (the directories shouldn't be "blamed"), and the "err" should be returned by "Read" but not by "Close"
|
// TODO: it doesn't work for directories (the directories shouldn't be "blamed"), and the "err" should be returned by "Read" but not by "Close"
|
||||||
err := cmd.Run(ctx, &gitcmd.RunOpts{
|
err := cmd.WithDir(repoPath).
|
||||||
UseContextTimeout: true,
|
WithUseContextTimeout(true).
|
||||||
Dir: repoPath,
|
WithStdout(stdout).
|
||||||
Stdout: stdout,
|
WithStderr(&stderr).
|
||||||
Stderr: &stderr,
|
Run(ctx)
|
||||||
})
|
|
||||||
done <- err
|
done <- err
|
||||||
_ = stdout.Close()
|
_ = stdout.Close()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@@ -93,7 +93,7 @@ func AddChanges(ctx context.Context, repoPath string, all bool, files ...string)
|
|||||||
cmd.AddArguments("--all")
|
cmd.AddArguments("--all")
|
||||||
}
|
}
|
||||||
cmd.AddDashesAndList(files...)
|
cmd.AddDashesAndList(files...)
|
||||||
_, _, err := cmd.RunStdString(ctx, &gitcmd.RunOpts{Dir: repoPath})
|
_, _, err := cmd.WithDir(repoPath).RunStdString(ctx)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -122,7 +122,7 @@ func CommitChanges(ctx context.Context, repoPath string, opts CommitChangesOptio
|
|||||||
}
|
}
|
||||||
cmd.AddOptionFormat("--message=%s", opts.Message)
|
cmd.AddOptionFormat("--message=%s", opts.Message)
|
||||||
|
|
||||||
_, _, err := cmd.RunStdString(ctx, &gitcmd.RunOpts{Dir: repoPath})
|
_, _, err := cmd.WithDir(repoPath).RunStdString(ctx)
|
||||||
// No stderr but exit status 1 means nothing to commit.
|
// No stderr but exit status 1 means nothing to commit.
|
||||||
if err != nil && err.Error() == "exit status 1" {
|
if err != nil && err.Error() == "exit status 1" {
|
||||||
return nil
|
return nil
|
||||||
@@ -141,7 +141,7 @@ func AllCommitsCount(ctx context.Context, repoPath string, hidePRRefs bool, file
|
|||||||
cmd.AddDashesAndList(files...)
|
cmd.AddDashesAndList(files...)
|
||||||
}
|
}
|
||||||
|
|
||||||
stdout, _, err := cmd.RunStdString(ctx, &gitcmd.RunOpts{Dir: repoPath})
|
stdout, _, err := cmd.WithDir(repoPath).RunStdString(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
@@ -173,7 +173,7 @@ func CommitsCount(ctx context.Context, opts CommitsCountOptions) (int64, error)
|
|||||||
cmd.AddDashesAndList(opts.RelPath...)
|
cmd.AddDashesAndList(opts.RelPath...)
|
||||||
}
|
}
|
||||||
|
|
||||||
stdout, _, err := cmd.RunStdString(ctx, &gitcmd.RunOpts{Dir: opts.RepoPath})
|
stdout, _, err := cmd.WithDir(opts.RepoPath).RunStdString(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
@@ -208,7 +208,10 @@ func (c *Commit) HasPreviousCommit(objectID ObjectID) (bool, error) {
|
|||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
_, _, err := gitcmd.NewCommand("merge-base", "--is-ancestor").AddDynamicArguments(that, this).RunStdString(c.repo.Ctx, &gitcmd.RunOpts{Dir: c.repo.Path})
|
_, _, err := gitcmd.NewCommand("merge-base", "--is-ancestor").
|
||||||
|
AddDynamicArguments(that, this).
|
||||||
|
WithDir(c.repo.Path).
|
||||||
|
RunStdString(c.repo.Ctx)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
@@ -354,7 +357,7 @@ func (c *Commit) GetBranchName() (string, error) {
|
|||||||
cmd.AddArguments("--exclude", "refs/tags/*")
|
cmd.AddArguments("--exclude", "refs/tags/*")
|
||||||
}
|
}
|
||||||
cmd.AddArguments("--name-only", "--no-undefined").AddDynamicArguments(c.ID.String())
|
cmd.AddArguments("--name-only", "--no-undefined").AddDynamicArguments(c.ID.String())
|
||||||
data, _, err := cmd.RunStdString(c.repo.Ctx, &gitcmd.RunOpts{Dir: c.repo.Path})
|
data, _, err := cmd.WithDir(c.repo.Path).RunStdString(c.repo.Ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// handle special case where git can not describe commit
|
// handle special case where git can not describe commit
|
||||||
if strings.Contains(err.Error(), "cannot describe") {
|
if strings.Contains(err.Error(), "cannot describe") {
|
||||||
@@ -432,11 +435,12 @@ func GetCommitFileStatus(ctx context.Context, repoPath, commitID string) (*Commi
|
|||||||
}()
|
}()
|
||||||
|
|
||||||
stderr := new(bytes.Buffer)
|
stderr := new(bytes.Buffer)
|
||||||
err := gitcmd.NewCommand("log", "--name-status", "-m", "--pretty=format:", "--first-parent", "--no-renames", "-z", "-1").AddDynamicArguments(commitID).Run(ctx, &gitcmd.RunOpts{
|
err := gitcmd.NewCommand("log", "--name-status", "-m", "--pretty=format:", "--first-parent", "--no-renames", "-z", "-1").
|
||||||
Dir: repoPath,
|
AddDynamicArguments(commitID).
|
||||||
Stdout: w,
|
WithDir(repoPath).
|
||||||
Stderr: stderr,
|
WithStdout(w).
|
||||||
})
|
WithStderr(stderr).
|
||||||
|
Run(ctx)
|
||||||
w.Close() // Close writer to exit parsing goroutine
|
w.Close() // Close writer to exit parsing goroutine
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, gitcmd.ConcatenateError(err, stderr.String())
|
return nil, gitcmd.ConcatenateError(err, stderr.String())
|
||||||
@@ -448,7 +452,10 @@ func GetCommitFileStatus(ctx context.Context, repoPath, commitID string) (*Commi
|
|||||||
|
|
||||||
// GetFullCommitID returns full length (40) of commit ID by given short SHA in a repository.
|
// GetFullCommitID returns full length (40) of commit ID by given short SHA in a repository.
|
||||||
func GetFullCommitID(ctx context.Context, repoPath, shortID string) (string, error) {
|
func GetFullCommitID(ctx context.Context, repoPath, shortID string) (string, error) {
|
||||||
commitID, _, err := gitcmd.NewCommand("rev-parse").AddDynamicArguments(shortID).RunStdString(ctx, &gitcmd.RunOpts{Dir: repoPath})
|
commitID, _, err := gitcmd.NewCommand("rev-parse").
|
||||||
|
AddDynamicArguments(shortID).
|
||||||
|
WithDir(repoPath).
|
||||||
|
RunStdString(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if strings.Contains(err.Error(), "exit status 128") {
|
if strings.Contains(err.Error(), "exit status 128") {
|
||||||
return "", ErrNotExist{shortID, ""}
|
return "", ErrNotExist{shortID, ""}
|
||||||
|
@@ -118,7 +118,9 @@ func syncGitConfig(ctx context.Context) (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func configSet(ctx context.Context, key, value string) error {
|
func configSet(ctx context.Context, key, value string) error {
|
||||||
stdout, _, err := gitcmd.NewCommand("config", "--global", "--get").AddDynamicArguments(key).RunStdString(ctx, nil)
|
stdout, _, err := gitcmd.NewCommand("config", "--global", "--get").
|
||||||
|
AddDynamicArguments(key).
|
||||||
|
RunStdString(ctx)
|
||||||
if err != nil && !gitcmd.IsErrorExitCode(err, 1) {
|
if err != nil && !gitcmd.IsErrorExitCode(err, 1) {
|
||||||
return fmt.Errorf("failed to get git config %s, err: %w", key, err)
|
return fmt.Errorf("failed to get git config %s, err: %w", key, err)
|
||||||
}
|
}
|
||||||
@@ -128,8 +130,9 @@ func configSet(ctx context.Context, key, value string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
_, _, err = gitcmd.NewCommand("config", "--global").AddDynamicArguments(key, value).RunStdString(ctx, nil)
|
if _, _, err = gitcmd.NewCommand("config", "--global").
|
||||||
if err != nil {
|
AddDynamicArguments(key, value).
|
||||||
|
RunStdString(ctx); err != nil {
|
||||||
return fmt.Errorf("failed to set git global config %s, err: %w", key, err)
|
return fmt.Errorf("failed to set git global config %s, err: %w", key, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -137,14 +140,14 @@ func configSet(ctx context.Context, key, value string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func configSetNonExist(ctx context.Context, key, value string) error {
|
func configSetNonExist(ctx context.Context, key, value string) error {
|
||||||
_, _, err := gitcmd.NewCommand("config", "--global", "--get").AddDynamicArguments(key).RunStdString(ctx, nil)
|
_, _, err := gitcmd.NewCommand("config", "--global", "--get").AddDynamicArguments(key).RunStdString(ctx)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
// already exist
|
// already exist
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if gitcmd.IsErrorExitCode(err, 1) {
|
if gitcmd.IsErrorExitCode(err, 1) {
|
||||||
// not exist, set new config
|
// not exist, set new config
|
||||||
_, _, err = gitcmd.NewCommand("config", "--global").AddDynamicArguments(key, value).RunStdString(ctx, nil)
|
_, _, err = gitcmd.NewCommand("config", "--global").AddDynamicArguments(key, value).RunStdString(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to set git global config %s, err: %w", key, err)
|
return fmt.Errorf("failed to set git global config %s, err: %w", key, err)
|
||||||
}
|
}
|
||||||
@@ -155,14 +158,14 @@ func configSetNonExist(ctx context.Context, key, value string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func configAddNonExist(ctx context.Context, key, value string) error {
|
func configAddNonExist(ctx context.Context, key, value string) error {
|
||||||
_, _, err := gitcmd.NewCommand("config", "--global", "--get").AddDynamicArguments(key, regexp.QuoteMeta(value)).RunStdString(ctx, nil)
|
_, _, err := gitcmd.NewCommand("config", "--global", "--get").AddDynamicArguments(key, regexp.QuoteMeta(value)).RunStdString(ctx)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
// already exist
|
// already exist
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if gitcmd.IsErrorExitCode(err, 1) {
|
if gitcmd.IsErrorExitCode(err, 1) {
|
||||||
// not exist, add new config
|
// not exist, add new config
|
||||||
_, _, err = gitcmd.NewCommand("config", "--global", "--add").AddDynamicArguments(key, value).RunStdString(ctx, nil)
|
_, _, err = gitcmd.NewCommand("config", "--global", "--add").AddDynamicArguments(key, value).RunStdString(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to add git global config %s, err: %w", key, err)
|
return fmt.Errorf("failed to add git global config %s, err: %w", key, err)
|
||||||
}
|
}
|
||||||
@@ -172,10 +175,10 @@ func configAddNonExist(ctx context.Context, key, value string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func configUnsetAll(ctx context.Context, key, value string) error {
|
func configUnsetAll(ctx context.Context, key, value string) error {
|
||||||
_, _, err := gitcmd.NewCommand("config", "--global", "--get").AddDynamicArguments(key).RunStdString(ctx, nil)
|
_, _, err := gitcmd.NewCommand("config", "--global", "--get").AddDynamicArguments(key).RunStdString(ctx)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
// exist, need to remove
|
// exist, need to remove
|
||||||
_, _, err = gitcmd.NewCommand("config", "--global", "--unset-all").AddDynamicArguments(key, regexp.QuoteMeta(value)).RunStdString(ctx, nil)
|
_, _, err = gitcmd.NewCommand("config", "--global", "--unset-all").AddDynamicArguments(key, regexp.QuoteMeta(value)).RunStdString(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to unset git global config %s, err: %w", key, err)
|
return fmt.Errorf("failed to unset git global config %s, err: %w", key, err)
|
||||||
}
|
}
|
||||||
|
@@ -35,12 +35,12 @@ func GetRawDiff(repo *Repository, commitID string, diffType RawDiffType, writer
|
|||||||
// GetReverseRawDiff dumps the reverse diff results of repository in given commit ID to io.Writer.
|
// GetReverseRawDiff dumps the reverse diff results of repository in given commit ID to io.Writer.
|
||||||
func GetReverseRawDiff(ctx context.Context, repoPath, commitID string, writer io.Writer) error {
|
func GetReverseRawDiff(ctx context.Context, repoPath, commitID string, writer io.Writer) error {
|
||||||
stderr := new(bytes.Buffer)
|
stderr := new(bytes.Buffer)
|
||||||
cmd := gitcmd.NewCommand("show", "--pretty=format:revert %H%n", "-R").AddDynamicArguments(commitID)
|
if err := gitcmd.NewCommand("show", "--pretty=format:revert %H%n", "-R").
|
||||||
if err := cmd.Run(ctx, &gitcmd.RunOpts{
|
AddDynamicArguments(commitID).
|
||||||
Dir: repoPath,
|
WithDir(repoPath).
|
||||||
Stdout: writer,
|
WithStdout(writer).
|
||||||
Stderr: stderr,
|
WithStderr(stderr).
|
||||||
}); err != nil {
|
Run(ctx); err != nil {
|
||||||
return fmt.Errorf("Run: %w - %s", err, stderr)
|
return fmt.Errorf("Run: %w - %s", err, stderr)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@@ -90,11 +90,10 @@ func GetRepoRawDiffForFile(repo *Repository, startCommit, endCommit string, diff
|
|||||||
}
|
}
|
||||||
|
|
||||||
stderr := new(bytes.Buffer)
|
stderr := new(bytes.Buffer)
|
||||||
if err = cmd.Run(repo.Ctx, &gitcmd.RunOpts{
|
if err = cmd.WithDir(repo.Path).
|
||||||
Dir: repo.Path,
|
WithStdout(writer).
|
||||||
Stdout: writer,
|
WithStderr(stderr).
|
||||||
Stderr: stderr,
|
Run(repo.Ctx); err != nil {
|
||||||
}); err != nil {
|
|
||||||
return fmt.Errorf("Run: %w - %s", err, stderr)
|
return fmt.Errorf("Run: %w - %s", err, stderr)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@@ -314,29 +313,28 @@ func GetAffectedFiles(repo *Repository, branchName, oldCommitID, newCommitID str
|
|||||||
|
|
||||||
// Run `git diff --name-only` to get the names of the changed files
|
// Run `git diff --name-only` to get the names of the changed files
|
||||||
err = gitcmd.NewCommand("diff", "--name-only").AddDynamicArguments(oldCommitID, newCommitID).
|
err = gitcmd.NewCommand("diff", "--name-only").AddDynamicArguments(oldCommitID, newCommitID).
|
||||||
Run(repo.Ctx, &gitcmd.RunOpts{
|
WithEnv(env).
|
||||||
Env: env,
|
WithDir(repo.Path).
|
||||||
Dir: repo.Path,
|
WithStdout(stdoutWriter).
|
||||||
Stdout: stdoutWriter,
|
WithPipelineFunc(func(ctx context.Context, cancel context.CancelFunc) error {
|
||||||
PipelineFunc: func(ctx context.Context, cancel context.CancelFunc) error {
|
// Close the writer end of the pipe to begin processing
|
||||||
// Close the writer end of the pipe to begin processing
|
_ = stdoutWriter.Close()
|
||||||
_ = stdoutWriter.Close()
|
defer func() {
|
||||||
defer func() {
|
// Close the reader on return to terminate the git command if necessary
|
||||||
// Close the reader on return to terminate the git command if necessary
|
_ = stdoutReader.Close()
|
||||||
_ = stdoutReader.Close()
|
}()
|
||||||
}()
|
// Now scan the output from the command
|
||||||
// Now scan the output from the command
|
scanner := bufio.NewScanner(stdoutReader)
|
||||||
scanner := bufio.NewScanner(stdoutReader)
|
for scanner.Scan() {
|
||||||
for scanner.Scan() {
|
path := strings.TrimSpace(scanner.Text())
|
||||||
path := strings.TrimSpace(scanner.Text())
|
if len(path) == 0 {
|
||||||
if len(path) == 0 {
|
continue
|
||||||
continue
|
|
||||||
}
|
|
||||||
affectedFiles = append(affectedFiles, path)
|
|
||||||
}
|
}
|
||||||
return scanner.Err()
|
affectedFiles = append(affectedFiles, path)
|
||||||
},
|
}
|
||||||
})
|
return scanner.Err()
|
||||||
|
}).
|
||||||
|
Run(repo.Ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Unable to get affected files for commits from %s to %s in %s: %v", oldCommitID, newCommitID, repo.Path, err)
|
log.Error("Unable to get affected files for commits from %s to %s in %s: %v", oldCommitID, newCommitID, repo.Path, err)
|
||||||
}
|
}
|
||||||
|
@@ -57,7 +57,7 @@ func DefaultFeatures() *Features {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func loadGitVersionFeatures() (*Features, error) {
|
func loadGitVersionFeatures() (*Features, error) {
|
||||||
stdout, _, runErr := gitcmd.NewCommand("version").RunStdString(context.Background(), nil)
|
stdout, _, runErr := gitcmd.NewCommand("version").RunStdString(context.Background())
|
||||||
if runErr != nil {
|
if runErr != nil {
|
||||||
return nil, runErr
|
return nil, runErr
|
||||||
}
|
}
|
||||||
|
@@ -46,6 +46,7 @@ type Command struct {
|
|||||||
brokenArgs []string
|
brokenArgs []string
|
||||||
cmd *exec.Cmd // for debug purpose only
|
cmd *exec.Cmd // for debug purpose only
|
||||||
configArgs []string
|
configArgs []string
|
||||||
|
opts runOpts
|
||||||
}
|
}
|
||||||
|
|
||||||
func logArgSanitize(arg string) string {
|
func logArgSanitize(arg string) string {
|
||||||
@@ -194,8 +195,8 @@ func ToTrustedCmdArgs(args []string) TrustedCmdArgs {
|
|||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
// RunOpts represents parameters to run the command. If UseContextTimeout is specified, then Timeout is ignored.
|
// runOpts represents parameters to run the command. If UseContextTimeout is specified, then Timeout is ignored.
|
||||||
type RunOpts struct {
|
type runOpts struct {
|
||||||
Env []string
|
Env []string
|
||||||
Timeout time.Duration
|
Timeout time.Duration
|
||||||
UseContextTimeout bool
|
UseContextTimeout bool
|
||||||
@@ -221,6 +222,8 @@ type RunOpts struct {
|
|||||||
Stdin io.Reader
|
Stdin io.Reader
|
||||||
|
|
||||||
PipelineFunc func(context.Context, context.CancelFunc) error
|
PipelineFunc func(context.Context, context.CancelFunc) error
|
||||||
|
|
||||||
|
callerInfo string
|
||||||
}
|
}
|
||||||
|
|
||||||
func commonBaseEnvs() []string {
|
func commonBaseEnvs() []string {
|
||||||
@@ -263,44 +266,99 @@ func CommonCmdServEnvs() []string {
|
|||||||
|
|
||||||
var ErrBrokenCommand = errors.New("git command is broken")
|
var ErrBrokenCommand = errors.New("git command is broken")
|
||||||
|
|
||||||
// Run runs the command with the RunOpts
|
func (c *Command) WithDir(dir string) *Command {
|
||||||
func (c *Command) Run(ctx context.Context, opts *RunOpts) error {
|
c.opts.Dir = dir
|
||||||
return c.run(ctx, 1, opts)
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Command) run(ctx context.Context, skip int, opts *RunOpts) error {
|
func (c *Command) WithEnv(env []string) *Command {
|
||||||
|
c.opts.Env = env
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Command) WithTimeout(timeout time.Duration) *Command {
|
||||||
|
c.opts.Timeout = timeout
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Command) WithStdout(stdout io.Writer) *Command {
|
||||||
|
c.opts.Stdout = stdout
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Command) WithStderr(stderr io.Writer) *Command {
|
||||||
|
c.opts.Stderr = stderr
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Command) WithStdin(stdin io.Reader) *Command {
|
||||||
|
c.opts.Stdin = stdin
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Command) WithPipelineFunc(f func(context.Context, context.CancelFunc) error) *Command {
|
||||||
|
c.opts.PipelineFunc = f
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Command) WithUseContextTimeout(useContextTimeout bool) *Command {
|
||||||
|
c.opts.UseContextTimeout = useContextTimeout
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithParentCallerInfo can be used to set the caller info (usually function name) of the parent function of the caller.
|
||||||
|
// For most cases, "Run" family functions can get its caller info automatically
|
||||||
|
// But if you need to call "Run" family functions in a wrapper function: "FeatureFunc -> GeneralWrapperFunc -> RunXxx",
|
||||||
|
// then you can to call this function in GeneralWrapperFunc to set the caller info of FeatureFunc.
|
||||||
|
// The caller info can only be set once.
|
||||||
|
func (c *Command) WithParentCallerInfo(optInfo ...string) *Command {
|
||||||
|
if c.opts.callerInfo != "" {
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
if len(optInfo) > 0 {
|
||||||
|
c.opts.callerInfo = optInfo[0]
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
skip := 1 /*parent "wrap/run" functions*/ + 1 /*this function*/
|
||||||
|
callerFuncName := util.CallerFuncName(skip)
|
||||||
|
callerInfo := callerFuncName
|
||||||
|
if pos := strings.LastIndex(callerInfo, "/"); pos >= 0 {
|
||||||
|
callerInfo = callerInfo[pos+1:]
|
||||||
|
}
|
||||||
|
c.opts.callerInfo = callerInfo
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run runs the command
|
||||||
|
func (c *Command) Run(ctx context.Context) error {
|
||||||
if len(c.brokenArgs) != 0 {
|
if len(c.brokenArgs) != 0 {
|
||||||
log.Error("git command is broken: %s, broken args: %s", c.LogString(), strings.Join(c.brokenArgs, " "))
|
log.Error("git command is broken: %s, broken args: %s", c.LogString(), strings.Join(c.brokenArgs, " "))
|
||||||
return ErrBrokenCommand
|
return ErrBrokenCommand
|
||||||
}
|
}
|
||||||
if opts == nil {
|
|
||||||
opts = &RunOpts{}
|
|
||||||
}
|
|
||||||
|
|
||||||
// We must not change the provided options
|
// We must not change the provided options
|
||||||
timeout := opts.Timeout
|
timeout := c.opts.Timeout
|
||||||
if timeout <= 0 {
|
if timeout <= 0 {
|
||||||
timeout = defaultCommandExecutionTimeout
|
timeout = defaultCommandExecutionTimeout
|
||||||
}
|
}
|
||||||
|
|
||||||
cmdLogString := c.LogString()
|
cmdLogString := c.LogString()
|
||||||
callerInfo := util.CallerFuncName(1 /* util */ + 1 /* this */ + skip /* parent */)
|
if c.opts.callerInfo == "" {
|
||||||
if pos := strings.LastIndex(callerInfo, "/"); pos >= 0 {
|
c.WithParentCallerInfo()
|
||||||
callerInfo = callerInfo[pos+1:]
|
|
||||||
}
|
}
|
||||||
// these logs are for debugging purposes only, so no guarantee of correctness or stability
|
// these logs are for debugging purposes only, so no guarantee of correctness or stability
|
||||||
desc := fmt.Sprintf("git.Run(by:%s, repo:%s): %s", callerInfo, logArgSanitize(opts.Dir), cmdLogString)
|
desc := fmt.Sprintf("git.Run(by:%s, repo:%s): %s", c.opts.callerInfo, logArgSanitize(c.opts.Dir), cmdLogString)
|
||||||
log.Debug("git.Command: %s", desc)
|
log.Debug("git.Command: %s", desc)
|
||||||
|
|
||||||
_, span := gtprof.GetTracer().Start(ctx, gtprof.TraceSpanGitRun)
|
_, span := gtprof.GetTracer().Start(ctx, gtprof.TraceSpanGitRun)
|
||||||
defer span.End()
|
defer span.End()
|
||||||
span.SetAttributeString(gtprof.TraceAttrFuncCaller, callerInfo)
|
span.SetAttributeString(gtprof.TraceAttrFuncCaller, c.opts.callerInfo)
|
||||||
span.SetAttributeString(gtprof.TraceAttrGitCommand, cmdLogString)
|
span.SetAttributeString(gtprof.TraceAttrGitCommand, cmdLogString)
|
||||||
|
|
||||||
var cancel context.CancelFunc
|
var cancel context.CancelFunc
|
||||||
var finished context.CancelFunc
|
var finished context.CancelFunc
|
||||||
|
|
||||||
if opts.UseContextTimeout {
|
if c.opts.UseContextTimeout {
|
||||||
ctx, cancel, finished = process.GetManager().AddContext(ctx, desc)
|
ctx, cancel, finished = process.GetManager().AddContext(ctx, desc)
|
||||||
} else {
|
} else {
|
||||||
ctx, cancel, finished = process.GetManager().AddContextTimeout(ctx, timeout, desc)
|
ctx, cancel, finished = process.GetManager().AddContextTimeout(ctx, timeout, desc)
|
||||||
@@ -311,24 +369,24 @@ func (c *Command) run(ctx context.Context, skip int, opts *RunOpts) error {
|
|||||||
|
|
||||||
cmd := exec.CommandContext(ctx, c.prog, append(c.configArgs, c.args...)...)
|
cmd := exec.CommandContext(ctx, c.prog, append(c.configArgs, c.args...)...)
|
||||||
c.cmd = cmd // for debug purpose only
|
c.cmd = cmd // for debug purpose only
|
||||||
if opts.Env == nil {
|
if c.opts.Env == nil {
|
||||||
cmd.Env = os.Environ()
|
cmd.Env = os.Environ()
|
||||||
} else {
|
} else {
|
||||||
cmd.Env = opts.Env
|
cmd.Env = c.opts.Env
|
||||||
}
|
}
|
||||||
|
|
||||||
process.SetSysProcAttribute(cmd)
|
process.SetSysProcAttribute(cmd)
|
||||||
cmd.Env = append(cmd.Env, CommonGitCmdEnvs()...)
|
cmd.Env = append(cmd.Env, CommonGitCmdEnvs()...)
|
||||||
cmd.Dir = opts.Dir
|
cmd.Dir = c.opts.Dir
|
||||||
cmd.Stdout = opts.Stdout
|
cmd.Stdout = c.opts.Stdout
|
||||||
cmd.Stderr = opts.Stderr
|
cmd.Stderr = c.opts.Stderr
|
||||||
cmd.Stdin = opts.Stdin
|
cmd.Stdin = c.opts.Stdin
|
||||||
if err := cmd.Start(); err != nil {
|
if err := cmd.Start(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if opts.PipelineFunc != nil {
|
if c.opts.PipelineFunc != nil {
|
||||||
err := opts.PipelineFunc(ctx, cancel)
|
err := c.opts.PipelineFunc(ctx, cancel)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
cancel()
|
cancel()
|
||||||
_ = cmd.Wait()
|
_ = cmd.Wait()
|
||||||
@@ -374,7 +432,8 @@ type runStdError struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *runStdError) Error() string {
|
func (r *runStdError) Error() string {
|
||||||
// the stderr must be in the returned error text, some code only checks `strings.Contains(err.Error(), "git error")`
|
// FIXME: GIT-CMD-STDERR: it is a bad design, the stderr should not be put in the error message
|
||||||
|
// But a lof of code only checks `strings.Contains(err.Error(), "git error")`
|
||||||
if r.errMsg == "" {
|
if r.errMsg == "" {
|
||||||
r.errMsg = ConcatenateError(r.err, r.stderr).Error()
|
r.errMsg = ConcatenateError(r.err, r.stderr).Error()
|
||||||
}
|
}
|
||||||
@@ -397,51 +456,33 @@ func IsErrorExitCode(err error, code int) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// RunStdString runs the command with options and returns stdout/stderr as string. and store stderr to returned error (err combined with stderr).
|
// RunStdString runs the command and returns stdout/stderr as string. and store stderr to returned error (err combined with stderr).
|
||||||
func (c *Command) RunStdString(ctx context.Context, opts *RunOpts) (stdout, stderr string, runErr RunStdError) {
|
func (c *Command) RunStdString(ctx context.Context) (stdout, stderr string, runErr RunStdError) {
|
||||||
stdoutBytes, stderrBytes, err := c.runStdBytes(ctx, opts)
|
stdoutBytes, stderrBytes, runErr := c.WithParentCallerInfo().runStdBytes(ctx)
|
||||||
stdout = util.UnsafeBytesToString(stdoutBytes)
|
return util.UnsafeBytesToString(stdoutBytes), util.UnsafeBytesToString(stderrBytes), runErr
|
||||||
stderr = util.UnsafeBytesToString(stderrBytes)
|
|
||||||
if err != nil {
|
|
||||||
return stdout, stderr, &runStdError{err: err, stderr: stderr}
|
|
||||||
}
|
|
||||||
// even if there is no err, there could still be some stderr output, so we just return stdout/stderr as they are
|
|
||||||
return stdout, stderr, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// RunStdBytes runs the command with options and returns stdout/stderr as bytes. and store stderr to returned error (err combined with stderr).
|
// RunStdBytes runs the command and returns stdout/stderr as bytes. and store stderr to returned error (err combined with stderr).
|
||||||
func (c *Command) RunStdBytes(ctx context.Context, opts *RunOpts) (stdout, stderr []byte, runErr RunStdError) {
|
func (c *Command) RunStdBytes(ctx context.Context) (stdout, stderr []byte, runErr RunStdError) {
|
||||||
return c.runStdBytes(ctx, opts)
|
return c.WithParentCallerInfo().runStdBytes(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Command) runStdBytes(ctx context.Context, opts *RunOpts) (stdout, stderr []byte, runErr RunStdError) {
|
func (c *Command) runStdBytes(ctx context.Context) ( /*stdout*/ []byte /*stderr*/, []byte /*runErr*/, RunStdError) {
|
||||||
if opts == nil {
|
if c.opts.Stdout != nil || c.opts.Stderr != nil {
|
||||||
opts = &RunOpts{}
|
|
||||||
}
|
|
||||||
if opts.Stdout != nil || opts.Stderr != nil {
|
|
||||||
// we must panic here, otherwise there would be bugs if developers set Stdin/Stderr by mistake, and it would be very difficult to debug
|
// we must panic here, otherwise there would be bugs if developers set Stdin/Stderr by mistake, and it would be very difficult to debug
|
||||||
panic("stdout and stderr field must be nil when using RunStdBytes")
|
panic("stdout and stderr field must be nil when using RunStdBytes")
|
||||||
}
|
}
|
||||||
stdoutBuf := &bytes.Buffer{}
|
stdoutBuf := &bytes.Buffer{}
|
||||||
stderrBuf := &bytes.Buffer{}
|
stderrBuf := &bytes.Buffer{}
|
||||||
|
err := c.WithParentCallerInfo().
|
||||||
// We must not change the provided options as it could break future calls - therefore make a copy.
|
WithStdout(stdoutBuf).
|
||||||
newOpts := &RunOpts{
|
WithStderr(stderrBuf).
|
||||||
Env: opts.Env,
|
Run(ctx)
|
||||||
Timeout: opts.Timeout,
|
|
||||||
UseContextTimeout: opts.UseContextTimeout,
|
|
||||||
Dir: opts.Dir,
|
|
||||||
Stdout: stdoutBuf,
|
|
||||||
Stderr: stderrBuf,
|
|
||||||
Stdin: opts.Stdin,
|
|
||||||
PipelineFunc: opts.PipelineFunc,
|
|
||||||
}
|
|
||||||
|
|
||||||
err := c.run(ctx, 2, newOpts)
|
|
||||||
stderr = stderrBuf.Bytes()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, stderr, &runStdError{err: err, stderr: util.UnsafeBytesToString(stderr)}
|
// FIXME: GIT-CMD-STDERR: it is a bad design, the stderr should not be put in the error message
|
||||||
|
// But a lot of code depends on it, so we have to keep this behavior
|
||||||
|
return nil, stderrBuf.Bytes(), &runStdError{err: err, stderr: util.UnsafeBytesToString(stderrBuf.Bytes())}
|
||||||
}
|
}
|
||||||
// even if there is no err, there could still be some stderr output
|
// even if there is no err, there could still be some stderr output
|
||||||
return stdoutBuf.Bytes(), stderr, nil
|
return stdoutBuf.Bytes(), stderrBuf.Bytes(), nil
|
||||||
}
|
}
|
||||||
|
@@ -17,7 +17,7 @@ func TestRunWithContextNoTimeout(t *testing.T) {
|
|||||||
// 'git --version' does not block so it must be finished before the timeout triggered.
|
// 'git --version' does not block so it must be finished before the timeout triggered.
|
||||||
cmd := NewCommand("--version")
|
cmd := NewCommand("--version")
|
||||||
for i := 0; i < maxLoops; i++ {
|
for i := 0; i < maxLoops; i++ {
|
||||||
if err := cmd.Run(t.Context(), &RunOpts{}); err != nil {
|
if err := cmd.Run(t.Context()); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -29,7 +29,7 @@ func TestRunWithContextTimeout(t *testing.T) {
|
|||||||
// 'git hash-object --stdin' blocks on stdin so we can have the timeout triggered.
|
// 'git hash-object --stdin' blocks on stdin so we can have the timeout triggered.
|
||||||
cmd := NewCommand("hash-object", "--stdin")
|
cmd := NewCommand("hash-object", "--stdin")
|
||||||
for i := 0; i < maxLoops; i++ {
|
for i := 0; i < maxLoops; i++ {
|
||||||
if err := cmd.Run(t.Context(), &RunOpts{Timeout: 1 * time.Millisecond}); err != nil {
|
if err := cmd.WithTimeout(1 * time.Millisecond).Run(t.Context()); err != nil {
|
||||||
if err != context.DeadlineExceeded {
|
if err != context.DeadlineExceeded {
|
||||||
t.Fatalf("Testing %d/%d: %v", i, maxLoops, err)
|
t.Fatalf("Testing %d/%d: %v", i, maxLoops, err)
|
||||||
}
|
}
|
||||||
|
@@ -23,38 +23,60 @@ func TestMain(m *testing.M) {
|
|||||||
defer cleanup()
|
defer cleanup()
|
||||||
|
|
||||||
setting.Git.HomePath = gitHomePath
|
setting.Git.HomePath = gitHomePath
|
||||||
|
os.Exit(m.Run())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRunWithContextStd(t *testing.T) {
|
func TestRunWithContextStd(t *testing.T) {
|
||||||
cmd := NewCommand("--version")
|
{
|
||||||
stdout, stderr, err := cmd.RunStdString(t.Context(), &RunOpts{})
|
cmd := NewCommand("--version")
|
||||||
assert.NoError(t, err)
|
stdout, stderr, err := cmd.RunStdString(t.Context())
|
||||||
assert.Empty(t, stderr)
|
assert.NoError(t, err)
|
||||||
assert.Contains(t, stdout, "git version")
|
assert.Empty(t, stderr)
|
||||||
|
assert.Contains(t, stdout, "git version")
|
||||||
cmd = NewCommand("--no-such-arg")
|
|
||||||
stdout, stderr, err = cmd.RunStdString(t.Context(), &RunOpts{})
|
|
||||||
if assert.Error(t, err) {
|
|
||||||
assert.Equal(t, stderr, err.Stderr())
|
|
||||||
assert.Contains(t, err.Stderr(), "unknown option:")
|
|
||||||
assert.Contains(t, err.Error(), "exit status 129 - unknown option:")
|
|
||||||
assert.Empty(t, stdout)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd = NewCommand()
|
{
|
||||||
cmd.AddDynamicArguments("-test")
|
cmd := NewCommand("ls-tree", "no-such")
|
||||||
assert.ErrorIs(t, cmd.Run(t.Context(), &RunOpts{}), ErrBrokenCommand)
|
stdout, stderr, err := cmd.RunStdString(t.Context())
|
||||||
|
if assert.Error(t, err) {
|
||||||
|
assert.Equal(t, stderr, err.Stderr())
|
||||||
|
assert.Equal(t, "fatal: Not a valid object name no-such\n", err.Stderr())
|
||||||
|
// FIXME: GIT-CMD-STDERR: it is a bad design, the stderr should not be put in the error message
|
||||||
|
assert.Equal(t, "exit status 128 - fatal: Not a valid object name no-such\n", err.Error())
|
||||||
|
assert.Empty(t, stdout)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
cmd = NewCommand()
|
{
|
||||||
cmd.AddDynamicArguments("--test")
|
cmd := NewCommand("ls-tree", "no-such")
|
||||||
assert.ErrorIs(t, cmd.Run(t.Context(), &RunOpts{}), ErrBrokenCommand)
|
stdout, stderr, err := cmd.RunStdBytes(t.Context())
|
||||||
|
if assert.Error(t, err) {
|
||||||
|
assert.Equal(t, string(stderr), err.Stderr())
|
||||||
|
assert.Equal(t, "fatal: Not a valid object name no-such\n", err.Stderr())
|
||||||
|
// FIXME: GIT-CMD-STDERR: it is a bad design, the stderr should not be put in the error message
|
||||||
|
assert.Equal(t, "exit status 128 - fatal: Not a valid object name no-such\n", err.Error())
|
||||||
|
assert.Empty(t, stdout)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
subCmd := "version"
|
{
|
||||||
cmd = NewCommand().AddDynamicArguments(subCmd) // for test purpose only, the sub-command should never be dynamic for production
|
cmd := NewCommand()
|
||||||
stdout, stderr, err = cmd.RunStdString(t.Context(), &RunOpts{})
|
cmd.AddDynamicArguments("-test")
|
||||||
assert.NoError(t, err)
|
assert.ErrorIs(t, cmd.Run(t.Context()), ErrBrokenCommand)
|
||||||
assert.Empty(t, stderr)
|
|
||||||
assert.Contains(t, stdout, "git version")
|
cmd = NewCommand()
|
||||||
|
cmd.AddDynamicArguments("--test")
|
||||||
|
assert.ErrorIs(t, cmd.Run(t.Context()), ErrBrokenCommand)
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
subCmd := "version"
|
||||||
|
cmd := NewCommand().AddDynamicArguments(subCmd) // for test purpose only, the sub-command should never be dynamic for production
|
||||||
|
stdout, stderr, err := cmd.RunStdString(t.Context())
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Empty(t, stderr)
|
||||||
|
assert.Contains(t, stdout, "git version")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGitArgument(t *testing.T) {
|
func TestGitArgument(t *testing.T) {
|
||||||
|
@@ -84,11 +84,10 @@ func GrepSearch(ctx context.Context, repo *Repository, search string, opts GrepO
|
|||||||
cmd.AddDashesAndList(opts.PathspecList...)
|
cmd.AddDashesAndList(opts.PathspecList...)
|
||||||
opts.MaxResultLimit = util.IfZero(opts.MaxResultLimit, 50)
|
opts.MaxResultLimit = util.IfZero(opts.MaxResultLimit, 50)
|
||||||
stderr := bytes.Buffer{}
|
stderr := bytes.Buffer{}
|
||||||
err = cmd.Run(ctx, &gitcmd.RunOpts{
|
err = cmd.WithDir(repo.Path).
|
||||||
Dir: repo.Path,
|
WithStdout(stdoutWriter).
|
||||||
Stdout: stdoutWriter,
|
WithStderr(&stderr).
|
||||||
Stderr: &stderr,
|
WithPipelineFunc(func(ctx context.Context, cancel context.CancelFunc) error {
|
||||||
PipelineFunc: func(ctx context.Context, cancel context.CancelFunc) error {
|
|
||||||
_ = stdoutWriter.Close()
|
_ = stdoutWriter.Close()
|
||||||
defer stdoutReader.Close()
|
defer stdoutReader.Close()
|
||||||
|
|
||||||
@@ -133,8 +132,8 @@ func GrepSearch(ctx context.Context, repo *Repository, search string, opts GrepO
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
},
|
}).
|
||||||
})
|
Run(ctx)
|
||||||
// git grep exits by cancel (killed), usually it is caused by the limit of results
|
// git grep exits by cancel (killed), usually it is caused by the limit of results
|
||||||
if gitcmd.IsErrorExitCode(err, -1) && stderr.Len() == 0 {
|
if gitcmd.IsErrorExitCode(err, -1) && stderr.Len() == 0 {
|
||||||
return results, nil
|
return results, nil
|
||||||
|
@@ -65,11 +65,10 @@ func LogNameStatusRepo(ctx context.Context, repository, head, treepath string, p
|
|||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
stderr := strings.Builder{}
|
stderr := strings.Builder{}
|
||||||
err := cmd.Run(ctx, &gitcmd.RunOpts{
|
err := cmd.WithDir(repository).
|
||||||
Dir: repository,
|
WithStdout(stdoutWriter).
|
||||||
Stdout: stdoutWriter,
|
WithStderr(&stderr).
|
||||||
Stderr: &stderr,
|
Run(ctx)
|
||||||
})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
_ = stdoutWriter.CloseWithError(gitcmd.ConcatenateError(err, (&stderr).String()))
|
_ = stdoutWriter.CloseWithError(gitcmd.ConcatenateError(err, (&stderr).String()))
|
||||||
return
|
return
|
||||||
|
@@ -26,12 +26,11 @@ func CatFileBatchCheck(ctx context.Context, shasToCheckReader *io.PipeReader, ca
|
|||||||
stderr := new(bytes.Buffer)
|
stderr := new(bytes.Buffer)
|
||||||
var errbuf strings.Builder
|
var errbuf strings.Builder
|
||||||
cmd := gitcmd.NewCommand("cat-file", "--batch-check")
|
cmd := gitcmd.NewCommand("cat-file", "--batch-check")
|
||||||
if err := cmd.Run(ctx, &gitcmd.RunOpts{
|
if err := cmd.WithDir(tmpBasePath).
|
||||||
Dir: tmpBasePath,
|
WithStdin(shasToCheckReader).
|
||||||
Stdin: shasToCheckReader,
|
WithStdout(catFileCheckWriter).
|
||||||
Stdout: catFileCheckWriter,
|
WithStderr(stderr).
|
||||||
Stderr: stderr,
|
Run(ctx); err != nil {
|
||||||
}); err != nil {
|
|
||||||
_ = catFileCheckWriter.CloseWithError(fmt.Errorf("git cat-file --batch-check [%s]: %w - %s", tmpBasePath, err, errbuf.String()))
|
_ = catFileCheckWriter.CloseWithError(fmt.Errorf("git cat-file --batch-check [%s]: %w - %s", tmpBasePath, err, errbuf.String()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -44,11 +43,10 @@ func CatFileBatchCheckAllObjects(ctx context.Context, catFileCheckWriter *io.Pip
|
|||||||
stderr := new(bytes.Buffer)
|
stderr := new(bytes.Buffer)
|
||||||
var errbuf strings.Builder
|
var errbuf strings.Builder
|
||||||
cmd := gitcmd.NewCommand("cat-file", "--batch-check", "--batch-all-objects")
|
cmd := gitcmd.NewCommand("cat-file", "--batch-check", "--batch-all-objects")
|
||||||
if err := cmd.Run(ctx, &gitcmd.RunOpts{
|
if err := cmd.WithDir(tmpBasePath).
|
||||||
Dir: tmpBasePath,
|
WithStdout(catFileCheckWriter).
|
||||||
Stdout: catFileCheckWriter,
|
WithStderr(stderr).
|
||||||
Stderr: stderr,
|
Run(ctx); err != nil {
|
||||||
}); err != nil {
|
|
||||||
log.Error("git cat-file --batch-check --batch-all-object [%s]: %v - %s", tmpBasePath, err, errbuf.String())
|
log.Error("git cat-file --batch-check --batch-all-object [%s]: %v - %s", tmpBasePath, err, errbuf.String())
|
||||||
err = fmt.Errorf("git cat-file --batch-check --batch-all-object [%s]: %w - %s", tmpBasePath, err, errbuf.String())
|
err = fmt.Errorf("git cat-file --batch-check --batch-all-object [%s]: %w - %s", tmpBasePath, err, errbuf.String())
|
||||||
_ = catFileCheckWriter.CloseWithError(err)
|
_ = catFileCheckWriter.CloseWithError(err)
|
||||||
@@ -64,12 +62,12 @@ func CatFileBatch(ctx context.Context, shasToBatchReader *io.PipeReader, catFile
|
|||||||
|
|
||||||
stderr := new(bytes.Buffer)
|
stderr := new(bytes.Buffer)
|
||||||
var errbuf strings.Builder
|
var errbuf strings.Builder
|
||||||
if err := gitcmd.NewCommand("cat-file", "--batch").Run(ctx, &gitcmd.RunOpts{
|
if err := gitcmd.NewCommand("cat-file", "--batch").
|
||||||
Dir: tmpBasePath,
|
WithDir(tmpBasePath).
|
||||||
Stdout: catFileBatchWriter,
|
WithStdin(shasToBatchReader).
|
||||||
Stdin: shasToBatchReader,
|
WithStdout(catFileBatchWriter).
|
||||||
Stderr: stderr,
|
WithStderr(stderr).
|
||||||
}); err != nil {
|
Run(ctx); err != nil {
|
||||||
_ = shasToBatchReader.CloseWithError(fmt.Errorf("git rev-list [%s]: %w - %s", tmpBasePath, err, errbuf.String()))
|
_ = shasToBatchReader.CloseWithError(fmt.Errorf("git rev-list [%s]: %w - %s", tmpBasePath, err, errbuf.String()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -33,11 +33,11 @@ func FindLFSFile(repo *git.Repository, objectID git.ObjectID) ([]*LFSResult, err
|
|||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
stderr := strings.Builder{}
|
stderr := strings.Builder{}
|
||||||
err := gitcmd.NewCommand("rev-list", "--all").Run(repo.Ctx, &gitcmd.RunOpts{
|
err := gitcmd.NewCommand("rev-list", "--all").
|
||||||
Dir: repo.Path,
|
WithDir(repo.Path).
|
||||||
Stdout: revListWriter,
|
WithStdout(revListWriter).
|
||||||
Stderr: &stderr,
|
WithStderr(&stderr).
|
||||||
})
|
Run(repo.Ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
_ = revListWriter.CloseWithError(gitcmd.ConcatenateError(err, (&stderr).String()))
|
_ = revListWriter.CloseWithError(gitcmd.ConcatenateError(err, (&stderr).String()))
|
||||||
} else {
|
} else {
|
||||||
|
@@ -22,12 +22,12 @@ func NameRevStdin(ctx context.Context, shasToNameReader *io.PipeReader, nameRevS
|
|||||||
|
|
||||||
stderr := new(bytes.Buffer)
|
stderr := new(bytes.Buffer)
|
||||||
var errbuf strings.Builder
|
var errbuf strings.Builder
|
||||||
if err := gitcmd.NewCommand("name-rev", "--stdin", "--name-only", "--always").Run(ctx, &gitcmd.RunOpts{
|
if err := gitcmd.NewCommand("name-rev", "--stdin", "--name-only", "--always").
|
||||||
Dir: tmpBasePath,
|
WithDir(tmpBasePath).
|
||||||
Stdout: nameRevStdinWriter,
|
WithStdin(shasToNameReader).
|
||||||
Stdin: shasToNameReader,
|
WithStdout(nameRevStdinWriter).
|
||||||
Stderr: stderr,
|
WithStderr(stderr).
|
||||||
}); err != nil {
|
Run(ctx); err != nil {
|
||||||
_ = shasToNameReader.CloseWithError(fmt.Errorf("git name-rev [%s]: %w - %s", tmpBasePath, err, errbuf.String()))
|
_ = shasToNameReader.CloseWithError(fmt.Errorf("git name-rev [%s]: %w - %s", tmpBasePath, err, errbuf.String()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -24,11 +24,10 @@ func RevListAllObjects(ctx context.Context, revListWriter *io.PipeWriter, wg *sy
|
|||||||
stderr := new(bytes.Buffer)
|
stderr := new(bytes.Buffer)
|
||||||
var errbuf strings.Builder
|
var errbuf strings.Builder
|
||||||
cmd := gitcmd.NewCommand("rev-list", "--objects", "--all")
|
cmd := gitcmd.NewCommand("rev-list", "--objects", "--all")
|
||||||
if err := cmd.Run(ctx, &gitcmd.RunOpts{
|
if err := cmd.WithDir(basePath).
|
||||||
Dir: basePath,
|
WithStdout(revListWriter).
|
||||||
Stdout: revListWriter,
|
WithStderr(stderr).
|
||||||
Stderr: stderr,
|
Run(ctx); err != nil {
|
||||||
}); err != nil {
|
|
||||||
log.Error("git rev-list --objects --all [%s]: %v - %s", basePath, err, errbuf.String())
|
log.Error("git rev-list --objects --all [%s]: %v - %s", basePath, err, errbuf.String())
|
||||||
err = fmt.Errorf("git rev-list --objects --all [%s]: %w - %s", basePath, err, errbuf.String())
|
err = fmt.Errorf("git rev-list --objects --all [%s]: %w - %s", basePath, err, errbuf.String())
|
||||||
_ = revListWriter.CloseWithError(err)
|
_ = revListWriter.CloseWithError(err)
|
||||||
@@ -46,11 +45,10 @@ func RevListObjects(ctx context.Context, revListWriter *io.PipeWriter, wg *sync.
|
|||||||
if baseSHA != "" {
|
if baseSHA != "" {
|
||||||
cmd = cmd.AddArguments("--not").AddDynamicArguments(baseSHA)
|
cmd = cmd.AddArguments("--not").AddDynamicArguments(baseSHA)
|
||||||
}
|
}
|
||||||
if err := cmd.Run(ctx, &gitcmd.RunOpts{
|
if err := cmd.WithDir(tmpBasePath).
|
||||||
Dir: tmpBasePath,
|
WithStdout(revListWriter).
|
||||||
Stdout: revListWriter,
|
WithStderr(stderr).
|
||||||
Stderr: stderr,
|
Run(ctx); err != nil {
|
||||||
}); err != nil {
|
|
||||||
log.Error("git rev-list [%s]: %v - %s", tmpBasePath, err, errbuf.String())
|
log.Error("git rev-list [%s]: %v - %s", tmpBasePath, err, errbuf.String())
|
||||||
errChan <- fmt.Errorf("git rev-list [%s]: %w - %s", tmpBasePath, err, errbuf.String())
|
errChan <- fmt.Errorf("git rev-list [%s]: %w - %s", tmpBasePath, err, errbuf.String())
|
||||||
}
|
}
|
||||||
|
@@ -22,7 +22,7 @@ func GetRemoteAddress(ctx context.Context, repoPath, remoteName string) (string,
|
|||||||
cmd = gitcmd.NewCommand("config", "--get").AddDynamicArguments("remote." + remoteName + ".url")
|
cmd = gitcmd.NewCommand("config", "--get").AddDynamicArguments("remote." + remoteName + ".url")
|
||||||
}
|
}
|
||||||
|
|
||||||
result, _, err := cmd.RunStdString(ctx, &gitcmd.RunOpts{Dir: repoPath})
|
result, _, err := cmd.WithDir(repoPath).RunStdString(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
@@ -40,8 +40,8 @@ func (repo *Repository) GetAllCommitsCount() (int64, error) {
|
|||||||
func (repo *Repository) ShowPrettyFormatLogToList(ctx context.Context, revisionRange string) ([]*Commit, error) {
|
func (repo *Repository) ShowPrettyFormatLogToList(ctx context.Context, revisionRange string) ([]*Commit, error) {
|
||||||
// avoid: ambiguous argument 'refs/a...refs/b': unknown revision or path not in the working tree. Use '--': 'git <command> [<revision>...] -- [<file>...]'
|
// avoid: ambiguous argument 'refs/a...refs/b': unknown revision or path not in the working tree. Use '--': 'git <command> [<revision>...] -- [<file>...]'
|
||||||
logs, _, err := gitcmd.NewCommand("log").AddArguments(prettyLogFormat).
|
logs, _, err := gitcmd.NewCommand("log").AddArguments(prettyLogFormat).
|
||||||
AddDynamicArguments(revisionRange).AddArguments("--").
|
AddDynamicArguments(revisionRange).AddArguments("--").WithDir(repo.Path).
|
||||||
RunStdBytes(ctx, &gitcmd.RunOpts{Dir: repo.Path})
|
RunStdBytes(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -69,7 +69,7 @@ func (repo *Repository) parsePrettyFormatLogToList(logs []byte) ([]*Commit, erro
|
|||||||
|
|
||||||
// IsRepoURLAccessible checks if given repository URL is accessible.
|
// IsRepoURLAccessible checks if given repository URL is accessible.
|
||||||
func IsRepoURLAccessible(ctx context.Context, url string) bool {
|
func IsRepoURLAccessible(ctx context.Context, url string) bool {
|
||||||
_, _, err := gitcmd.NewCommand("ls-remote", "-q", "-h").AddDynamicArguments(url, "HEAD").RunStdString(ctx, nil)
|
_, _, err := gitcmd.NewCommand("ls-remote", "-q", "-h").AddDynamicArguments(url, "HEAD").RunStdString(ctx)
|
||||||
return err == nil
|
return err == nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,19 +92,20 @@ func InitRepository(ctx context.Context, repoPath string, bare bool, objectForma
|
|||||||
if bare {
|
if bare {
|
||||||
cmd.AddArguments("--bare")
|
cmd.AddArguments("--bare")
|
||||||
}
|
}
|
||||||
_, _, err = cmd.RunStdString(ctx, &gitcmd.RunOpts{Dir: repoPath})
|
_, _, err = cmd.WithDir(repoPath).RunStdString(ctx)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsEmpty Check if repository is empty.
|
// IsEmpty Check if repository is empty.
|
||||||
func (repo *Repository) IsEmpty() (bool, error) {
|
func (repo *Repository) IsEmpty() (bool, error) {
|
||||||
var errbuf, output strings.Builder
|
var errbuf, output strings.Builder
|
||||||
if err := gitcmd.NewCommand().AddOptionFormat("--git-dir=%s", repo.Path).AddArguments("rev-list", "-n", "1", "--all").
|
if err := gitcmd.NewCommand().
|
||||||
Run(repo.Ctx, &gitcmd.RunOpts{
|
AddOptionFormat("--git-dir=%s", repo.Path).
|
||||||
Dir: repo.Path,
|
AddArguments("rev-list", "-n", "1", "--all").
|
||||||
Stdout: &output,
|
WithDir(repo.Path).
|
||||||
Stderr: &errbuf,
|
WithStdout(&output).
|
||||||
}); err != nil {
|
WithStderr(&errbuf).
|
||||||
|
Run(repo.Ctx); err != nil {
|
||||||
if (err.Error() == "exit status 1" && strings.TrimSpace(errbuf.String()) == "") || err.Error() == "exit status 129" {
|
if (err.Error() == "exit status 1" && strings.TrimSpace(errbuf.String()) == "") || err.Error() == "exit status 129" {
|
||||||
// git 2.11 exits with 129 if the repo is empty
|
// git 2.11 exits with 129 if the repo is empty
|
||||||
return true, nil
|
return true, nil
|
||||||
@@ -177,12 +178,12 @@ func Clone(ctx context.Context, from, to string, opts CloneRepoOptions) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
stderr := new(bytes.Buffer)
|
stderr := new(bytes.Buffer)
|
||||||
if err = cmd.Run(ctx, &gitcmd.RunOpts{
|
if err = cmd.
|
||||||
Timeout: opts.Timeout,
|
WithTimeout(opts.Timeout).
|
||||||
Env: envs,
|
WithEnv(envs).
|
||||||
Stdout: io.Discard,
|
WithStdout(io.Discard).
|
||||||
Stderr: stderr,
|
WithStderr(stderr).
|
||||||
}); err != nil {
|
Run(ctx); err != nil {
|
||||||
return gitcmd.ConcatenateError(err, stderr.String())
|
return gitcmd.ConcatenateError(err, stderr.String())
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@@ -213,7 +214,7 @@ func Push(ctx context.Context, repoPath string, opts PushOptions) error {
|
|||||||
}
|
}
|
||||||
cmd.AddDashesAndList(remoteBranchArgs...)
|
cmd.AddDashesAndList(remoteBranchArgs...)
|
||||||
|
|
||||||
stdout, stderr, err := cmd.RunStdString(ctx, &gitcmd.RunOpts{Env: opts.Env, Timeout: opts.Timeout, Dir: repoPath})
|
stdout, stderr, err := cmd.WithEnv(opts.Env).WithTimeout(opts.Timeout).WithDir(repoPath).RunStdString(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if strings.Contains(stderr, "non-fast-forward") {
|
if strings.Contains(stderr, "non-fast-forward") {
|
||||||
return &ErrPushOutOfDate{StdOut: stdout, StdErr: stderr, Err: err}
|
return &ErrPushOutOfDate{StdOut: stdout, StdErr: stderr, Err: err}
|
||||||
@@ -233,7 +234,7 @@ func Push(ctx context.Context, repoPath string, opts PushOptions) error {
|
|||||||
// GetLatestCommitTime returns time for latest commit in repository (across all branches)
|
// GetLatestCommitTime returns time for latest commit in repository (across all branches)
|
||||||
func GetLatestCommitTime(ctx context.Context, repoPath string) (time.Time, error) {
|
func GetLatestCommitTime(ctx context.Context, repoPath string) (time.Time, error) {
|
||||||
cmd := gitcmd.NewCommand("for-each-ref", "--sort=-committerdate", BranchPrefix, "--count", "1", "--format=%(committerdate)")
|
cmd := gitcmd.NewCommand("for-each-ref", "--sort=-committerdate", BranchPrefix, "--count", "1", "--format=%(committerdate)")
|
||||||
stdout, _, err := cmd.RunStdString(ctx, &gitcmd.RunOpts{Dir: repoPath})
|
stdout, _, err := cmd.WithDir(repoPath).RunStdString(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return time.Time{}, err
|
return time.Time{}, err
|
||||||
}
|
}
|
||||||
|
74
modules/git/repo_archive.go
Normal file
74
modules/git/repo_archive.go
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
// Copyright 2015 The Gogs Authors. All rights reserved.
|
||||||
|
// Copyright 2020 The Gitea Authors. All rights reserved.
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
package git
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"code.gitea.io/gitea/modules/git/gitcmd"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ArchiveType archive types
|
||||||
|
type ArchiveType int
|
||||||
|
|
||||||
|
const (
|
||||||
|
ArchiveUnknown ArchiveType = iota
|
||||||
|
ArchiveZip // 1
|
||||||
|
ArchiveTarGz // 2
|
||||||
|
ArchiveBundle // 3
|
||||||
|
)
|
||||||
|
|
||||||
|
// String converts an ArchiveType to string: the extension of the archive file without prefix dot
|
||||||
|
func (a ArchiveType) String() string {
|
||||||
|
switch a {
|
||||||
|
case ArchiveZip:
|
||||||
|
return "zip"
|
||||||
|
case ArchiveTarGz:
|
||||||
|
return "tar.gz"
|
||||||
|
case ArchiveBundle:
|
||||||
|
return "bundle"
|
||||||
|
}
|
||||||
|
return "unknown"
|
||||||
|
}
|
||||||
|
|
||||||
|
func SplitArchiveNameType(s string) (string, ArchiveType) {
|
||||||
|
switch {
|
||||||
|
case strings.HasSuffix(s, ".zip"):
|
||||||
|
return strings.TrimSuffix(s, ".zip"), ArchiveZip
|
||||||
|
case strings.HasSuffix(s, ".tar.gz"):
|
||||||
|
return strings.TrimSuffix(s, ".tar.gz"), ArchiveTarGz
|
||||||
|
case strings.HasSuffix(s, ".bundle"):
|
||||||
|
return strings.TrimSuffix(s, ".bundle"), ArchiveBundle
|
||||||
|
}
|
||||||
|
return s, ArchiveUnknown
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateArchive create archive content to the target path
|
||||||
|
func (repo *Repository) CreateArchive(ctx context.Context, format ArchiveType, target io.Writer, usePrefix bool, commitID string) error {
|
||||||
|
if format.String() == "unknown" {
|
||||||
|
return fmt.Errorf("unknown format: %v", format)
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd := gitcmd.NewCommand("archive")
|
||||||
|
if usePrefix {
|
||||||
|
cmd.AddOptionFormat("--prefix=%s", filepath.Base(strings.TrimSuffix(repo.Path, ".git"))+"/")
|
||||||
|
}
|
||||||
|
cmd.AddOptionFormat("--format=%s", format.String())
|
||||||
|
cmd.AddDynamicArguments(commitID)
|
||||||
|
|
||||||
|
var stderr strings.Builder
|
||||||
|
err := cmd.WithDir(repo.Path).
|
||||||
|
WithStdout(target).
|
||||||
|
WithStderr(&stderr).
|
||||||
|
Run(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return gitcmd.ConcatenateError(err, stderr.String())
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
@@ -17,8 +17,8 @@ func (repo *Repository) AddRemote(name, url string, fetch bool) error {
|
|||||||
if fetch {
|
if fetch {
|
||||||
cmd.AddArguments("-f")
|
cmd.AddArguments("-f")
|
||||||
}
|
}
|
||||||
cmd.AddDynamicArguments(name, url)
|
_, _, err := cmd.AddDynamicArguments(name, url).
|
||||||
|
WithDir(repo.Path).
|
||||||
_, _, err := cmd.RunStdString(repo.Ctx, &gitcmd.RunOpts{Dir: repo.Path})
|
RunStdString(repo.Ctx)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@@ -110,11 +110,11 @@ func WalkShowRef(ctx context.Context, repoPath string, extraArgs gitcmd.TrustedC
|
|||||||
stderrBuilder := &strings.Builder{}
|
stderrBuilder := &strings.Builder{}
|
||||||
args := gitcmd.TrustedCmdArgs{"for-each-ref", "--format=%(objectname) %(refname)"}
|
args := gitcmd.TrustedCmdArgs{"for-each-ref", "--format=%(objectname) %(refname)"}
|
||||||
args = append(args, extraArgs...)
|
args = append(args, extraArgs...)
|
||||||
err := gitcmd.NewCommand(args...).Run(ctx, &gitcmd.RunOpts{
|
err := gitcmd.NewCommand(args...).
|
||||||
Dir: repoPath,
|
WithDir(repoPath).
|
||||||
Stdout: stdoutWriter,
|
WithStdout(stdoutWriter).
|
||||||
Stderr: stderrBuilder,
|
WithStderr(stderrBuilder).
|
||||||
})
|
Run(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if stderrBuilder.Len() == 0 {
|
if stderrBuilder.Len() == 0 {
|
||||||
_ = stdoutWriter.Close()
|
_ = stdoutWriter.Close()
|
||||||
|
@@ -60,7 +60,11 @@ func (repo *Repository) getCommitByPathWithID(id ObjectID, relpath string) (*Com
|
|||||||
relpath = `\` + relpath
|
relpath = `\` + relpath
|
||||||
}
|
}
|
||||||
|
|
||||||
stdout, _, runErr := gitcmd.NewCommand("log", "-1", prettyLogFormat).AddDynamicArguments(id.String()).AddDashesAndList(relpath).RunStdString(repo.Ctx, &gitcmd.RunOpts{Dir: repo.Path})
|
stdout, _, runErr := gitcmd.NewCommand("log", "-1", prettyLogFormat).
|
||||||
|
AddDynamicArguments(id.String()).
|
||||||
|
AddDashesAndList(relpath).
|
||||||
|
WithDir(repo.Path).
|
||||||
|
RunStdString(repo.Ctx)
|
||||||
if runErr != nil {
|
if runErr != nil {
|
||||||
return nil, runErr
|
return nil, runErr
|
||||||
}
|
}
|
||||||
@@ -75,7 +79,10 @@ func (repo *Repository) getCommitByPathWithID(id ObjectID, relpath string) (*Com
|
|||||||
|
|
||||||
// GetCommitByPath returns the last commit of relative path.
|
// GetCommitByPath returns the last commit of relative path.
|
||||||
func (repo *Repository) GetCommitByPath(relpath string) (*Commit, error) {
|
func (repo *Repository) GetCommitByPath(relpath string) (*Commit, error) {
|
||||||
stdout, _, runErr := gitcmd.NewCommand("log", "-1", prettyLogFormat).AddDashesAndList(relpath).RunStdBytes(repo.Ctx, &gitcmd.RunOpts{Dir: repo.Path})
|
stdout, _, runErr := gitcmd.NewCommand("log", "-1", prettyLogFormat).
|
||||||
|
AddDashesAndList(relpath).
|
||||||
|
WithDir(repo.Path).
|
||||||
|
RunStdBytes(repo.Ctx)
|
||||||
if runErr != nil {
|
if runErr != nil {
|
||||||
return nil, runErr
|
return nil, runErr
|
||||||
}
|
}
|
||||||
@@ -108,7 +115,7 @@ func (repo *Repository) commitsByRangeWithTime(id ObjectID, page, pageSize int,
|
|||||||
cmd.AddOptionFormat("--until=%s", until)
|
cmd.AddOptionFormat("--until=%s", until)
|
||||||
}
|
}
|
||||||
|
|
||||||
stdout, _, err := cmd.RunStdBytes(repo.Ctx, &gitcmd.RunOpts{Dir: repo.Path})
|
stdout, _, err := cmd.WithDir(repo.Path).RunStdBytes(repo.Ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -162,7 +169,7 @@ func (repo *Repository) searchCommits(id ObjectID, opts SearchCommitsOptions) ([
|
|||||||
|
|
||||||
// search for commits matching given constraints and keywords in commit msg
|
// search for commits matching given constraints and keywords in commit msg
|
||||||
addCommonSearchArgs(cmd)
|
addCommonSearchArgs(cmd)
|
||||||
stdout, _, err := cmd.RunStdBytes(repo.Ctx, &gitcmd.RunOpts{Dir: repo.Path})
|
stdout, _, err := cmd.WithDir(repo.Path).RunStdBytes(repo.Ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -183,7 +190,7 @@ func (repo *Repository) searchCommits(id ObjectID, opts SearchCommitsOptions) ([
|
|||||||
hashCmd.AddDynamicArguments(v)
|
hashCmd.AddDynamicArguments(v)
|
||||||
|
|
||||||
// search with given constraints for commit matching sha hash of v
|
// search with given constraints for commit matching sha hash of v
|
||||||
hashMatching, _, err := hashCmd.RunStdBytes(repo.Ctx, &gitcmd.RunOpts{Dir: repo.Path})
|
hashMatching, _, err := hashCmd.WithDir(repo.Path).RunStdBytes(repo.Ctx)
|
||||||
if err != nil || bytes.Contains(stdout, hashMatching) {
|
if err != nil || bytes.Contains(stdout, hashMatching) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@@ -198,7 +205,11 @@ func (repo *Repository) searchCommits(id ObjectID, opts SearchCommitsOptions) ([
|
|||||||
// FileChangedBetweenCommits Returns true if the file changed between commit IDs id1 and id2
|
// FileChangedBetweenCommits Returns true if the file changed between commit IDs id1 and id2
|
||||||
// You must ensure that id1 and id2 are valid commit ids.
|
// You must ensure that id1 and id2 are valid commit ids.
|
||||||
func (repo *Repository) FileChangedBetweenCommits(filename, id1, id2 string) (bool, error) {
|
func (repo *Repository) FileChangedBetweenCommits(filename, id1, id2 string) (bool, error) {
|
||||||
stdout, _, err := gitcmd.NewCommand("diff", "--name-only", "-z").AddDynamicArguments(id1, id2).AddDashesAndList(filename).RunStdBytes(repo.Ctx, &gitcmd.RunOpts{Dir: repo.Path})
|
stdout, _, err := gitcmd.NewCommand("diff", "--name-only", "-z").
|
||||||
|
AddDynamicArguments(id1, id2).
|
||||||
|
AddDashesAndList(filename).
|
||||||
|
WithDir(repo.Path).
|
||||||
|
RunStdBytes(repo.Ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
@@ -249,11 +260,10 @@ func (repo *Repository) CommitsByFileAndRange(opts CommitsByFileAndRangeOptions)
|
|||||||
}
|
}
|
||||||
|
|
||||||
gitCmd.AddDashesAndList(opts.File)
|
gitCmd.AddDashesAndList(opts.File)
|
||||||
err := gitCmd.Run(repo.Ctx, &gitcmd.RunOpts{
|
err := gitCmd.WithDir(repo.Path).
|
||||||
Dir: repo.Path,
|
WithStdout(stdoutWriter).
|
||||||
Stdout: stdoutWriter,
|
WithStderr(&stderr).
|
||||||
Stderr: &stderr,
|
Run(repo.Ctx)
|
||||||
})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
_ = stdoutWriter.CloseWithError(gitcmd.ConcatenateError(err, (&stderr).String()))
|
_ = stdoutWriter.CloseWithError(gitcmd.ConcatenateError(err, (&stderr).String()))
|
||||||
} else {
|
} else {
|
||||||
@@ -291,11 +301,17 @@ func (repo *Repository) CommitsByFileAndRange(opts CommitsByFileAndRangeOptions)
|
|||||||
|
|
||||||
// FilesCountBetween return the number of files changed between two commits
|
// FilesCountBetween return the number of files changed between two commits
|
||||||
func (repo *Repository) FilesCountBetween(startCommitID, endCommitID string) (int, error) {
|
func (repo *Repository) FilesCountBetween(startCommitID, endCommitID string) (int, error) {
|
||||||
stdout, _, err := gitcmd.NewCommand("diff", "--name-only").AddDynamicArguments(startCommitID+"..."+endCommitID).RunStdString(repo.Ctx, &gitcmd.RunOpts{Dir: repo.Path})
|
stdout, _, err := gitcmd.NewCommand("diff", "--name-only").
|
||||||
|
AddDynamicArguments(startCommitID + "..." + endCommitID).
|
||||||
|
WithDir(repo.Path).
|
||||||
|
RunStdString(repo.Ctx)
|
||||||
if err != nil && strings.Contains(err.Error(), "no merge base") {
|
if err != nil && strings.Contains(err.Error(), "no merge base") {
|
||||||
// git >= 2.28 now returns an error if startCommitID and endCommitID have become unrelated.
|
// git >= 2.28 now returns an error if startCommitID and endCommitID have become unrelated.
|
||||||
// previously it would return the results of git diff --name-only startCommitID endCommitID so let's try that...
|
// previously it would return the results of git diff --name-only startCommitID endCommitID so let's try that...
|
||||||
stdout, _, err = gitcmd.NewCommand("diff", "--name-only").AddDynamicArguments(startCommitID, endCommitID).RunStdString(repo.Ctx, &gitcmd.RunOpts{Dir: repo.Path})
|
stdout, _, err = gitcmd.NewCommand("diff", "--name-only").
|
||||||
|
AddDynamicArguments(startCommitID, endCommitID).
|
||||||
|
WithDir(repo.Path).
|
||||||
|
RunStdString(repo.Ctx)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
@@ -309,13 +325,22 @@ func (repo *Repository) CommitsBetween(last, before *Commit) ([]*Commit, error)
|
|||||||
var stdout []byte
|
var stdout []byte
|
||||||
var err error
|
var err error
|
||||||
if before == nil {
|
if before == nil {
|
||||||
stdout, _, err = gitcmd.NewCommand("rev-list").AddDynamicArguments(last.ID.String()).RunStdBytes(repo.Ctx, &gitcmd.RunOpts{Dir: repo.Path})
|
stdout, _, err = gitcmd.NewCommand("rev-list").
|
||||||
|
AddDynamicArguments(last.ID.String()).
|
||||||
|
WithDir(repo.Path).
|
||||||
|
RunStdBytes(repo.Ctx)
|
||||||
} else {
|
} else {
|
||||||
stdout, _, err = gitcmd.NewCommand("rev-list").AddDynamicArguments(before.ID.String()+".."+last.ID.String()).RunStdBytes(repo.Ctx, &gitcmd.RunOpts{Dir: repo.Path})
|
stdout, _, err = gitcmd.NewCommand("rev-list").
|
||||||
|
AddDynamicArguments(before.ID.String() + ".." + last.ID.String()).
|
||||||
|
WithDir(repo.Path).
|
||||||
|
RunStdBytes(repo.Ctx)
|
||||||
if err != nil && strings.Contains(err.Error(), "no merge base") {
|
if err != nil && strings.Contains(err.Error(), "no merge base") {
|
||||||
// future versions of git >= 2.28 are likely to return an error if before and last have become unrelated.
|
// future versions of git >= 2.28 are likely to return an error if before and last have become unrelated.
|
||||||
// previously it would return the results of git rev-list before last so let's try that...
|
// previously it would return the results of git rev-list before last so let's try that...
|
||||||
stdout, _, err = gitcmd.NewCommand("rev-list").AddDynamicArguments(before.ID.String(), last.ID.String()).RunStdBytes(repo.Ctx, &gitcmd.RunOpts{Dir: repo.Path})
|
stdout, _, err = gitcmd.NewCommand("rev-list").
|
||||||
|
AddDynamicArguments(before.ID.String(), last.ID.String()).
|
||||||
|
WithDir(repo.Path).
|
||||||
|
RunStdBytes(repo.Ctx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -332,19 +357,25 @@ func (repo *Repository) CommitsBetweenLimit(last, before *Commit, limit, skip in
|
|||||||
stdout, _, err = gitcmd.NewCommand("rev-list").
|
stdout, _, err = gitcmd.NewCommand("rev-list").
|
||||||
AddOptionValues("--max-count", strconv.Itoa(limit)).
|
AddOptionValues("--max-count", strconv.Itoa(limit)).
|
||||||
AddOptionValues("--skip", strconv.Itoa(skip)).
|
AddOptionValues("--skip", strconv.Itoa(skip)).
|
||||||
AddDynamicArguments(last.ID.String()).RunStdBytes(repo.Ctx, &gitcmd.RunOpts{Dir: repo.Path})
|
AddDynamicArguments(last.ID.String()).
|
||||||
|
WithDir(repo.Path).
|
||||||
|
RunStdBytes(repo.Ctx)
|
||||||
} else {
|
} else {
|
||||||
stdout, _, err = gitcmd.NewCommand("rev-list").
|
stdout, _, err = gitcmd.NewCommand("rev-list").
|
||||||
AddOptionValues("--max-count", strconv.Itoa(limit)).
|
AddOptionValues("--max-count", strconv.Itoa(limit)).
|
||||||
AddOptionValues("--skip", strconv.Itoa(skip)).
|
AddOptionValues("--skip", strconv.Itoa(skip)).
|
||||||
AddDynamicArguments(before.ID.String()+".."+last.ID.String()).RunStdBytes(repo.Ctx, &gitcmd.RunOpts{Dir: repo.Path})
|
AddDynamicArguments(before.ID.String() + ".." + last.ID.String()).
|
||||||
|
WithDir(repo.Path).
|
||||||
|
RunStdBytes(repo.Ctx)
|
||||||
if err != nil && strings.Contains(err.Error(), "no merge base") {
|
if err != nil && strings.Contains(err.Error(), "no merge base") {
|
||||||
// future versions of git >= 2.28 are likely to return an error if before and last have become unrelated.
|
// future versions of git >= 2.28 are likely to return an error if before and last have become unrelated.
|
||||||
// previously it would return the results of git rev-list --max-count n before last so let's try that...
|
// previously it would return the results of git rev-list --max-count n before last so let's try that...
|
||||||
stdout, _, err = gitcmd.NewCommand("rev-list").
|
stdout, _, err = gitcmd.NewCommand("rev-list").
|
||||||
AddOptionValues("--max-count", strconv.Itoa(limit)).
|
AddOptionValues("--max-count", strconv.Itoa(limit)).
|
||||||
AddOptionValues("--skip", strconv.Itoa(skip)).
|
AddOptionValues("--skip", strconv.Itoa(skip)).
|
||||||
AddDynamicArguments(before.ID.String(), last.ID.String()).RunStdBytes(repo.Ctx, &gitcmd.RunOpts{Dir: repo.Path})
|
AddDynamicArguments(before.ID.String(), last.ID.String()).
|
||||||
|
WithDir(repo.Path).
|
||||||
|
RunStdBytes(repo.Ctx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -359,13 +390,25 @@ func (repo *Repository) CommitsBetweenNotBase(last, before *Commit, baseBranch s
|
|||||||
var stdout []byte
|
var stdout []byte
|
||||||
var err error
|
var err error
|
||||||
if before == nil {
|
if before == nil {
|
||||||
stdout, _, err = gitcmd.NewCommand("rev-list").AddDynamicArguments(last.ID.String()).AddOptionValues("--not", baseBranch).RunStdBytes(repo.Ctx, &gitcmd.RunOpts{Dir: repo.Path})
|
stdout, _, err = gitcmd.NewCommand("rev-list").
|
||||||
|
AddDynamicArguments(last.ID.String()).
|
||||||
|
AddOptionValues("--not", baseBranch).
|
||||||
|
WithDir(repo.Path).
|
||||||
|
RunStdBytes(repo.Ctx)
|
||||||
} else {
|
} else {
|
||||||
stdout, _, err = gitcmd.NewCommand("rev-list").AddDynamicArguments(before.ID.String()+".."+last.ID.String()).AddOptionValues("--not", baseBranch).RunStdBytes(repo.Ctx, &gitcmd.RunOpts{Dir: repo.Path})
|
stdout, _, err = gitcmd.NewCommand("rev-list").
|
||||||
|
AddDynamicArguments(before.ID.String()+".."+last.ID.String()).
|
||||||
|
AddOptionValues("--not", baseBranch).
|
||||||
|
WithDir(repo.Path).
|
||||||
|
RunStdBytes(repo.Ctx)
|
||||||
if err != nil && strings.Contains(err.Error(), "no merge base") {
|
if err != nil && strings.Contains(err.Error(), "no merge base") {
|
||||||
// future versions of git >= 2.28 are likely to return an error if before and last have become unrelated.
|
// future versions of git >= 2.28 are likely to return an error if before and last have become unrelated.
|
||||||
// previously it would return the results of git rev-list before last so let's try that...
|
// previously it would return the results of git rev-list before last so let's try that...
|
||||||
stdout, _, err = gitcmd.NewCommand("rev-list").AddDynamicArguments(before.ID.String(), last.ID.String()).AddOptionValues("--not", baseBranch).RunStdBytes(repo.Ctx, &gitcmd.RunOpts{Dir: repo.Path})
|
stdout, _, err = gitcmd.NewCommand("rev-list").
|
||||||
|
AddDynamicArguments(before.ID.String(), last.ID.String()).
|
||||||
|
AddOptionValues("--not", baseBranch).
|
||||||
|
WithDir(repo.Path).
|
||||||
|
RunStdBytes(repo.Ctx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -417,7 +460,7 @@ func (repo *Repository) commitsBefore(id ObjectID, limit int) ([]*Commit, error)
|
|||||||
}
|
}
|
||||||
cmd.AddDynamicArguments(id.String())
|
cmd.AddDynamicArguments(id.String())
|
||||||
|
|
||||||
stdout, _, runErr := cmd.RunStdBytes(repo.Ctx, &gitcmd.RunOpts{Dir: repo.Path})
|
stdout, _, runErr := cmd.WithDir(repo.Path).RunStdBytes(repo.Ctx)
|
||||||
if runErr != nil {
|
if runErr != nil {
|
||||||
return nil, runErr
|
return nil, runErr
|
||||||
}
|
}
|
||||||
@@ -457,10 +500,9 @@ func (repo *Repository) getBranches(env []string, commitID string, limit int) ([
|
|||||||
stdout, _, err := gitcmd.NewCommand("for-each-ref", "--format=%(refname:strip=2)").
|
stdout, _, err := gitcmd.NewCommand("for-each-ref", "--format=%(refname:strip=2)").
|
||||||
AddOptionFormat("--count=%d", limit).
|
AddOptionFormat("--count=%d", limit).
|
||||||
AddOptionValues("--contains", commitID, BranchPrefix).
|
AddOptionValues("--contains", commitID, BranchPrefix).
|
||||||
RunStdString(repo.Ctx, &gitcmd.RunOpts{
|
WithDir(repo.Path).
|
||||||
Dir: repo.Path,
|
WithEnv(env).
|
||||||
Env: env,
|
RunStdString(repo.Ctx)
|
||||||
})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -469,10 +511,11 @@ func (repo *Repository) getBranches(env []string, commitID string, limit int) ([
|
|||||||
return branches, nil
|
return branches, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
stdout, _, err := gitcmd.NewCommand("branch").AddOptionValues("--contains", commitID).RunStdString(repo.Ctx, &gitcmd.RunOpts{
|
stdout, _, err := gitcmd.NewCommand("branch").
|
||||||
Dir: repo.Path,
|
AddOptionValues("--contains", commitID).
|
||||||
Env: env,
|
WithDir(repo.Path).
|
||||||
})
|
WithEnv(env).
|
||||||
|
RunStdString(repo.Ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -511,7 +554,10 @@ func (repo *Repository) GetCommitsFromIDs(commitIDs []string) []*Commit {
|
|||||||
|
|
||||||
// IsCommitInBranch check if the commit is on the branch
|
// IsCommitInBranch check if the commit is on the branch
|
||||||
func (repo *Repository) IsCommitInBranch(commitID, branch string) (r bool, err error) {
|
func (repo *Repository) IsCommitInBranch(commitID, branch string) (r bool, err error) {
|
||||||
stdout, _, err := gitcmd.NewCommand("branch", "--contains").AddDynamicArguments(commitID, branch).RunStdString(repo.Ctx, &gitcmd.RunOpts{Dir: repo.Path})
|
stdout, _, err := gitcmd.NewCommand("branch", "--contains").
|
||||||
|
AddDynamicArguments(commitID, branch).
|
||||||
|
WithDir(repo.Path).
|
||||||
|
RunStdString(repo.Ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
@@ -540,10 +586,9 @@ func (repo *Repository) GetCommitBranchStart(env []string, branch, endCommitID s
|
|||||||
cmd := gitcmd.NewCommand("log", prettyLogFormat)
|
cmd := gitcmd.NewCommand("log", prettyLogFormat)
|
||||||
cmd.AddDynamicArguments(endCommitID)
|
cmd.AddDynamicArguments(endCommitID)
|
||||||
|
|
||||||
stdout, _, runErr := cmd.RunStdBytes(repo.Ctx, &gitcmd.RunOpts{
|
stdout, _, runErr := cmd.WithDir(repo.Path).
|
||||||
Dir: repo.Path,
|
WithEnv(env).
|
||||||
Env: env,
|
RunStdBytes(repo.Ctx)
|
||||||
})
|
|
||||||
if runErr != nil {
|
if runErr != nil {
|
||||||
return "", runErr
|
return "", runErr
|
||||||
}
|
}
|
||||||
|
@@ -51,7 +51,10 @@ func (repo *Repository) ConvertToGitID(commitID string) (ObjectID, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
actualCommitID, _, err := gitcmd.NewCommand("rev-parse", "--verify").AddDynamicArguments(commitID).RunStdString(repo.Ctx, &gitcmd.RunOpts{Dir: repo.Path})
|
actualCommitID, _, err := gitcmd.NewCommand("rev-parse", "--verify").
|
||||||
|
AddDynamicArguments(commitID).
|
||||||
|
WithDir(repo.Path).
|
||||||
|
RunStdString(repo.Ctx)
|
||||||
actualCommitID = strings.TrimSpace(actualCommitID)
|
actualCommitID = strings.TrimSpace(actualCommitID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if strings.Contains(err.Error(), "unknown revision or path") ||
|
if strings.Contains(err.Error(), "unknown revision or path") ||
|
||||||
|
@@ -17,7 +17,10 @@ import (
|
|||||||
|
|
||||||
// ResolveReference resolves a name to a reference
|
// ResolveReference resolves a name to a reference
|
||||||
func (repo *Repository) ResolveReference(name string) (string, error) {
|
func (repo *Repository) ResolveReference(name string) (string, error) {
|
||||||
stdout, _, err := gitcmd.NewCommand("show-ref", "--hash").AddDynamicArguments(name).RunStdString(repo.Ctx, &gitcmd.RunOpts{Dir: repo.Path})
|
stdout, _, err := gitcmd.NewCommand("show-ref", "--hash").
|
||||||
|
AddDynamicArguments(name).
|
||||||
|
WithDir(repo.Path).
|
||||||
|
RunStdString(repo.Ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if strings.Contains(err.Error(), "not a valid ref") {
|
if strings.Contains(err.Error(), "not a valid ref") {
|
||||||
return "", ErrNotExist{name, ""}
|
return "", ErrNotExist{name, ""}
|
||||||
@@ -57,7 +60,10 @@ func (repo *Repository) IsCommitExist(name string) bool {
|
|||||||
log.Error("IsCommitExist: %v", err)
|
log.Error("IsCommitExist: %v", err)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
_, _, err := gitcmd.NewCommand("cat-file", "-e").AddDynamicArguments(name).RunStdString(repo.Ctx, &gitcmd.RunOpts{Dir: repo.Path})
|
_, _, err := gitcmd.NewCommand("cat-file", "-e").
|
||||||
|
AddDynamicArguments(name).
|
||||||
|
WithDir(repo.Path).
|
||||||
|
RunStdString(repo.Ctx)
|
||||||
return err == nil
|
return err == nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -14,7 +14,7 @@ import (
|
|||||||
// this requires git v2.18 to be installed
|
// this requires git v2.18 to be installed
|
||||||
func WriteCommitGraph(ctx context.Context, repoPath string) error {
|
func WriteCommitGraph(ctx context.Context, repoPath string) error {
|
||||||
if DefaultFeatures().CheckVersionAtLeast("2.18") {
|
if DefaultFeatures().CheckVersionAtLeast("2.18") {
|
||||||
if _, _, err := gitcmd.NewCommand("commit-graph", "write").RunStdString(ctx, &gitcmd.RunOpts{Dir: repoPath}); err != nil {
|
if _, _, err := gitcmd.NewCommand("commit-graph", "write").WithDir(repoPath).RunStdString(ctx); err != nil {
|
||||||
return fmt.Errorf("unable to write commit-graph for '%s' : %w", repoPath, err)
|
return fmt.Errorf("unable to write commit-graph for '%s' : %w", repoPath, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -27,13 +27,20 @@ func (repo *Repository) GetMergeBase(tmpRemote, base, head string) (string, stri
|
|||||||
if tmpRemote != "origin" {
|
if tmpRemote != "origin" {
|
||||||
tmpBaseName := RemotePrefix + tmpRemote + "/tmp_" + base
|
tmpBaseName := RemotePrefix + tmpRemote + "/tmp_" + base
|
||||||
// Fetch commit into a temporary branch in order to be able to handle commits and tags
|
// Fetch commit into a temporary branch in order to be able to handle commits and tags
|
||||||
_, _, err := gitcmd.NewCommand("fetch", "--no-tags").AddDynamicArguments(tmpRemote).AddDashesAndList(base+":"+tmpBaseName).RunStdString(repo.Ctx, &gitcmd.RunOpts{Dir: repo.Path})
|
_, _, err := gitcmd.NewCommand("fetch", "--no-tags").
|
||||||
|
AddDynamicArguments(tmpRemote).
|
||||||
|
AddDashesAndList(base + ":" + tmpBaseName).
|
||||||
|
WithDir(repo.Path).
|
||||||
|
RunStdString(repo.Ctx)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
base = tmpBaseName
|
base = tmpBaseName
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
stdout, _, err := gitcmd.NewCommand("merge-base").AddDashesAndList(base, head).RunStdString(repo.Ctx, &gitcmd.RunOpts{Dir: repo.Path})
|
stdout, _, err := gitcmd.NewCommand("merge-base").
|
||||||
|
AddDashesAndList(base, head).
|
||||||
|
WithDir(repo.Path).
|
||||||
|
RunStdString(repo.Ctx)
|
||||||
return strings.TrimSpace(stdout), base, err
|
return strings.TrimSpace(stdout), base, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -61,22 +68,25 @@ func (repo *Repository) GetDiffNumChangedFiles(base, head string, directComparis
|
|||||||
}
|
}
|
||||||
|
|
||||||
// avoid: ambiguous argument 'refs/a...refs/b': unknown revision or path not in the working tree. Use '--': 'git <command> [<revision>...] -- [<file>...]'
|
// avoid: ambiguous argument 'refs/a...refs/b': unknown revision or path not in the working tree. Use '--': 'git <command> [<revision>...] -- [<file>...]'
|
||||||
if err := gitcmd.NewCommand("diff", "-z", "--name-only").AddDynamicArguments(base+separator+head).AddArguments("--").
|
if err := gitcmd.NewCommand("diff", "-z", "--name-only").
|
||||||
Run(repo.Ctx, &gitcmd.RunOpts{
|
AddDynamicArguments(base + separator + head).
|
||||||
Dir: repo.Path,
|
AddArguments("--").
|
||||||
Stdout: w,
|
WithDir(repo.Path).
|
||||||
Stderr: stderr,
|
WithStdout(w).
|
||||||
}); err != nil {
|
WithStderr(stderr).
|
||||||
|
Run(repo.Ctx); err != nil {
|
||||||
if strings.Contains(stderr.String(), "no merge base") {
|
if strings.Contains(stderr.String(), "no merge base") {
|
||||||
// git >= 2.28 now returns an error if base and head have become unrelated.
|
// git >= 2.28 now returns an error if base and head have become unrelated.
|
||||||
// previously it would return the results of git diff -z --name-only base head so let's try that...
|
// previously it would return the results of git diff -z --name-only base head so let's try that...
|
||||||
w = &lineCountWriter{}
|
w = &lineCountWriter{}
|
||||||
stderr.Reset()
|
stderr.Reset()
|
||||||
if err = gitcmd.NewCommand("diff", "-z", "--name-only").AddDynamicArguments(base, head).AddArguments("--").Run(repo.Ctx, &gitcmd.RunOpts{
|
if err = gitcmd.NewCommand("diff", "-z", "--name-only").
|
||||||
Dir: repo.Path,
|
AddDynamicArguments(base, head).
|
||||||
Stdout: w,
|
AddArguments("--").
|
||||||
Stderr: stderr,
|
WithDir(repo.Path).
|
||||||
}); err == nil {
|
WithStdout(w).
|
||||||
|
WithStderr(stderr).
|
||||||
|
Run(repo.Ctx); err == nil {
|
||||||
return w.numLines, nil
|
return w.numLines, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -91,30 +101,29 @@ var patchCommits = regexp.MustCompile(`^From\s(\w+)\s`)
|
|||||||
func (repo *Repository) GetDiff(compareArg string, w io.Writer) error {
|
func (repo *Repository) GetDiff(compareArg string, w io.Writer) error {
|
||||||
stderr := new(bytes.Buffer)
|
stderr := new(bytes.Buffer)
|
||||||
return gitcmd.NewCommand("diff", "-p").AddDynamicArguments(compareArg).
|
return gitcmd.NewCommand("diff", "-p").AddDynamicArguments(compareArg).
|
||||||
Run(repo.Ctx, &gitcmd.RunOpts{
|
WithDir(repo.Path).
|
||||||
Dir: repo.Path,
|
WithStdout(w).
|
||||||
Stdout: w,
|
WithStderr(stderr).
|
||||||
Stderr: stderr,
|
Run(repo.Ctx)
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetDiffBinary generates and returns patch data between given revisions, including binary diffs.
|
// GetDiffBinary generates and returns patch data between given revisions, including binary diffs.
|
||||||
func (repo *Repository) GetDiffBinary(compareArg string, w io.Writer) error {
|
func (repo *Repository) GetDiffBinary(compareArg string, w io.Writer) error {
|
||||||
return gitcmd.NewCommand("diff", "-p", "--binary", "--histogram").AddDynamicArguments(compareArg).Run(repo.Ctx, &gitcmd.RunOpts{
|
return gitcmd.NewCommand("diff", "-p", "--binary", "--histogram").
|
||||||
Dir: repo.Path,
|
AddDynamicArguments(compareArg).
|
||||||
Stdout: w,
|
WithDir(repo.Path).
|
||||||
})
|
WithStdout(w).
|
||||||
|
Run(repo.Ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetPatch generates and returns format-patch data between given revisions, able to be used with `git apply`
|
// GetPatch generates and returns format-patch data between given revisions, able to be used with `git apply`
|
||||||
func (repo *Repository) GetPatch(compareArg string, w io.Writer) error {
|
func (repo *Repository) GetPatch(compareArg string, w io.Writer) error {
|
||||||
stderr := new(bytes.Buffer)
|
stderr := new(bytes.Buffer)
|
||||||
return gitcmd.NewCommand("format-patch", "--binary", "--stdout").AddDynamicArguments(compareArg).
|
return gitcmd.NewCommand("format-patch", "--binary", "--stdout").AddDynamicArguments(compareArg).
|
||||||
Run(repo.Ctx, &gitcmd.RunOpts{
|
WithDir(repo.Path).
|
||||||
Dir: repo.Path,
|
WithStdout(w).
|
||||||
Stdout: w,
|
WithStderr(stderr).
|
||||||
Stderr: stderr,
|
Run(repo.Ctx)
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetFilesChangedBetween returns a list of all files that have been changed between the given commits
|
// GetFilesChangedBetween returns a list of all files that have been changed between the given commits
|
||||||
@@ -131,7 +140,7 @@ func (repo *Repository) GetFilesChangedBetween(base, head string) ([]string, err
|
|||||||
} else {
|
} else {
|
||||||
cmd.AddDynamicArguments(base, head)
|
cmd.AddDynamicArguments(base, head)
|
||||||
}
|
}
|
||||||
stdout, _, err := cmd.RunStdString(repo.Ctx, &gitcmd.RunOpts{Dir: repo.Path})
|
stdout, _, err := cmd.WithDir(repo.Path).RunStdString(repo.Ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@@ -103,7 +103,8 @@ func TestReadWritePullHead(t *testing.T) {
|
|||||||
newCommit := "feaf4ba6bc635fec442f46ddd4512416ec43c2c2"
|
newCommit := "feaf4ba6bc635fec442f46ddd4512416ec43c2c2"
|
||||||
_, _, err = gitcmd.NewCommand("update-ref").
|
_, _, err = gitcmd.NewCommand("update-ref").
|
||||||
AddDynamicArguments(PullPrefix+"1/head", newCommit).
|
AddDynamicArguments(PullPrefix+"1/head", newCommit).
|
||||||
RunStdString(t.Context(), &gitcmd.RunOpts{Dir: repo.Path})
|
WithDir(repo.Path).
|
||||||
|
RunStdString(t.Context())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
return
|
return
|
||||||
@@ -121,8 +122,9 @@ func TestReadWritePullHead(t *testing.T) {
|
|||||||
|
|
||||||
// Remove file after the test
|
// Remove file after the test
|
||||||
_, _, err = gitcmd.NewCommand("update-ref", "--no-deref", "-d").
|
_, _, err = gitcmd.NewCommand("update-ref", "--no-deref", "-d").
|
||||||
AddDynamicArguments(PullPrefix+"1/head").
|
AddDynamicArguments(PullPrefix + "1/head").
|
||||||
RunStdString(t.Context(), &gitcmd.RunOpts{Dir: repo.Path})
|
WithDir(repo.Path).
|
||||||
|
RunStdString(t.Context())
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -43,7 +43,7 @@ func (repo *Repository) GetDefaultPublicGPGKey(forceUpdate bool) (*GPGSettings,
|
|||||||
Sign: true,
|
Sign: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
value, _, _ := gitcmd.NewCommand("config", "--get", "commit.gpgsign").RunStdString(repo.Ctx, &gitcmd.RunOpts{Dir: repo.Path})
|
value, _, _ := gitcmd.NewCommand("config", "--get", "commit.gpgsign").WithDir(repo.Path).RunStdString(repo.Ctx)
|
||||||
sign, valid := ParseBool(strings.TrimSpace(value))
|
sign, valid := ParseBool(strings.TrimSpace(value))
|
||||||
if !sign || !valid {
|
if !sign || !valid {
|
||||||
gpgSettings.Sign = false
|
gpgSettings.Sign = false
|
||||||
@@ -51,16 +51,16 @@ func (repo *Repository) GetDefaultPublicGPGKey(forceUpdate bool) (*GPGSettings,
|
|||||||
return gpgSettings, nil
|
return gpgSettings, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
signingKey, _, _ := gitcmd.NewCommand("config", "--get", "user.signingkey").RunStdString(repo.Ctx, &gitcmd.RunOpts{Dir: repo.Path})
|
signingKey, _, _ := gitcmd.NewCommand("config", "--get", "user.signingkey").WithDir(repo.Path).RunStdString(repo.Ctx)
|
||||||
gpgSettings.KeyID = strings.TrimSpace(signingKey)
|
gpgSettings.KeyID = strings.TrimSpace(signingKey)
|
||||||
|
|
||||||
format, _, _ := gitcmd.NewCommand("config", "--default", SigningKeyFormatOpenPGP, "--get", "gpg.format").RunStdString(repo.Ctx, &gitcmd.RunOpts{Dir: repo.Path})
|
format, _, _ := gitcmd.NewCommand("config", "--default", SigningKeyFormatOpenPGP, "--get", "gpg.format").WithDir(repo.Path).RunStdString(repo.Ctx)
|
||||||
gpgSettings.Format = strings.TrimSpace(format)
|
gpgSettings.Format = strings.TrimSpace(format)
|
||||||
|
|
||||||
defaultEmail, _, _ := gitcmd.NewCommand("config", "--get", "user.email").RunStdString(repo.Ctx, &gitcmd.RunOpts{Dir: repo.Path})
|
defaultEmail, _, _ := gitcmd.NewCommand("config", "--get", "user.email").WithDir(repo.Path).RunStdString(repo.Ctx)
|
||||||
gpgSettings.Email = strings.TrimSpace(defaultEmail)
|
gpgSettings.Email = strings.TrimSpace(defaultEmail)
|
||||||
|
|
||||||
defaultName, _, _ := gitcmd.NewCommand("config", "--get", "user.name").RunStdString(repo.Ctx, &gitcmd.RunOpts{Dir: repo.Path})
|
defaultName, _, _ := gitcmd.NewCommand("config", "--get", "user.name").WithDir(repo.Path).RunStdString(repo.Ctx)
|
||||||
gpgSettings.Name = strings.TrimSpace(defaultName)
|
gpgSettings.Name = strings.TrimSpace(defaultName)
|
||||||
|
|
||||||
if err := gpgSettings.LoadPublicKeyContent(); err != nil {
|
if err := gpgSettings.LoadPublicKeyContent(); err != nil {
|
||||||
|
@@ -22,7 +22,7 @@ func (repo *Repository) ReadTreeToIndex(treeish string, indexFilename ...string)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if len(treeish) != objectFormat.FullLength() {
|
if len(treeish) != objectFormat.FullLength() {
|
||||||
res, _, err := gitcmd.NewCommand("rev-parse", "--verify").AddDynamicArguments(treeish).RunStdString(repo.Ctx, &gitcmd.RunOpts{Dir: repo.Path})
|
res, _, err := gitcmd.NewCommand("rev-parse", "--verify").AddDynamicArguments(treeish).WithDir(repo.Path).RunStdString(repo.Ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -42,7 +42,7 @@ func (repo *Repository) readTreeToIndex(id ObjectID, indexFilename ...string) er
|
|||||||
if len(indexFilename) > 0 {
|
if len(indexFilename) > 0 {
|
||||||
env = append(os.Environ(), "GIT_INDEX_FILE="+indexFilename[0])
|
env = append(os.Environ(), "GIT_INDEX_FILE="+indexFilename[0])
|
||||||
}
|
}
|
||||||
_, _, err := gitcmd.NewCommand("read-tree").AddDynamicArguments(id.String()).RunStdString(repo.Ctx, &gitcmd.RunOpts{Dir: repo.Path, Env: env})
|
_, _, err := gitcmd.NewCommand("read-tree").AddDynamicArguments(id.String()).WithDir(repo.Path).WithEnv(env).RunStdString(repo.Ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -75,14 +75,14 @@ func (repo *Repository) ReadTreeToTemporaryIndex(treeish string) (tmpIndexFilena
|
|||||||
|
|
||||||
// EmptyIndex empties the index
|
// EmptyIndex empties the index
|
||||||
func (repo *Repository) EmptyIndex() error {
|
func (repo *Repository) EmptyIndex() error {
|
||||||
_, _, err := gitcmd.NewCommand("read-tree", "--empty").RunStdString(repo.Ctx, &gitcmd.RunOpts{Dir: repo.Path})
|
_, _, err := gitcmd.NewCommand("read-tree", "--empty").WithDir(repo.Path).RunStdString(repo.Ctx)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// LsFiles checks if the given filenames are in the index
|
// LsFiles checks if the given filenames are in the index
|
||||||
func (repo *Repository) LsFiles(filenames ...string) ([]string, error) {
|
func (repo *Repository) LsFiles(filenames ...string) ([]string, error) {
|
||||||
cmd := gitcmd.NewCommand("ls-files", "-z").AddDashesAndList(filenames...)
|
cmd := gitcmd.NewCommand("ls-files", "-z").AddDashesAndList(filenames...)
|
||||||
res, _, err := cmd.RunStdBytes(repo.Ctx, &gitcmd.RunOpts{Dir: repo.Path})
|
res, _, err := cmd.WithDir(repo.Path).RunStdBytes(repo.Ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -110,12 +110,12 @@ func (repo *Repository) RemoveFilesFromIndex(filenames ...string) error {
|
|||||||
buffer.WriteString("0 blob " + objectFormat.EmptyObjectID().String() + "\t" + file + "\000")
|
buffer.WriteString("0 blob " + objectFormat.EmptyObjectID().String() + "\t" + file + "\000")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return cmd.Run(repo.Ctx, &gitcmd.RunOpts{
|
return cmd.
|
||||||
Dir: repo.Path,
|
WithDir(repo.Path).
|
||||||
Stdin: bytes.NewReader(buffer.Bytes()),
|
WithStdin(bytes.NewReader(buffer.Bytes())).
|
||||||
Stdout: stdout,
|
WithStdout(stdout).
|
||||||
Stderr: stderr,
|
WithStderr(stderr).
|
||||||
})
|
Run(repo.Ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
type IndexObjectInfo struct {
|
type IndexObjectInfo struct {
|
||||||
@@ -134,12 +134,12 @@ func (repo *Repository) AddObjectsToIndex(objects ...IndexObjectInfo) error {
|
|||||||
// using format: mode SP type SP sha1 TAB path
|
// using format: mode SP type SP sha1 TAB path
|
||||||
buffer.WriteString(object.Mode + " blob " + object.Object.String() + "\t" + object.Filename + "\000")
|
buffer.WriteString(object.Mode + " blob " + object.Object.String() + "\t" + object.Filename + "\000")
|
||||||
}
|
}
|
||||||
return cmd.Run(repo.Ctx, &gitcmd.RunOpts{
|
return cmd.
|
||||||
Dir: repo.Path,
|
WithDir(repo.Path).
|
||||||
Stdin: bytes.NewReader(buffer.Bytes()),
|
WithStdin(bytes.NewReader(buffer.Bytes())).
|
||||||
Stdout: stdout,
|
WithStdout(stdout).
|
||||||
Stderr: stderr,
|
WithStderr(stderr).
|
||||||
})
|
Run(repo.Ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddObjectToIndex adds the provided object hash to the index at the provided filename
|
// AddObjectToIndex adds the provided object hash to the index at the provided filename
|
||||||
@@ -149,7 +149,7 @@ func (repo *Repository) AddObjectToIndex(mode string, object ObjectID, filename
|
|||||||
|
|
||||||
// WriteTree writes the current index as a tree to the object db and returns its hash
|
// WriteTree writes the current index as a tree to the object db and returns its hash
|
||||||
func (repo *Repository) WriteTree() (*Tree, error) {
|
func (repo *Repository) WriteTree() (*Tree, error) {
|
||||||
stdout, _, runErr := gitcmd.NewCommand("write-tree").RunStdString(repo.Ctx, &gitcmd.RunOpts{Dir: repo.Path})
|
stdout, _, runErr := gitcmd.NewCommand("write-tree").WithDir(repo.Path).RunStdString(repo.Ctx)
|
||||||
if runErr != nil {
|
if runErr != nil {
|
||||||
return nil, runErr
|
return nil, runErr
|
||||||
}
|
}
|
||||||
|
@@ -76,12 +76,12 @@ func (repo *Repository) hashObject(reader io.Reader, save bool) (string, error)
|
|||||||
}
|
}
|
||||||
stdout := new(bytes.Buffer)
|
stdout := new(bytes.Buffer)
|
||||||
stderr := new(bytes.Buffer)
|
stderr := new(bytes.Buffer)
|
||||||
err := cmd.Run(repo.Ctx, &gitcmd.RunOpts{
|
err := cmd.
|
||||||
Dir: repo.Path,
|
WithDir(repo.Path).
|
||||||
Stdin: reader,
|
WithStdin(reader).
|
||||||
Stdout: stdout,
|
WithStdout(stdout).
|
||||||
Stderr: stderr,
|
WithStderr(stderr).
|
||||||
})
|
Run(repo.Ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
@@ -28,7 +28,8 @@ func (repo *Repository) ListOccurrences(ctx context.Context, refType, commitSHA
|
|||||||
default:
|
default:
|
||||||
return nil, util.NewInvalidArgumentErrorf(`can only use "branch" or "tag" for refType, but got %q`, refType)
|
return nil, util.NewInvalidArgumentErrorf(`can only use "branch" or "tag" for refType, but got %q`, refType)
|
||||||
}
|
}
|
||||||
stdout, _, err := cmd.AddArguments("--no-color", "--sort=-creatordate", "--contains").AddDynamicArguments(commitSHA).RunStdString(ctx, &gitcmd.RunOpts{Dir: repo.Path})
|
stdout, _, err := cmd.AddArguments("--no-color", "--sort=-creatordate", "--contains").
|
||||||
|
AddDynamicArguments(commitSHA).WithDir(repo.Path).RunStdString(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@@ -23,11 +23,11 @@ func (repo *Repository) GetRefsFiltered(pattern string) ([]*Reference, error) {
|
|||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
stderrBuilder := &strings.Builder{}
|
stderrBuilder := &strings.Builder{}
|
||||||
err := gitcmd.NewCommand("for-each-ref").Run(repo.Ctx, &gitcmd.RunOpts{
|
err := gitcmd.NewCommand("for-each-ref").
|
||||||
Dir: repo.Path,
|
WithDir(repo.Path).
|
||||||
Stdout: stdoutWriter,
|
WithStdout(stdoutWriter).
|
||||||
Stderr: stderrBuilder,
|
WithStderr(stderrBuilder).
|
||||||
})
|
Run(repo.Ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
_ = stdoutWriter.CloseWithError(gitcmd.ConcatenateError(err, stderrBuilder.String()))
|
_ = stdoutWriter.CloseWithError(gitcmd.ConcatenateError(err, stderrBuilder.String()))
|
||||||
} else {
|
} else {
|
||||||
|
@@ -43,7 +43,8 @@ func (repo *Repository) GetCodeActivityStats(fromTime time.Time, branch string)
|
|||||||
|
|
||||||
stdout, _, runErr := gitcmd.NewCommand("rev-list", "--count", "--no-merges", "--branches=*", "--date=iso").
|
stdout, _, runErr := gitcmd.NewCommand("rev-list", "--count", "--no-merges", "--branches=*", "--date=iso").
|
||||||
AddOptionFormat("--since=%s", since).
|
AddOptionFormat("--since=%s", since).
|
||||||
RunStdString(repo.Ctx, &gitcmd.RunOpts{Dir: repo.Path})
|
WithDir(repo.Path).
|
||||||
|
RunStdString(repo.Ctx)
|
||||||
if runErr != nil {
|
if runErr != nil {
|
||||||
return nil, runErr
|
return nil, runErr
|
||||||
}
|
}
|
||||||
@@ -72,12 +73,11 @@ func (repo *Repository) GetCodeActivityStats(fromTime time.Time, branch string)
|
|||||||
}
|
}
|
||||||
|
|
||||||
stderr := new(strings.Builder)
|
stderr := new(strings.Builder)
|
||||||
err = gitCmd.Run(repo.Ctx, &gitcmd.RunOpts{
|
err = gitCmd.
|
||||||
Env: []string{},
|
WithDir(repo.Path).
|
||||||
Dir: repo.Path,
|
WithStdout(stdoutWriter).
|
||||||
Stdout: stdoutWriter,
|
WithStderr(stderr).
|
||||||
Stderr: stderr,
|
WithPipelineFunc(func(ctx context.Context, cancel context.CancelFunc) error {
|
||||||
PipelineFunc: func(ctx context.Context, cancel context.CancelFunc) error {
|
|
||||||
_ = stdoutWriter.Close()
|
_ = stdoutWriter.Close()
|
||||||
scanner := bufio.NewScanner(stdoutReader)
|
scanner := bufio.NewScanner(stdoutReader)
|
||||||
scanner.Split(bufio.ScanLines)
|
scanner.Split(bufio.ScanLines)
|
||||||
@@ -145,8 +145,8 @@ func (repo *Repository) GetCodeActivityStats(fromTime time.Time, branch string)
|
|||||||
stats.Authors = a
|
stats.Authors = a
|
||||||
_ = stdoutReader.Close()
|
_ = stdoutReader.Close()
|
||||||
return nil
|
return nil
|
||||||
},
|
}).
|
||||||
})
|
Run(repo.Ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("Failed to get GetCodeActivityStats for repository.\nError: %w\nStderr: %s", err, stderr)
|
return nil, fmt.Errorf("Failed to get GetCodeActivityStats for repository.\nError: %w\nStderr: %s", err, stderr)
|
||||||
}
|
}
|
||||||
|
@@ -19,13 +19,17 @@ const TagPrefix = "refs/tags/"
|
|||||||
|
|
||||||
// CreateTag create one tag in the repository
|
// CreateTag create one tag in the repository
|
||||||
func (repo *Repository) CreateTag(name, revision string) error {
|
func (repo *Repository) CreateTag(name, revision string) error {
|
||||||
_, _, err := gitcmd.NewCommand("tag").AddDashesAndList(name, revision).RunStdString(repo.Ctx, &gitcmd.RunOpts{Dir: repo.Path})
|
_, _, err := gitcmd.NewCommand("tag").AddDashesAndList(name, revision).WithDir(repo.Path).RunStdString(repo.Ctx)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateAnnotatedTag create one annotated tag in the repository
|
// CreateAnnotatedTag create one annotated tag in the repository
|
||||||
func (repo *Repository) CreateAnnotatedTag(name, message, revision string) error {
|
func (repo *Repository) CreateAnnotatedTag(name, message, revision string) error {
|
||||||
_, _, err := gitcmd.NewCommand("tag", "-a", "-m").AddDynamicArguments(message).AddDashesAndList(name, revision).RunStdString(repo.Ctx, &gitcmd.RunOpts{Dir: repo.Path})
|
_, _, err := gitcmd.NewCommand("tag", "-a", "-m").
|
||||||
|
AddDynamicArguments(message).
|
||||||
|
AddDashesAndList(name, revision).
|
||||||
|
WithDir(repo.Path).
|
||||||
|
RunStdString(repo.Ctx)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -35,7 +39,7 @@ func (repo *Repository) GetTagNameBySHA(sha string) (string, error) {
|
|||||||
return "", fmt.Errorf("SHA is too short: %s", sha)
|
return "", fmt.Errorf("SHA is too short: %s", sha)
|
||||||
}
|
}
|
||||||
|
|
||||||
stdout, _, err := gitcmd.NewCommand("show-ref", "--tags", "-d").RunStdString(repo.Ctx, &gitcmd.RunOpts{Dir: repo.Path})
|
stdout, _, err := gitcmd.NewCommand("show-ref", "--tags", "-d").WithDir(repo.Path).RunStdString(repo.Ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
@@ -58,7 +62,7 @@ func (repo *Repository) GetTagNameBySHA(sha string) (string, error) {
|
|||||||
|
|
||||||
// GetTagID returns the object ID for a tag (annotated tags have both an object SHA AND a commit SHA)
|
// GetTagID returns the object ID for a tag (annotated tags have both an object SHA AND a commit SHA)
|
||||||
func (repo *Repository) GetTagID(name string) (string, error) {
|
func (repo *Repository) GetTagID(name string) (string, error) {
|
||||||
stdout, _, err := gitcmd.NewCommand("show-ref", "--tags").AddDashesAndList(name).RunStdString(repo.Ctx, &gitcmd.RunOpts{Dir: repo.Path})
|
stdout, _, err := gitcmd.NewCommand("show-ref", "--tags").AddDashesAndList(name).WithDir(repo.Path).RunStdString(repo.Ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
@@ -115,12 +119,15 @@ func (repo *Repository) GetTagInfos(page, pageSize int) ([]*Tag, int, error) {
|
|||||||
defer stdoutReader.Close()
|
defer stdoutReader.Close()
|
||||||
defer stdoutWriter.Close()
|
defer stdoutWriter.Close()
|
||||||
stderr := strings.Builder{}
|
stderr := strings.Builder{}
|
||||||
rc := &gitcmd.RunOpts{Dir: repo.Path, Stdout: stdoutWriter, Stderr: &stderr}
|
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
err := gitcmd.NewCommand("for-each-ref").
|
err := gitcmd.NewCommand("for-each-ref").
|
||||||
AddOptionFormat("--format=%s", forEachRefFmt.Flag()).
|
AddOptionFormat("--format=%s", forEachRefFmt.Flag()).
|
||||||
AddArguments("--sort", "-*creatordate", "refs/tags").Run(repo.Ctx, rc)
|
AddArguments("--sort", "-*creatordate", "refs/tags").
|
||||||
|
WithDir(repo.Path).
|
||||||
|
WithStdout(stdoutWriter).
|
||||||
|
WithStderr(&stderr).
|
||||||
|
Run(repo.Ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
_ = stdoutWriter.CloseWithError(gitcmd.ConcatenateError(err, stderr.String()))
|
_ = stdoutWriter.CloseWithError(gitcmd.ConcatenateError(err, stderr.String()))
|
||||||
} else {
|
} else {
|
||||||
|
@@ -60,13 +60,12 @@ func (repo *Repository) CommitTree(author, committer *Signature, tree *Tree, opt
|
|||||||
|
|
||||||
stdout := new(bytes.Buffer)
|
stdout := new(bytes.Buffer)
|
||||||
stderr := new(bytes.Buffer)
|
stderr := new(bytes.Buffer)
|
||||||
err := cmd.Run(repo.Ctx, &gitcmd.RunOpts{
|
err := cmd.WithEnv(env).
|
||||||
Env: env,
|
WithDir(repo.Path).
|
||||||
Dir: repo.Path,
|
WithStdin(messageBytes).
|
||||||
Stdin: messageBytes,
|
WithStdout(stdout).
|
||||||
Stdout: stdout,
|
WithStderr(stderr).
|
||||||
Stderr: stderr,
|
Run(repo.Ctx)
|
||||||
})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, gitcmd.ConcatenateError(err, stderr.String())
|
return nil, gitcmd.ConcatenateError(err, stderr.String())
|
||||||
}
|
}
|
||||||
|
@@ -38,7 +38,10 @@ func (repo *Repository) GetTree(idStr string) (*Tree, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if len(idStr) != objectFormat.FullLength() {
|
if len(idStr) != objectFormat.FullLength() {
|
||||||
res, _, err := gitcmd.NewCommand("rev-parse", "--verify").AddDynamicArguments(idStr).RunStdString(repo.Ctx, &gitcmd.RunOpts{Dir: repo.Path})
|
res, _, err := gitcmd.NewCommand("rev-parse", "--verify").
|
||||||
|
AddDynamicArguments(idStr).
|
||||||
|
WithDir(repo.Path).
|
||||||
|
RunStdString(repo.Ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@@ -25,10 +25,11 @@ func GetTemplateSubmoduleCommits(ctx context.Context, repoPath string) (submodul
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
opts := &gitcmd.RunOpts{
|
|
||||||
Dir: repoPath,
|
err = gitcmd.NewCommand("ls-tree", "-r", "--", "HEAD").
|
||||||
Stdout: stdoutWriter,
|
WithDir(repoPath).
|
||||||
PipelineFunc: func(ctx context.Context, cancel context.CancelFunc) error {
|
WithStdout(stdoutWriter).
|
||||||
|
WithPipelineFunc(func(ctx context.Context, cancel context.CancelFunc) error {
|
||||||
_ = stdoutWriter.Close()
|
_ = stdoutWriter.Close()
|
||||||
defer stdoutReader.Close()
|
defer stdoutReader.Close()
|
||||||
|
|
||||||
@@ -44,9 +45,8 @@ func GetTemplateSubmoduleCommits(ctx context.Context, repoPath string) (submodul
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return scanner.Err()
|
return scanner.Err()
|
||||||
},
|
}).
|
||||||
}
|
Run(ctx)
|
||||||
err = gitcmd.NewCommand("ls-tree", "-r", "--", "HEAD").Run(ctx, opts)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("GetTemplateSubmoduleCommits: error running git ls-tree: %v", err)
|
return nil, fmt.Errorf("GetTemplateSubmoduleCommits: error running git ls-tree: %v", err)
|
||||||
}
|
}
|
||||||
@@ -58,7 +58,7 @@ func GetTemplateSubmoduleCommits(ctx context.Context, repoPath string) (submodul
|
|||||||
func AddTemplateSubmoduleIndexes(ctx context.Context, repoPath string, submodules []TemplateSubmoduleCommit) error {
|
func AddTemplateSubmoduleIndexes(ctx context.Context, repoPath string, submodules []TemplateSubmoduleCommit) error {
|
||||||
for _, submodule := range submodules {
|
for _, submodule := range submodules {
|
||||||
cmd := gitcmd.NewCommand("update-index", "--add", "--cacheinfo", "160000").AddDynamicArguments(submodule.Commit, submodule.Path)
|
cmd := gitcmd.NewCommand("update-index", "--add", "--cacheinfo", "160000").AddDynamicArguments(submodule.Commit, submodule.Path)
|
||||||
if stdout, _, err := cmd.RunStdString(ctx, &gitcmd.RunOpts{Dir: repoPath}); err != nil {
|
if stdout, _, err := cmd.WithDir(repoPath).RunStdString(ctx); err != nil {
|
||||||
log.Error("Unable to add %s as submodule to repo %s: stdout %s\nError: %v", submodule.Path, repoPath, stdout, err)
|
log.Error("Unable to add %s as submodule to repo %s: stdout %s\nError: %v", submodule.Path, repoPath, stdout, err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@@ -32,14 +32,14 @@ func TestAddTemplateSubmoduleIndexes(t *testing.T) {
|
|||||||
ctx := t.Context()
|
ctx := t.Context()
|
||||||
tmpDir := t.TempDir()
|
tmpDir := t.TempDir()
|
||||||
var err error
|
var err error
|
||||||
_, _, err = gitcmd.NewCommand("init").RunStdString(ctx, &gitcmd.RunOpts{Dir: tmpDir})
|
_, _, err = gitcmd.NewCommand("init").WithDir(tmpDir).RunStdString(ctx)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
_ = os.Mkdir(filepath.Join(tmpDir, "new-dir"), 0o755)
|
_ = os.Mkdir(filepath.Join(tmpDir, "new-dir"), 0o755)
|
||||||
err = AddTemplateSubmoduleIndexes(ctx, tmpDir, []TemplateSubmoduleCommit{{Path: "new-dir", Commit: "1234567890123456789012345678901234567890"}})
|
err = AddTemplateSubmoduleIndexes(ctx, tmpDir, []TemplateSubmoduleCommit{{Path: "new-dir", Commit: "1234567890123456789012345678901234567890"}})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
_, _, err = gitcmd.NewCommand("add", "--all").RunStdString(ctx, &gitcmd.RunOpts{Dir: tmpDir})
|
_, _, err = gitcmd.NewCommand("add", "--all").WithDir(tmpDir).RunStdString(ctx)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
_, _, err = gitcmd.NewCommand("-c", "user.name=a", "-c", "user.email=b", "commit", "-m=test").RunStdString(ctx, &gitcmd.RunOpts{Dir: tmpDir})
|
_, _, err = gitcmd.NewCommand("-c", "user.name=a", "-c", "user.email=b", "commit", "-m=test").WithDir(tmpDir).RunStdString(ctx)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
submodules, err := GetTemplateSubmoduleCommits(t.Context(), tmpDir)
|
submodules, err := GetTemplateSubmoduleCommits(t.Context(), tmpDir)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
@@ -53,7 +53,7 @@ func (repo *Repository) LsTree(ref string, filenames ...string) ([]string, error
|
|||||||
cmd := gitcmd.NewCommand("ls-tree", "-z", "--name-only").
|
cmd := gitcmd.NewCommand("ls-tree", "-z", "--name-only").
|
||||||
AddDashesAndList(append([]string{ref}, filenames...)...)
|
AddDashesAndList(append([]string{ref}, filenames...)...)
|
||||||
|
|
||||||
res, _, err := cmd.RunStdBytes(repo.Ctx, &gitcmd.RunOpts{Dir: repo.Path})
|
res, _, err := cmd.WithDir(repo.Path).RunStdBytes(repo.Ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -69,7 +69,8 @@ func (repo *Repository) LsTree(ref string, filenames ...string) ([]string, error
|
|||||||
func (repo *Repository) GetTreePathLatestCommit(refName, treePath string) (*Commit, error) {
|
func (repo *Repository) GetTreePathLatestCommit(refName, treePath string) (*Commit, error) {
|
||||||
stdout, _, err := gitcmd.NewCommand("rev-list", "-1").
|
stdout, _, err := gitcmd.NewCommand("rev-list", "-1").
|
||||||
AddDynamicArguments(refName).AddDashesAndList(treePath).
|
AddDynamicArguments(refName).AddDashesAndList(treePath).
|
||||||
RunStdString(repo.Ctx, &gitcmd.RunOpts{Dir: repo.Path})
|
WithDir(repo.Path).
|
||||||
|
RunStdString(repo.Ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@@ -72,7 +72,7 @@ func (t *Tree) ListEntries() (Entries, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
stdout, _, runErr := gitcmd.NewCommand("ls-tree", "-l").AddDynamicArguments(t.ID.String()).RunStdBytes(t.repo.Ctx, &gitcmd.RunOpts{Dir: t.repo.Path})
|
stdout, _, runErr := gitcmd.NewCommand("ls-tree", "-l").AddDynamicArguments(t.ID.String()).WithDir(t.repo.Path).RunStdBytes(t.repo.Ctx)
|
||||||
if runErr != nil {
|
if runErr != nil {
|
||||||
if strings.Contains(runErr.Error(), "fatal: Not a valid object name") || strings.Contains(runErr.Error(), "fatal: not a tree object") {
|
if strings.Contains(runErr.Error(), "fatal: Not a valid object name") || strings.Contains(runErr.Error(), "fatal: not a tree object") {
|
||||||
return nil, ErrNotExist{
|
return nil, ErrNotExist{
|
||||||
@@ -101,7 +101,8 @@ func (t *Tree) listEntriesRecursive(extraArgs gitcmd.TrustedCmdArgs) (Entries, e
|
|||||||
stdout, _, runErr := gitcmd.NewCommand("ls-tree", "-t", "-r").
|
stdout, _, runErr := gitcmd.NewCommand("ls-tree", "-t", "-r").
|
||||||
AddArguments(extraArgs...).
|
AddArguments(extraArgs...).
|
||||||
AddDynamicArguments(t.ID.String()).
|
AddDynamicArguments(t.ID.String()).
|
||||||
RunStdBytes(t.repo.Ctx, &gitcmd.RunOpts{Dir: t.repo.Path})
|
WithDir(t.repo.Path).
|
||||||
|
RunStdBytes(t.repo.Ctx)
|
||||||
if runErr != nil {
|
if runErr != nil {
|
||||||
return nil, runErr
|
return nil, runErr
|
||||||
}
|
}
|
||||||
|
@@ -29,12 +29,7 @@ func CreateArchive(ctx context.Context, repo Repository, format string, target i
|
|||||||
cmd.AddDynamicArguments(commitID)
|
cmd.AddDynamicArguments(commitID)
|
||||||
|
|
||||||
var stderr strings.Builder
|
var stderr strings.Builder
|
||||||
err := cmd.Run(ctx, &gitcmd.RunOpts{
|
if err := RunCmd(ctx, repo, cmd.WithStdout(target).WithStderr(&stderr)); err != nil {
|
||||||
Dir: repoPath(repo),
|
|
||||||
Stdout: target,
|
|
||||||
Stderr: &stderr,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return gitcmd.ConcatenateError(err, stderr.String())
|
return gitcmd.ConcatenateError(err, stderr.String())
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@@ -49,23 +44,23 @@ func CreateBundle(ctx context.Context, repo Repository, commit string, out io.Wr
|
|||||||
defer cleanup()
|
defer cleanup()
|
||||||
|
|
||||||
env := append(os.Environ(), "GIT_OBJECT_DIRECTORY="+filepath.Join(repoPath(repo), "objects"))
|
env := append(os.Environ(), "GIT_OBJECT_DIRECTORY="+filepath.Join(repoPath(repo), "objects"))
|
||||||
_, _, err = gitcmd.NewCommand("init", "--bare").RunStdString(ctx, &gitcmd.RunOpts{Dir: tmp, Env: env})
|
_, _, err = gitcmd.NewCommand("init", "--bare").WithDir(tmp).WithEnv(env).RunStdString(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
_, _, err = gitcmd.NewCommand("reset", "--soft").AddDynamicArguments(commit).RunStdString(ctx, &gitcmd.RunOpts{Dir: tmp, Env: env})
|
_, _, err = gitcmd.NewCommand("reset", "--soft").AddDynamicArguments(commit).WithDir(tmp).WithEnv(env).RunStdString(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
_, _, err = gitcmd.NewCommand("branch", "-m", "bundle").RunStdString(ctx, &gitcmd.RunOpts{Dir: tmp, Env: env})
|
_, _, err = gitcmd.NewCommand("branch", "-m", "bundle").WithDir(tmp).WithEnv(env).RunStdString(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
tmpFile := filepath.Join(tmp, "bundle")
|
tmpFile := filepath.Join(tmp, "bundle")
|
||||||
_, _, err = gitcmd.NewCommand("bundle", "create").AddDynamicArguments(tmpFile, "bundle", "HEAD").RunStdString(ctx, &gitcmd.RunOpts{Dir: tmp, Env: env})
|
_, _, err = gitcmd.NewCommand("bundle", "create").AddDynamicArguments(tmpFile, "bundle", "HEAD").WithDir(tmp).WithEnv(env).RunStdString(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@@ -10,7 +10,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func LineBlame(ctx context.Context, repo Repository, revision, file string, line uint) (string, error) {
|
func LineBlame(ctx context.Context, repo Repository, revision, file string, line uint) (string, error) {
|
||||||
return runCmdString(ctx, repo,
|
return RunCmdString(ctx, repo,
|
||||||
gitcmd.NewCommand("blame").
|
gitcmd.NewCommand("blame").
|
||||||
AddOptionFormat("-L %d,%d", line, line).
|
AddOptionFormat("-L %d,%d", line, line).
|
||||||
AddOptionValues("-p", revision).
|
AddOptionValues("-p", revision).
|
||||||
|
@@ -36,14 +36,14 @@ func GetBranchCommitID(ctx context.Context, repo Repository, branch string) (str
|
|||||||
|
|
||||||
// SetDefaultBranch sets default branch of repository.
|
// SetDefaultBranch sets default branch of repository.
|
||||||
func SetDefaultBranch(ctx context.Context, repo Repository, name string) error {
|
func SetDefaultBranch(ctx context.Context, repo Repository, name string) error {
|
||||||
_, err := runCmdString(ctx, repo, gitcmd.NewCommand("symbolic-ref", "HEAD").
|
_, err := RunCmdString(ctx, repo, gitcmd.NewCommand("symbolic-ref", "HEAD").
|
||||||
AddDynamicArguments(git.BranchPrefix+name))
|
AddDynamicArguments(git.BranchPrefix+name))
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetDefaultBranch gets default branch of repository.
|
// GetDefaultBranch gets default branch of repository.
|
||||||
func GetDefaultBranch(ctx context.Context, repo Repository) (string, error) {
|
func GetDefaultBranch(ctx context.Context, repo Repository) (string, error) {
|
||||||
stdout, err := runCmdString(ctx, repo, gitcmd.NewCommand("symbolic-ref", "HEAD"))
|
stdout, err := RunCmdString(ctx, repo, gitcmd.NewCommand("symbolic-ref", "HEAD"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
@@ -56,7 +56,7 @@ func GetDefaultBranch(ctx context.Context, repo Repository) (string, error) {
|
|||||||
|
|
||||||
// IsReferenceExist returns true if given reference exists in the repository.
|
// IsReferenceExist returns true if given reference exists in the repository.
|
||||||
func IsReferenceExist(ctx context.Context, repo Repository, name string) bool {
|
func IsReferenceExist(ctx context.Context, repo Repository, name string) bool {
|
||||||
_, err := runCmdString(ctx, repo, gitcmd.NewCommand("show-ref", "--verify").AddDashesAndList(name))
|
_, err := RunCmdString(ctx, repo, gitcmd.NewCommand("show-ref", "--verify").AddDashesAndList(name))
|
||||||
return err == nil
|
return err == nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,7 +76,7 @@ func DeleteBranch(ctx context.Context, repo Repository, name string, force bool)
|
|||||||
}
|
}
|
||||||
|
|
||||||
cmd.AddDashesAndList(name)
|
cmd.AddDashesAndList(name)
|
||||||
_, err := runCmdString(ctx, repo, cmd)
|
_, err := RunCmdString(ctx, repo, cmd)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -85,12 +85,12 @@ func CreateBranch(ctx context.Context, repo Repository, branch, oldbranchOrCommi
|
|||||||
cmd := gitcmd.NewCommand("branch")
|
cmd := gitcmd.NewCommand("branch")
|
||||||
cmd.AddDashesAndList(branch, oldbranchOrCommit)
|
cmd.AddDashesAndList(branch, oldbranchOrCommit)
|
||||||
|
|
||||||
_, err := runCmdString(ctx, repo, cmd)
|
_, err := RunCmdString(ctx, repo, cmd)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// RenameBranch rename a branch
|
// RenameBranch rename a branch
|
||||||
func RenameBranch(ctx context.Context, repo Repository, from, to string) error {
|
func RenameBranch(ctx context.Context, repo Repository, from, to string) error {
|
||||||
_, err := runCmdString(ctx, repo, gitcmd.NewCommand("branch", "-m").AddDynamicArguments(from, to))
|
_, err := RunCmdString(ctx, repo, gitcmd.NewCommand("branch", "-m").AddDynamicArguments(from, to))
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@@ -9,7 +9,15 @@ import (
|
|||||||
"code.gitea.io/gitea/modules/git/gitcmd"
|
"code.gitea.io/gitea/modules/git/gitcmd"
|
||||||
)
|
)
|
||||||
|
|
||||||
func runCmdString(ctx context.Context, repo Repository, cmd *gitcmd.Command) (string, error) {
|
func RunCmd(ctx context.Context, repo Repository, cmd *gitcmd.Command) error {
|
||||||
res, _, err := cmd.RunStdString(ctx, &gitcmd.RunOpts{Dir: repoPath(repo)})
|
return cmd.WithDir(repoPath(repo)).WithParentCallerInfo().Run(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
func RunCmdString(ctx context.Context, repo Repository, cmd *gitcmd.Command) (string, error) {
|
||||||
|
res, _, err := cmd.WithDir(repoPath(repo)).WithParentCallerInfo().RunStdString(ctx)
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func RunCmdBytes(ctx context.Context, repo Repository, cmd *gitcmd.Command) ([]byte, []byte, error) {
|
||||||
|
return cmd.WithDir(repoPath(repo)).WithParentCallerInfo().RunStdBytes(ctx)
|
||||||
|
}
|
||||||
|
@@ -22,7 +22,7 @@ type DivergeObject struct {
|
|||||||
func GetDivergingCommits(ctx context.Context, repo Repository, baseBranch, targetBranch string) (*DivergeObject, error) {
|
func GetDivergingCommits(ctx context.Context, repo Repository, baseBranch, targetBranch string) (*DivergeObject, error) {
|
||||||
cmd := gitcmd.NewCommand("rev-list", "--count", "--left-right").
|
cmd := gitcmd.NewCommand("rev-list", "--count", "--left-right").
|
||||||
AddDynamicArguments(baseBranch + "..." + targetBranch).AddArguments("--")
|
AddDynamicArguments(baseBranch + "..." + targetBranch).AddArguments("--")
|
||||||
stdout, _, err1 := cmd.RunStdString(ctx, &gitcmd.RunOpts{Dir: repoPath(repo)})
|
stdout, err1 := RunCmdString(ctx, repo, cmd)
|
||||||
if err1 != nil {
|
if err1 != nil {
|
||||||
return nil, err1
|
return nil, err1
|
||||||
}
|
}
|
||||||
|
@@ -12,7 +12,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func GitConfigGet(ctx context.Context, repo Repository, key string) (string, error) {
|
func GitConfigGet(ctx context.Context, repo Repository, key string) (string, error) {
|
||||||
result, err := runCmdString(ctx, repo, gitcmd.NewCommand("config", "--get").
|
result, err := RunCmdString(ctx, repo, gitcmd.NewCommand("config", "--get").
|
||||||
AddDynamicArguments(key))
|
AddDynamicArguments(key))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
@@ -27,7 +27,7 @@ func getRepoConfigLockKey(repoStoragePath string) string {
|
|||||||
// GitConfigAdd add a git configuration key to a specific value for the given repository.
|
// GitConfigAdd add a git configuration key to a specific value for the given repository.
|
||||||
func GitConfigAdd(ctx context.Context, repo Repository, key, value string) error {
|
func GitConfigAdd(ctx context.Context, repo Repository, key, value string) error {
|
||||||
return globallock.LockAndDo(ctx, getRepoConfigLockKey(repo.RelativePath()), func(ctx context.Context) error {
|
return globallock.LockAndDo(ctx, getRepoConfigLockKey(repo.RelativePath()), func(ctx context.Context) error {
|
||||||
_, err := runCmdString(ctx, repo, gitcmd.NewCommand("config", "--add").
|
_, err := RunCmdString(ctx, repo, gitcmd.NewCommand("config", "--add").
|
||||||
AddDynamicArguments(key, value))
|
AddDynamicArguments(key, value))
|
||||||
return err
|
return err
|
||||||
})
|
})
|
||||||
@@ -38,7 +38,7 @@ func GitConfigAdd(ctx context.Context, repo Repository, key, value string) error
|
|||||||
// If the key exists, it will be updated to the new value.
|
// If the key exists, it will be updated to the new value.
|
||||||
func GitConfigSet(ctx context.Context, repo Repository, key, value string) error {
|
func GitConfigSet(ctx context.Context, repo Repository, key, value string) error {
|
||||||
return globallock.LockAndDo(ctx, getRepoConfigLockKey(repo.RelativePath()), func(ctx context.Context) error {
|
return globallock.LockAndDo(ctx, getRepoConfigLockKey(repo.RelativePath()), func(ctx context.Context) error {
|
||||||
_, err := runCmdString(ctx, repo, gitcmd.NewCommand("config").
|
_, err := RunCmdString(ctx, repo, gitcmd.NewCommand("config").
|
||||||
AddDynamicArguments(key, value))
|
AddDynamicArguments(key, value))
|
||||||
return err
|
return err
|
||||||
})
|
})
|
||||||
|
@@ -20,7 +20,7 @@ func GetDiffShortStatByCmdArgs(ctx context.Context, repo Repository, trustedArgs
|
|||||||
// we get:
|
// we get:
|
||||||
// " 9902 files changed, 2034198 insertions(+), 298800 deletions(-)\n"
|
// " 9902 files changed, 2034198 insertions(+), 298800 deletions(-)\n"
|
||||||
cmd := gitcmd.NewCommand("diff", "--shortstat").AddArguments(trustedArgs...).AddDynamicArguments(dynamicArgs...)
|
cmd := gitcmd.NewCommand("diff", "--shortstat").AddArguments(trustedArgs...).AddDynamicArguments(dynamicArgs...)
|
||||||
stdout, err := runCmdString(ctx, repo, cmd)
|
stdout, err := RunCmdString(ctx, repo, cmd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, 0, 0, err
|
return 0, 0, 0, err
|
||||||
}
|
}
|
||||||
|
@@ -12,5 +12,5 @@ import (
|
|||||||
|
|
||||||
// Fsck verifies the connectivity and validity of the objects in the database
|
// Fsck verifies the connectivity and validity of the objects in the database
|
||||||
func Fsck(ctx context.Context, repo Repository, timeout time.Duration, args gitcmd.TrustedCmdArgs) error {
|
func Fsck(ctx context.Context, repo Repository, timeout time.Duration, args gitcmd.TrustedCmdArgs) error {
|
||||||
return gitcmd.NewCommand("fsck").AddArguments(args...).Run(ctx, &gitcmd.RunOpts{Timeout: timeout, Dir: repoPath(repo)})
|
return RunCmd(ctx, repo, gitcmd.NewCommand("fsck").AddArguments(args...).WithTimeout(timeout))
|
||||||
}
|
}
|
||||||
|
@@ -10,12 +10,10 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func UpdateRef(ctx context.Context, repo Repository, refName, newCommitID string) error {
|
func UpdateRef(ctx context.Context, repo Repository, refName, newCommitID string) error {
|
||||||
_, _, err := gitcmd.NewCommand("update-ref").AddDynamicArguments(refName, newCommitID).RunStdString(ctx, &gitcmd.RunOpts{Dir: repoPath(repo)})
|
return RunCmd(ctx, repo, gitcmd.NewCommand("update-ref").AddDynamicArguments(refName, newCommitID))
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func RemoveRef(ctx context.Context, repo Repository, refName string) error {
|
func RemoveRef(ctx context.Context, repo Repository, refName string) error {
|
||||||
_, _, err := gitcmd.NewCommand("update-ref", "--no-deref", "-d").
|
return RunCmd(ctx, repo, gitcmd.NewCommand("update-ref", "--no-deref", "-d").
|
||||||
AddDynamicArguments(refName).RunStdString(ctx, &gitcmd.RunOpts{Dir: repoPath(repo)})
|
AddDynamicArguments(refName))
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
@@ -36,7 +36,7 @@ func GitRemoteAdd(ctx context.Context, repo Repository, remoteName, remoteURL st
|
|||||||
return errors.New("unknown remote option: " + string(options[0]))
|
return errors.New("unknown remote option: " + string(options[0]))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_, err := runCmdString(ctx, repo, cmd.AddDynamicArguments(remoteName, remoteURL))
|
_, err := RunCmdString(ctx, repo, cmd.AddDynamicArguments(remoteName, remoteURL))
|
||||||
return err
|
return err
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -44,7 +44,7 @@ func GitRemoteAdd(ctx context.Context, repo Repository, remoteName, remoteURL st
|
|||||||
func GitRemoteRemove(ctx context.Context, repo Repository, remoteName string) error {
|
func GitRemoteRemove(ctx context.Context, repo Repository, remoteName string) error {
|
||||||
return globallock.LockAndDo(ctx, getRepoConfigLockKey(repo.RelativePath()), func(ctx context.Context) error {
|
return globallock.LockAndDo(ctx, getRepoConfigLockKey(repo.RelativePath()), func(ctx context.Context) error {
|
||||||
cmd := gitcmd.NewCommand("remote", "rm").AddDynamicArguments(remoteName)
|
cmd := gitcmd.NewCommand("remote", "rm").AddDynamicArguments(remoteName)
|
||||||
_, err := runCmdString(ctx, repo, cmd)
|
_, err := RunCmdString(ctx, repo, cmd)
|
||||||
return err
|
return err
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -63,22 +63,18 @@ func GitRemoteGetURL(ctx context.Context, repo Repository, remoteName string) (*
|
|||||||
|
|
||||||
// GitRemotePrune prunes the remote branches that no longer exist in the remote repository.
|
// GitRemotePrune prunes the remote branches that no longer exist in the remote repository.
|
||||||
func GitRemotePrune(ctx context.Context, repo Repository, remoteName string, timeout time.Duration, stdout, stderr io.Writer) error {
|
func GitRemotePrune(ctx context.Context, repo Repository, remoteName string, timeout time.Duration, stdout, stderr io.Writer) error {
|
||||||
return gitcmd.NewCommand("remote", "prune").AddDynamicArguments(remoteName).
|
return RunCmd(ctx, repo, gitcmd.NewCommand("remote", "prune").
|
||||||
Run(ctx, &gitcmd.RunOpts{
|
AddDynamicArguments(remoteName).
|
||||||
Timeout: timeout,
|
WithTimeout(timeout).
|
||||||
Dir: repoPath(repo),
|
WithStdout(stdout).
|
||||||
Stdout: stdout,
|
WithStderr(stderr))
|
||||||
Stderr: stderr,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GitRemoteUpdatePrune updates the remote branches and prunes the ones that no longer exist in the remote repository.
|
// GitRemoteUpdatePrune updates the remote branches and prunes the ones that no longer exist in the remote repository.
|
||||||
func GitRemoteUpdatePrune(ctx context.Context, repo Repository, remoteName string, timeout time.Duration, stdout, stderr io.Writer) error {
|
func GitRemoteUpdatePrune(ctx context.Context, repo Repository, remoteName string, timeout time.Duration, stdout, stderr io.Writer) error {
|
||||||
return gitcmd.NewCommand("remote", "update", "--prune").AddDynamicArguments(remoteName).
|
return RunCmd(ctx, repo, gitcmd.NewCommand("remote", "update", "--prune").
|
||||||
Run(ctx, &gitcmd.RunOpts{
|
AddDynamicArguments(remoteName).
|
||||||
Timeout: timeout,
|
WithTimeout(timeout).
|
||||||
Dir: repoPath(repo),
|
WithStdout(stdout).
|
||||||
Stdout: stdout,
|
WithStderr(stderr))
|
||||||
Stderr: stderr,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
37
modules/gitrepo/size.go
Normal file
37
modules/gitrepo/size.go
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
// Copyright 2025 The Gitea Authors. All rights reserved.
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
package gitrepo
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
)
|
||||||
|
|
||||||
|
const notRegularFileMode = os.ModeSymlink | os.ModeNamedPipe | os.ModeSocket | os.ModeDevice | os.ModeCharDevice | os.ModeIrregular
|
||||||
|
|
||||||
|
// CalcRepositorySize returns the disk consumption for a given path
|
||||||
|
func CalcRepositorySize(repo Repository) (int64, error) {
|
||||||
|
var size int64
|
||||||
|
err := filepath.WalkDir(repoPath(repo), func(_ string, entry os.DirEntry, err error) error {
|
||||||
|
if os.IsNotExist(err) { // ignore the error because some files (like temp/lock file) may be deleted during traversing.
|
||||||
|
return nil
|
||||||
|
} else if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if entry.IsDir() {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
info, err := entry.Info()
|
||||||
|
if os.IsNotExist(err) { // ignore the error as above
|
||||||
|
return nil
|
||||||
|
} else if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if (info.Mode() & notRegularFileMode) == 0 {
|
||||||
|
size += info.Size()
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
return size, err
|
||||||
|
}
|
@@ -17,6 +17,7 @@ import (
|
|||||||
"code.gitea.io/gitea/modules/charset"
|
"code.gitea.io/gitea/modules/charset"
|
||||||
"code.gitea.io/gitea/modules/git"
|
"code.gitea.io/gitea/modules/git"
|
||||||
"code.gitea.io/gitea/modules/git/gitcmd"
|
"code.gitea.io/gitea/modules/git/gitcmd"
|
||||||
|
"code.gitea.io/gitea/modules/gitrepo"
|
||||||
"code.gitea.io/gitea/modules/indexer"
|
"code.gitea.io/gitea/modules/indexer"
|
||||||
path_filter "code.gitea.io/gitea/modules/indexer/code/bleve/token/path"
|
path_filter "code.gitea.io/gitea/modules/indexer/code/bleve/token/path"
|
||||||
"code.gitea.io/gitea/modules/indexer/code/internal"
|
"code.gitea.io/gitea/modules/indexer/code/internal"
|
||||||
@@ -163,7 +164,7 @@ func (b *Indexer) addUpdate(ctx context.Context, batchWriter git.WriteCloserErro
|
|||||||
var err error
|
var err error
|
||||||
if !update.Sized {
|
if !update.Sized {
|
||||||
var stdout string
|
var stdout string
|
||||||
stdout, _, err = gitcmd.NewCommand("cat-file", "-s").AddDynamicArguments(update.BlobSha).RunStdString(ctx, &gitcmd.RunOpts{Dir: repo.RepoPath()})
|
stdout, err = gitrepo.RunCmdString(ctx, repo, gitcmd.NewCommand("cat-file", "-s").AddDynamicArguments(update.BlobSha))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@@ -16,6 +16,7 @@ import (
|
|||||||
"code.gitea.io/gitea/modules/charset"
|
"code.gitea.io/gitea/modules/charset"
|
||||||
"code.gitea.io/gitea/modules/git"
|
"code.gitea.io/gitea/modules/git"
|
||||||
"code.gitea.io/gitea/modules/git/gitcmd"
|
"code.gitea.io/gitea/modules/git/gitcmd"
|
||||||
|
"code.gitea.io/gitea/modules/gitrepo"
|
||||||
"code.gitea.io/gitea/modules/indexer"
|
"code.gitea.io/gitea/modules/indexer"
|
||||||
"code.gitea.io/gitea/modules/indexer/code/internal"
|
"code.gitea.io/gitea/modules/indexer/code/internal"
|
||||||
indexer_internal "code.gitea.io/gitea/modules/indexer/internal"
|
indexer_internal "code.gitea.io/gitea/modules/indexer/internal"
|
||||||
@@ -148,7 +149,7 @@ func (b *Indexer) addUpdate(ctx context.Context, batchWriter git.WriteCloserErro
|
|||||||
var err error
|
var err error
|
||||||
if !update.Sized {
|
if !update.Sized {
|
||||||
var stdout string
|
var stdout string
|
||||||
stdout, _, err = gitcmd.NewCommand("cat-file", "-s").AddDynamicArguments(update.BlobSha).RunStdString(ctx, &gitcmd.RunOpts{Dir: repo.RepoPath()})
|
stdout, err = gitrepo.RunCmdString(ctx, repo, gitcmd.NewCommand("cat-file", "-s").AddDynamicArguments(update.BlobSha))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@@ -11,13 +11,14 @@ import (
|
|||||||
repo_model "code.gitea.io/gitea/models/repo"
|
repo_model "code.gitea.io/gitea/models/repo"
|
||||||
"code.gitea.io/gitea/modules/git"
|
"code.gitea.io/gitea/modules/git"
|
||||||
"code.gitea.io/gitea/modules/git/gitcmd"
|
"code.gitea.io/gitea/modules/git/gitcmd"
|
||||||
|
"code.gitea.io/gitea/modules/gitrepo"
|
||||||
"code.gitea.io/gitea/modules/indexer/code/internal"
|
"code.gitea.io/gitea/modules/indexer/code/internal"
|
||||||
"code.gitea.io/gitea/modules/log"
|
"code.gitea.io/gitea/modules/log"
|
||||||
"code.gitea.io/gitea/modules/setting"
|
"code.gitea.io/gitea/modules/setting"
|
||||||
)
|
)
|
||||||
|
|
||||||
func getDefaultBranchSha(ctx context.Context, repo *repo_model.Repository) (string, error) {
|
func getDefaultBranchSha(ctx context.Context, repo *repo_model.Repository) (string, error) {
|
||||||
stdout, _, err := gitcmd.NewCommand("show-ref", "-s").AddDynamicArguments(git.BranchPrefix+repo.DefaultBranch).RunStdString(ctx, &gitcmd.RunOpts{Dir: repo.RepoPath()})
|
stdout, err := gitrepo.RunCmdString(ctx, repo, gitcmd.NewCommand("show-ref", "-s").AddDynamicArguments(git.BranchPrefix+repo.DefaultBranch))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
@@ -34,7 +35,7 @@ func getRepoChanges(ctx context.Context, repo *repo_model.Repository, revision s
|
|||||||
needGenesis := len(status.CommitSha) == 0
|
needGenesis := len(status.CommitSha) == 0
|
||||||
if !needGenesis {
|
if !needGenesis {
|
||||||
hasAncestorCmd := gitcmd.NewCommand("merge-base").AddDynamicArguments(status.CommitSha, revision)
|
hasAncestorCmd := gitcmd.NewCommand("merge-base").AddDynamicArguments(status.CommitSha, revision)
|
||||||
stdout, _, _ := hasAncestorCmd.RunStdString(ctx, &gitcmd.RunOpts{Dir: repo.RepoPath()})
|
stdout, _ := gitrepo.RunCmdString(ctx, repo, hasAncestorCmd)
|
||||||
needGenesis = len(stdout) == 0
|
needGenesis = len(stdout) == 0
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,7 +88,7 @@ func parseGitLsTreeOutput(stdout []byte) ([]internal.FileUpdate, error) {
|
|||||||
// genesisChanges get changes to add repo to the indexer for the first time
|
// genesisChanges get changes to add repo to the indexer for the first time
|
||||||
func genesisChanges(ctx context.Context, repo *repo_model.Repository, revision string) (*internal.RepoChanges, error) {
|
func genesisChanges(ctx context.Context, repo *repo_model.Repository, revision string) (*internal.RepoChanges, error) {
|
||||||
var changes internal.RepoChanges
|
var changes internal.RepoChanges
|
||||||
stdout, _, runErr := gitcmd.NewCommand("ls-tree", "--full-tree", "-l", "-r").AddDynamicArguments(revision).RunStdBytes(ctx, &gitcmd.RunOpts{Dir: repo.RepoPath()})
|
stdout, _, runErr := gitrepo.RunCmdBytes(ctx, repo, gitcmd.NewCommand("ls-tree", "--full-tree", "-l", "-r").AddDynamicArguments(revision))
|
||||||
if runErr != nil {
|
if runErr != nil {
|
||||||
return nil, runErr
|
return nil, runErr
|
||||||
}
|
}
|
||||||
@@ -100,7 +101,7 @@ func genesisChanges(ctx context.Context, repo *repo_model.Repository, revision s
|
|||||||
// nonGenesisChanges get changes since the previous indexer update
|
// nonGenesisChanges get changes since the previous indexer update
|
||||||
func nonGenesisChanges(ctx context.Context, repo *repo_model.Repository, revision string) (*internal.RepoChanges, error) {
|
func nonGenesisChanges(ctx context.Context, repo *repo_model.Repository, revision string) (*internal.RepoChanges, error) {
|
||||||
diffCmd := gitcmd.NewCommand("diff", "--name-status").AddDynamicArguments(repo.CodeIndexerStatus.CommitSha, revision)
|
diffCmd := gitcmd.NewCommand("diff", "--name-status").AddDynamicArguments(repo.CodeIndexerStatus.CommitSha, revision)
|
||||||
stdout, _, runErr := diffCmd.RunStdString(ctx, &gitcmd.RunOpts{Dir: repo.RepoPath()})
|
stdout, runErr := gitrepo.RunCmdString(ctx, repo, diffCmd)
|
||||||
if runErr != nil {
|
if runErr != nil {
|
||||||
// previous commit sha may have been removed by a force push, so
|
// previous commit sha may have been removed by a force push, so
|
||||||
// try rebuilding from scratch
|
// try rebuilding from scratch
|
||||||
@@ -118,7 +119,7 @@ func nonGenesisChanges(ctx context.Context, repo *repo_model.Repository, revisio
|
|||||||
updateChanges := func() error {
|
updateChanges := func() error {
|
||||||
cmd := gitcmd.NewCommand("ls-tree", "--full-tree", "-l").AddDynamicArguments(revision).
|
cmd := gitcmd.NewCommand("ls-tree", "--full-tree", "-l").AddDynamicArguments(revision).
|
||||||
AddDashesAndList(updatedFilenames...)
|
AddDashesAndList(updatedFilenames...)
|
||||||
lsTreeStdout, _, err := cmd.RunStdBytes(ctx, &gitcmd.RunOpts{Dir: repo.RepoPath()})
|
lsTreeStdout, _, err := gitrepo.RunCmdBytes(ctx, repo, cmd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@@ -6,44 +6,15 @@ package repository
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
|
|
||||||
git_model "code.gitea.io/gitea/models/git"
|
git_model "code.gitea.io/gitea/models/git"
|
||||||
repo_model "code.gitea.io/gitea/models/repo"
|
repo_model "code.gitea.io/gitea/models/repo"
|
||||||
|
"code.gitea.io/gitea/modules/gitrepo"
|
||||||
)
|
)
|
||||||
|
|
||||||
const notRegularFileMode = os.ModeSymlink | os.ModeNamedPipe | os.ModeSocket | os.ModeDevice | os.ModeCharDevice | os.ModeIrregular
|
|
||||||
|
|
||||||
// getDirectorySize returns the disk consumption for a given path
|
|
||||||
func getDirectorySize(path string) (int64, error) {
|
|
||||||
var size int64
|
|
||||||
err := filepath.WalkDir(path, func(_ string, entry os.DirEntry, err error) error {
|
|
||||||
if os.IsNotExist(err) { // ignore the error because some files (like temp/lock file) may be deleted during traversing.
|
|
||||||
return nil
|
|
||||||
} else if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if entry.IsDir() {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
info, err := entry.Info()
|
|
||||||
if os.IsNotExist(err) { // ignore the error as above
|
|
||||||
return nil
|
|
||||||
} else if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if (info.Mode() & notRegularFileMode) == 0 {
|
|
||||||
size += info.Size()
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
return size, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// UpdateRepoSize updates the repository size, calculating it using getDirectorySize
|
// UpdateRepoSize updates the repository size, calculating it using getDirectorySize
|
||||||
func UpdateRepoSize(ctx context.Context, repo *repo_model.Repository) error {
|
func UpdateRepoSize(ctx context.Context, repo *repo_model.Repository) error {
|
||||||
size, err := getDirectorySize(repo.RepoPath())
|
size, err := gitrepo.CalcRepositorySize(repo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("updateSize: %w", err)
|
return fmt.Errorf("updateSize: %w", err)
|
||||||
}
|
}
|
||||||
|
@@ -8,6 +8,7 @@ import (
|
|||||||
|
|
||||||
repo_model "code.gitea.io/gitea/models/repo"
|
repo_model "code.gitea.io/gitea/models/repo"
|
||||||
"code.gitea.io/gitea/models/unittest"
|
"code.gitea.io/gitea/models/unittest"
|
||||||
|
"code.gitea.io/gitea/modules/gitrepo"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
@@ -16,7 +17,7 @@ func TestGetDirectorySize(t *testing.T) {
|
|||||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||||
repo, err := repo_model.GetRepositoryByID(t.Context(), 1)
|
repo, err := repo_model.GetRepositoryByID(t.Context(), 1)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
size, err := getDirectorySize(repo.RepoPath())
|
size, err := gitrepo.CalcRepositorySize(repo)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
repo.Size = 8165 // real size on the disk
|
repo.Size = 8165 // real size on the disk
|
||||||
assert.Equal(t, repo.Size, size)
|
assert.Equal(t, repo.Size, size)
|
||||||
|
@@ -5,9 +5,13 @@ package util
|
|||||||
|
|
||||||
import "runtime"
|
import "runtime"
|
||||||
|
|
||||||
func CallerFuncName(skip int) string {
|
func CallerFuncName(optSkipParent ...int) string {
|
||||||
pc := make([]uintptr, 1)
|
pc := make([]uintptr, 1)
|
||||||
runtime.Callers(skip+1, pc)
|
skipParent := 0
|
||||||
|
if len(optSkipParent) > 0 {
|
||||||
|
skipParent = optSkipParent[0]
|
||||||
|
}
|
||||||
|
runtime.Callers(skipParent+1 /*this*/ +1 /*runtime*/, pc)
|
||||||
funcName := runtime.FuncForPC(pc[0]).Name()
|
funcName := runtime.FuncForPC(pc[0]).Name()
|
||||||
return funcName
|
return funcName
|
||||||
}
|
}
|
||||||
|
@@ -11,7 +11,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestCallerFuncName(t *testing.T) {
|
func TestCallerFuncName(t *testing.T) {
|
||||||
s := CallerFuncName(1)
|
s := CallerFuncName()
|
||||||
assert.Equal(t, "code.gitea.io/gitea/modules/util.TestCallerFuncName", s)
|
assert.Equal(t, "code.gitea.io/gitea/modules/util.TestCallerFuncName", s)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -26,7 +26,7 @@ func BenchmarkCallerFuncName(b *testing.B) {
|
|||||||
// It is almost as fast as fmt.Sprintf
|
// It is almost as fast as fmt.Sprintf
|
||||||
b.Run("caller", func(b *testing.B) {
|
b.Run("caller", func(b *testing.B) {
|
||||||
for b.Loop() {
|
for b.Loop() {
|
||||||
CallerFuncName(1)
|
CallerFuncName()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@@ -189,7 +189,12 @@ func preReceiveBranch(ctx *preReceiveContext, oldCommitID, newCommitID string, r
|
|||||||
|
|
||||||
// 2. Disallow force pushes to protected branches
|
// 2. Disallow force pushes to protected branches
|
||||||
if oldCommitID != objectFormat.EmptyObjectID().String() {
|
if oldCommitID != objectFormat.EmptyObjectID().String() {
|
||||||
output, _, err := gitcmd.NewCommand("rev-list", "--max-count=1").AddDynamicArguments(oldCommitID, "^"+newCommitID).RunStdString(ctx, &gitcmd.RunOpts{Dir: repo.RepoPath(), Env: ctx.env})
|
output, err := gitrepo.RunCmdString(ctx,
|
||||||
|
repo,
|
||||||
|
gitcmd.NewCommand("rev-list", "--max-count=1").
|
||||||
|
AddDynamicArguments(oldCommitID, "^"+newCommitID).
|
||||||
|
WithEnv(ctx.env),
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Unable to detect force push between: %s and %s in %-v Error: %v", oldCommitID, newCommitID, repo, err)
|
log.Error("Unable to detect force push between: %s and %s in %-v Error: %v", oldCommitID, newCommitID, repo, err)
|
||||||
ctx.JSON(http.StatusInternalServerError, private.Response{
|
ctx.JSON(http.StatusInternalServerError, private.Response{
|
||||||
|
@@ -39,11 +39,10 @@ func verifyCommits(oldCommitID, newCommitID string, repo *git.Repository, env []
|
|||||||
command = gitcmd.NewCommand("rev-list").AddDynamicArguments(oldCommitID + "..." + newCommitID)
|
command = gitcmd.NewCommand("rev-list").AddDynamicArguments(oldCommitID + "..." + newCommitID)
|
||||||
}
|
}
|
||||||
// This is safe as force pushes are already forbidden
|
// This is safe as force pushes are already forbidden
|
||||||
err = command.Run(repo.Ctx, &gitcmd.RunOpts{
|
err = command.WithEnv(env).
|
||||||
Env: env,
|
WithDir(repo.Path).
|
||||||
Dir: repo.Path,
|
WithStdout(stdoutWriter).
|
||||||
Stdout: stdoutWriter,
|
WithPipelineFunc(func(ctx context.Context, cancel context.CancelFunc) error {
|
||||||
PipelineFunc: func(ctx context.Context, cancel context.CancelFunc) error {
|
|
||||||
_ = stdoutWriter.Close()
|
_ = stdoutWriter.Close()
|
||||||
err := readAndVerifyCommitsFromShaReader(stdoutReader, repo, env)
|
err := readAndVerifyCommitsFromShaReader(stdoutReader, repo, env)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -52,8 +51,8 @@ func verifyCommits(oldCommitID, newCommitID string, repo *git.Repository, env []
|
|||||||
}
|
}
|
||||||
_ = stdoutReader.Close()
|
_ = stdoutReader.Close()
|
||||||
return err
|
return err
|
||||||
},
|
}).
|
||||||
})
|
Run(repo.Ctx)
|
||||||
if err != nil && !isErrUnverifiedCommit(err) {
|
if err != nil && !isErrUnverifiedCommit(err) {
|
||||||
log.Error("Unable to check commits from %s to %s in %s: %v", oldCommitID, newCommitID, repo.Path, err)
|
log.Error("Unable to check commits from %s to %s in %s: %v", oldCommitID, newCommitID, repo.Path, err)
|
||||||
}
|
}
|
||||||
@@ -86,26 +85,25 @@ func readAndVerifyCommit(sha string, repo *git.Repository, env []string) error {
|
|||||||
commitID := git.MustIDFromString(sha)
|
commitID := git.MustIDFromString(sha)
|
||||||
|
|
||||||
return gitcmd.NewCommand("cat-file", "commit").AddDynamicArguments(sha).
|
return gitcmd.NewCommand("cat-file", "commit").AddDynamicArguments(sha).
|
||||||
Run(repo.Ctx, &gitcmd.RunOpts{
|
WithEnv(env).
|
||||||
Env: env,
|
WithDir(repo.Path).
|
||||||
Dir: repo.Path,
|
WithStdout(stdoutWriter).
|
||||||
Stdout: stdoutWriter,
|
WithPipelineFunc(func(ctx context.Context, cancel context.CancelFunc) error {
|
||||||
PipelineFunc: func(ctx context.Context, cancel context.CancelFunc) error {
|
_ = stdoutWriter.Close()
|
||||||
_ = stdoutWriter.Close()
|
commit, err := git.CommitFromReader(repo, commitID, stdoutReader)
|
||||||
commit, err := git.CommitFromReader(repo, commitID, stdoutReader)
|
if err != nil {
|
||||||
if err != nil {
|
return err
|
||||||
return err
|
}
|
||||||
|
verification := asymkey_service.ParseCommitWithSignature(ctx, commit)
|
||||||
|
if !verification.Verified {
|
||||||
|
cancel()
|
||||||
|
return &errUnverifiedCommit{
|
||||||
|
commit.ID.String(),
|
||||||
}
|
}
|
||||||
verification := asymkey_service.ParseCommitWithSignature(ctx, commit)
|
}
|
||||||
if !verification.Verified {
|
return nil
|
||||||
cancel()
|
}).
|
||||||
return &errUnverifiedCommit{
|
Run(repo.Ctx)
|
||||||
commit.ID.String(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type errUnverifiedCommit struct {
|
type errUnverifiedCommit struct {
|
||||||
|
@@ -316,7 +316,9 @@ func dummyInfoRefs(ctx *context.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
refs, _, err := gitcmd.NewCommand("receive-pack", "--stateless-rpc", "--advertise-refs", ".").RunStdBytes(ctx, &gitcmd.RunOpts{Dir: tmpDir})
|
refs, _, err := gitcmd.NewCommand("receive-pack", "--stateless-rpc", "--advertise-refs", ".").
|
||||||
|
WithDir(tmpDir).
|
||||||
|
RunStdBytes(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error(fmt.Sprintf("%v - %s", err, string(refs)))
|
log.Error(fmt.Sprintf("%v - %s", err, string(refs)))
|
||||||
}
|
}
|
||||||
@@ -447,15 +449,15 @@ func serviceRPC(ctx *context.Context, h *serviceHandler, service string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var stderr bytes.Buffer
|
var stderr bytes.Buffer
|
||||||
cmd.AddArguments("--stateless-rpc").AddDynamicArguments(h.getRepoDir())
|
if err := cmd.AddArguments("--stateless-rpc").
|
||||||
if err := cmd.Run(ctx, &gitcmd.RunOpts{
|
AddDynamicArguments(h.getRepoDir()).
|
||||||
Dir: h.getRepoDir(),
|
WithDir(h.getRepoDir()).
|
||||||
Env: append(os.Environ(), h.environ...),
|
WithEnv(append(os.Environ(), h.environ...)).
|
||||||
Stdout: ctx.Resp,
|
WithStderr(&stderr).
|
||||||
Stdin: reqBody,
|
WithStdin(reqBody).
|
||||||
Stderr: &stderr,
|
WithStdout(ctx.Resp).
|
||||||
UseContextTimeout: true,
|
WithUseContextTimeout(true).
|
||||||
}); err != nil {
|
Run(ctx); err != nil {
|
||||||
if !git.IsErrCanceledOrKilled(err) {
|
if !git.IsErrCanceledOrKilled(err) {
|
||||||
log.Error("Fail to serve RPC(%s) in %s: %v - %s", service, h.getRepoDir(), err, stderr.String())
|
log.Error("Fail to serve RPC(%s) in %s: %v - %s", service, h.getRepoDir(), err, stderr.String())
|
||||||
}
|
}
|
||||||
@@ -495,7 +497,7 @@ func getServiceType(ctx *context.Context) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func updateServerInfo(ctx gocontext.Context, dir string) []byte {
|
func updateServerInfo(ctx gocontext.Context, dir string) []byte {
|
||||||
out, _, err := gitcmd.NewCommand("update-server-info").RunStdBytes(ctx, &gitcmd.RunOpts{Dir: dir})
|
out, _, err := gitcmd.NewCommand("update-server-info").WithDir(dir).RunStdBytes(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error(fmt.Sprintf("%v - %s", err, string(out)))
|
log.Error(fmt.Sprintf("%v - %s", err, string(out)))
|
||||||
}
|
}
|
||||||
@@ -525,7 +527,10 @@ func GetInfoRefs(ctx *context.Context) {
|
|||||||
}
|
}
|
||||||
h.environ = append(os.Environ(), h.environ...)
|
h.environ = append(os.Environ(), h.environ...)
|
||||||
|
|
||||||
refs, _, err := cmd.AddArguments("--stateless-rpc", "--advertise-refs", ".").RunStdBytes(ctx, &gitcmd.RunOpts{Env: h.environ, Dir: h.getRepoDir()})
|
refs, _, err := cmd.AddArguments("--stateless-rpc", "--advertise-refs", ".").
|
||||||
|
WithEnv(h.environ).
|
||||||
|
WithDir(h.getRepoDir()).
|
||||||
|
RunStdBytes(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error(fmt.Sprintf("%v - %s", err, string(refs)))
|
log.Error(fmt.Sprintf("%v - %s", err, string(refs)))
|
||||||
}
|
}
|
||||||
|
@@ -234,7 +234,8 @@ func GetMergedBaseCommitID(ctx *context.Context, issue *issues_model.Issue) stri
|
|||||||
}
|
}
|
||||||
if commitSHA != "" {
|
if commitSHA != "" {
|
||||||
// Get immediate parent of the first commit in the patch, grab history back
|
// Get immediate parent of the first commit in the patch, grab history back
|
||||||
parentCommit, _, err = gitcmd.NewCommand("rev-list", "-1", "--skip=1").AddDynamicArguments(commitSHA).RunStdString(ctx, &gitcmd.RunOpts{Dir: ctx.Repo.GitRepo.Path})
|
parentCommit, err = gitrepo.RunCmdString(ctx, ctx.Repo.Repository,
|
||||||
|
gitcmd.NewCommand("rev-list", "-1", "--skip=1").AddDynamicArguments(commitSHA))
|
||||||
if err == nil {
|
if err == nil {
|
||||||
parentCommit = strings.TrimSpace(parentCommit)
|
parentCommit = strings.TrimSpace(parentCommit)
|
||||||
}
|
}
|
||||||
|
@@ -195,7 +195,7 @@ func notify(ctx context.Context, input *notifyInput) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
log.Trace("repo %s with commit %s event %s find %d workflows and %d schedules",
|
log.Trace("repo %s with commit %s event %s find %d workflows and %d schedules",
|
||||||
input.Repo.RepoPath(),
|
input.Repo.RelativePath(),
|
||||||
commit.ID,
|
commit.ID,
|
||||||
input.Event,
|
input.Event,
|
||||||
len(workflows),
|
len(workflows),
|
||||||
@@ -204,7 +204,7 @@ func notify(ctx context.Context, input *notifyInput) error {
|
|||||||
|
|
||||||
for _, wf := range workflows {
|
for _, wf := range workflows {
|
||||||
if actionsConfig.IsWorkflowDisabled(wf.EntryName) {
|
if actionsConfig.IsWorkflowDisabled(wf.EntryName) {
|
||||||
log.Trace("repo %s has disable workflows %s", input.Repo.RepoPath(), wf.EntryName)
|
log.Trace("repo %s has disable workflows %s", input.Repo.RelativePath(), wf.EntryName)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -225,7 +225,7 @@ func notify(ctx context.Context, input *notifyInput) error {
|
|||||||
return fmt.Errorf("DetectWorkflows: %w", err)
|
return fmt.Errorf("DetectWorkflows: %w", err)
|
||||||
}
|
}
|
||||||
if len(baseWorkflows) == 0 {
|
if len(baseWorkflows) == 0 {
|
||||||
log.Trace("repo %s with commit %s couldn't find pull_request_target workflows", input.Repo.RepoPath(), baseCommit.ID)
|
log.Trace("repo %s with commit %s couldn't find pull_request_target workflows", input.Repo.RelativePath(), baseCommit.ID)
|
||||||
} else {
|
} else {
|
||||||
for _, wf := range baseWorkflows {
|
for _, wf := range baseWorkflows {
|
||||||
if wf.TriggerEvent.Name == actions_module.GithubEventPullRequestTarget {
|
if wf.TriggerEvent.Name == actions_module.GithubEventPullRequestTarget {
|
||||||
@@ -255,11 +255,11 @@ func skipWorkflows(ctx context.Context, input *notifyInput, commit *git.Commit)
|
|||||||
if slices.Contains(skipWorkflowEvents, input.Event) {
|
if slices.Contains(skipWorkflowEvents, input.Event) {
|
||||||
for _, s := range setting.Actions.SkipWorkflowStrings {
|
for _, s := range setting.Actions.SkipWorkflowStrings {
|
||||||
if input.PullRequest != nil && strings.Contains(input.PullRequest.Issue.Title, s) {
|
if input.PullRequest != nil && strings.Contains(input.PullRequest.Issue.Title, s) {
|
||||||
log.Debug("repo %s: skipped run for pr %v because of %s string", input.Repo.RepoPath(), input.PullRequest.Issue.ID, s)
|
log.Debug("repo %s: skipped run for pr %v because of %s string", input.Repo.RelativePath(), input.PullRequest.Issue.ID, s)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if strings.Contains(commit.CommitMessage, s) {
|
if strings.Contains(commit.CommitMessage, s) {
|
||||||
log.Debug("repo %s with commit %s: skipped run because of %s string", input.Repo.RepoPath(), commit.ID, s)
|
log.Debug("repo %s with commit %s: skipped run because of %s string", input.Repo.RelativePath(), commit.ID, s)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -282,7 +282,7 @@ func skipWorkflows(ctx context.Context, input *notifyInput, commit *git.Commit)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// skip workflow runs events exceeding the maximum of 5 recursive events
|
// skip workflow runs events exceeding the maximum of 5 recursive events
|
||||||
log.Debug("repo %s: skipped workflow_run because of recursive event of 5", input.Repo.RepoPath())
|
log.Debug("repo %s: skipped workflow_run because of recursive event of 5", input.Repo.RelativePath())
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
@@ -296,7 +296,7 @@ func handleWorkflows(
|
|||||||
ref string,
|
ref string,
|
||||||
) error {
|
) error {
|
||||||
if len(detectedWorkflows) == 0 {
|
if len(detectedWorkflows) == 0 {
|
||||||
log.Trace("repo %s with commit %s couldn't find workflows", input.Repo.RepoPath(), commit.ID)
|
log.Trace("repo %s with commit %s couldn't find workflows", input.Repo.RelativePath(), commit.ID)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -521,7 +521,7 @@ func handleSchedules(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if len(detectedWorkflows) == 0 {
|
if len(detectedWorkflows) == 0 {
|
||||||
log.Trace("repo %s with commit %s couldn't find schedules", input.Repo.RepoPath(), commit.ID)
|
log.Trace("repo %s with commit %s couldn't find schedules", input.Repo.RelativePath(), commit.ID)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -7,7 +7,6 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
git_model "code.gitea.io/gitea/models/git"
|
git_model "code.gitea.io/gitea/models/git"
|
||||||
@@ -199,9 +198,10 @@ func ProcReceive(ctx context.Context, repo *repo_model.Repository, gitRepo *git.
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !forcePush.Value() {
|
if !forcePush.Value() {
|
||||||
output, _, err := gitcmd.NewCommand("rev-list", "--max-count=1").
|
output, err := gitrepo.RunCmdString(ctx, repo,
|
||||||
AddDynamicArguments(oldCommitID, "^"+opts.NewCommitIDs[i]).
|
gitcmd.NewCommand("rev-list", "--max-count=1").
|
||||||
RunStdString(ctx, &gitcmd.RunOpts{Dir: repo.RepoPath(), Env: os.Environ()})
|
AddDynamicArguments(oldCommitID, "^"+opts.NewCommitIDs[i]),
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to detect force push: %w", err)
|
return nil, fmt.Errorf("failed to detect force push: %w", err)
|
||||||
} else if len(output) > 0 {
|
} else if len(output) > 0 {
|
||||||
|
@@ -117,16 +117,16 @@ func SigningKey(ctx context.Context, repoPath string) (*git.SigningKey, *git.Sig
|
|||||||
|
|
||||||
if setting.Repository.Signing.SigningKey == "default" || setting.Repository.Signing.SigningKey == "" {
|
if setting.Repository.Signing.SigningKey == "default" || setting.Repository.Signing.SigningKey == "" {
|
||||||
// Can ignore the error here as it means that commit.gpgsign is not set
|
// Can ignore the error here as it means that commit.gpgsign is not set
|
||||||
value, _, _ := gitcmd.NewCommand("config", "--get", "commit.gpgsign").RunStdString(ctx, &gitcmd.RunOpts{Dir: repoPath})
|
value, _, _ := gitcmd.NewCommand("config", "--get", "commit.gpgsign").WithDir(repoPath).RunStdString(ctx)
|
||||||
sign, valid := git.ParseBool(strings.TrimSpace(value))
|
sign, valid := git.ParseBool(strings.TrimSpace(value))
|
||||||
if !sign || !valid {
|
if !sign || !valid {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
format, _, _ := gitcmd.NewCommand("config", "--default", git.SigningKeyFormatOpenPGP, "--get", "gpg.format").RunStdString(ctx, &gitcmd.RunOpts{Dir: repoPath})
|
format, _, _ := gitcmd.NewCommand("config", "--default", git.SigningKeyFormatOpenPGP, "--get", "gpg.format").WithDir(repoPath).RunStdString(ctx)
|
||||||
signingKey, _, _ := gitcmd.NewCommand("config", "--get", "user.signingkey").RunStdString(ctx, &gitcmd.RunOpts{Dir: repoPath})
|
signingKey, _, _ := gitcmd.NewCommand("config", "--get", "user.signingkey").WithDir(repoPath).RunStdString(ctx)
|
||||||
signingName, _, _ := gitcmd.NewCommand("config", "--get", "user.name").RunStdString(ctx, &gitcmd.RunOpts{Dir: repoPath})
|
signingName, _, _ := gitcmd.NewCommand("config", "--get", "user.name").WithDir(repoPath).RunStdString(ctx)
|
||||||
signingEmail, _, _ := gitcmd.NewCommand("config", "--get", "user.email").RunStdString(ctx, &gitcmd.RunOpts{Dir: repoPath})
|
signingEmail, _, _ := gitcmd.NewCommand("config", "--get", "user.email").WithDir(repoPath).RunStdString(ctx)
|
||||||
|
|
||||||
if strings.TrimSpace(signingKey) == "" {
|
if strings.TrimSpace(signingKey) == "" {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
|
@@ -621,7 +621,7 @@ func RepoAssignment(ctx *Context) {
|
|||||||
ctx.Repo.GitRepo, err = gitrepo.RepositoryFromRequestContextOrOpen(ctx, repo)
|
ctx.Repo.GitRepo, err = gitrepo.RepositoryFromRequestContextOrOpen(ctx, repo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if strings.Contains(err.Error(), "repository does not exist") || strings.Contains(err.Error(), "no such file or directory") {
|
if strings.Contains(err.Error(), "repository does not exist") || strings.Contains(err.Error(), "no such file or directory") {
|
||||||
log.Error("Repository %-v has a broken repository on the file system: %s Error: %v", ctx.Repo.Repository, ctx.Repo.Repository.RepoPath(), err)
|
log.Error("Repository %-v has a broken repository on the file system: %s Error: %v", ctx.Repo.Repository, ctx.Repo.Repository.RelativePath(), err)
|
||||||
ctx.Repo.Repository.MarkAsBrokenEmpty()
|
ctx.Repo.Repository.MarkAsBrokenEmpty()
|
||||||
// Only allow access to base of repo or settings
|
// Only allow access to base of repo or settings
|
||||||
if !isHomeOrSettings {
|
if !isHomeOrSettings {
|
||||||
|
@@ -146,7 +146,7 @@ func ToAPIPullRequest(ctx context.Context, pr *issues_model.PullRequest, doer *u
|
|||||||
|
|
||||||
gitRepo, err := gitrepo.OpenRepository(ctx, pr.BaseRepo)
|
gitRepo, err := gitrepo.OpenRepository(ctx, pr.BaseRepo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("OpenRepository[%s]: %v", pr.BaseRepo.RepoPath(), err)
|
log.Error("OpenRepository[%s]: %v", pr.BaseRepo.RelativePath(), err)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
defer gitRepo.Close()
|
defer gitRepo.Close()
|
||||||
@@ -192,7 +192,7 @@ func ToAPIPullRequest(ctx context.Context, pr *issues_model.PullRequest, doer *u
|
|||||||
|
|
||||||
headGitRepo, err := gitrepo.OpenRepository(ctx, pr.HeadRepo)
|
headGitRepo, err := gitrepo.OpenRepository(ctx, pr.HeadRepo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("OpenRepository[%s]: %v", pr.HeadRepo.RepoPath(), err)
|
log.Error("OpenRepository[%s]: %v", pr.HeadRepo.RelativePath(), err)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
defer headGitRepo.Close()
|
defer headGitRepo.Close()
|
||||||
@@ -248,7 +248,7 @@ func ToAPIPullRequest(ctx context.Context, pr *issues_model.PullRequest, doer *u
|
|||||||
if len(apiPullRequest.Head.Sha) == 0 && len(apiPullRequest.Head.Ref) != 0 {
|
if len(apiPullRequest.Head.Sha) == 0 && len(apiPullRequest.Head.Ref) != 0 {
|
||||||
baseGitRepo, err := gitrepo.OpenRepository(ctx, pr.BaseRepo)
|
baseGitRepo, err := gitrepo.OpenRepository(ctx, pr.BaseRepo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("OpenRepository[%s]: %v", pr.BaseRepo.RepoPath(), err)
|
log.Error("OpenRepository[%s]: %v", pr.BaseRepo.RelativePath(), err)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
defer baseGitRepo.Close()
|
defer baseGitRepo.Close()
|
||||||
|
@@ -9,6 +9,7 @@ import (
|
|||||||
repo_model "code.gitea.io/gitea/models/repo"
|
repo_model "code.gitea.io/gitea/models/repo"
|
||||||
"code.gitea.io/gitea/modules/git"
|
"code.gitea.io/gitea/modules/git"
|
||||||
"code.gitea.io/gitea/modules/git/gitcmd"
|
"code.gitea.io/gitea/modules/git/gitcmd"
|
||||||
|
"code.gitea.io/gitea/modules/gitrepo"
|
||||||
"code.gitea.io/gitea/modules/log"
|
"code.gitea.io/gitea/modules/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -19,9 +20,11 @@ func synchronizeRepoHeads(ctx context.Context, logger log.Logger, autofix bool)
|
|||||||
numReposUpdated := 0
|
numReposUpdated := 0
|
||||||
err := iterateRepositories(ctx, func(repo *repo_model.Repository) error {
|
err := iterateRepositories(ctx, func(repo *repo_model.Repository) error {
|
||||||
numRepos++
|
numRepos++
|
||||||
_, _, defaultBranchErr := gitcmd.NewCommand("rev-parse").AddDashesAndList(repo.DefaultBranch).RunStdString(ctx, &gitcmd.RunOpts{Dir: repo.RepoPath()})
|
_, defaultBranchErr := gitrepo.RunCmdString(ctx, repo,
|
||||||
|
gitcmd.NewCommand("rev-parse").AddDashesAndList(repo.DefaultBranch))
|
||||||
|
|
||||||
head, _, headErr := gitcmd.NewCommand("symbolic-ref", "--short", "HEAD").RunStdString(ctx, &gitcmd.RunOpts{Dir: repo.RepoPath()})
|
head, headErr := gitrepo.RunCmdString(ctx, repo,
|
||||||
|
gitcmd.NewCommand("symbolic-ref", "--short", "HEAD"))
|
||||||
|
|
||||||
// what we expect: default branch is valid, and HEAD points to it
|
// what we expect: default branch is valid, and HEAD points to it
|
||||||
if headErr == nil && defaultBranchErr == nil && head == repo.DefaultBranch {
|
if headErr == nil && defaultBranchErr == nil && head == repo.DefaultBranch {
|
||||||
@@ -47,7 +50,7 @@ func synchronizeRepoHeads(ctx context.Context, logger log.Logger, autofix bool)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// otherwise, let's try fixing HEAD
|
// otherwise, let's try fixing HEAD
|
||||||
err := gitcmd.NewCommand("symbolic-ref").AddDashesAndList("HEAD", git.BranchPrefix+repo.DefaultBranch).Run(ctx, &gitcmd.RunOpts{Dir: repo.RepoPath()})
|
err := gitrepo.RunCmd(ctx, repo, gitcmd.NewCommand("symbolic-ref").AddDashesAndList("HEAD", git.BranchPrefix+repo.DefaultBranch))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Warn("Failed to fix HEAD for %s/%s: %v", repo.OwnerName, repo.Name, err)
|
logger.Warn("Failed to fix HEAD for %s/%s: %v", repo.OwnerName, repo.Name, err)
|
||||||
return nil
|
return nil
|
||||||
|
@@ -13,6 +13,7 @@ import (
|
|||||||
repo_model "code.gitea.io/gitea/models/repo"
|
repo_model "code.gitea.io/gitea/models/repo"
|
||||||
"code.gitea.io/gitea/modules/git"
|
"code.gitea.io/gitea/modules/git"
|
||||||
"code.gitea.io/gitea/modules/git/gitcmd"
|
"code.gitea.io/gitea/modules/git/gitcmd"
|
||||||
|
"code.gitea.io/gitea/modules/gitrepo"
|
||||||
"code.gitea.io/gitea/modules/log"
|
"code.gitea.io/gitea/modules/log"
|
||||||
|
|
||||||
"xorm.io/builder"
|
"xorm.io/builder"
|
||||||
@@ -37,23 +38,22 @@ func checkPRMergeBase(ctx context.Context, logger log.Logger, autofix bool) erro
|
|||||||
return iteratePRs(ctx, repo, func(repo *repo_model.Repository, pr *issues_model.PullRequest) error {
|
return iteratePRs(ctx, repo, func(repo *repo_model.Repository, pr *issues_model.PullRequest) error {
|
||||||
numPRs++
|
numPRs++
|
||||||
pr.BaseRepo = repo
|
pr.BaseRepo = repo
|
||||||
repoPath := repo.RepoPath()
|
|
||||||
|
|
||||||
oldMergeBase := pr.MergeBase
|
oldMergeBase := pr.MergeBase
|
||||||
|
|
||||||
if !pr.HasMerged {
|
if !pr.HasMerged {
|
||||||
var err error
|
var err error
|
||||||
pr.MergeBase, _, err = gitcmd.NewCommand("merge-base").AddDashesAndList(pr.BaseBranch, pr.GetGitHeadRefName()).RunStdString(ctx, &gitcmd.RunOpts{Dir: repoPath})
|
pr.MergeBase, err = gitrepo.RunCmdString(ctx, repo, gitcmd.NewCommand("merge-base").AddDashesAndList(pr.BaseBranch, pr.GetGitHeadRefName()))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
var err2 error
|
var err2 error
|
||||||
pr.MergeBase, _, err2 = gitcmd.NewCommand("rev-parse").AddDynamicArguments(git.BranchPrefix+pr.BaseBranch).RunStdString(ctx, &gitcmd.RunOpts{Dir: repoPath})
|
pr.MergeBase, err2 = gitrepo.RunCmdString(ctx, repo, gitcmd.NewCommand("rev-parse").AddDynamicArguments(git.BranchPrefix+pr.BaseBranch))
|
||||||
if err2 != nil {
|
if err2 != nil {
|
||||||
logger.Warn("Unable to get merge base for PR ID %d, #%d onto %s in %s/%s. Error: %v & %v", pr.ID, pr.Index, pr.BaseBranch, pr.BaseRepo.OwnerName, pr.BaseRepo.Name, err, err2)
|
logger.Warn("Unable to get merge base for PR ID %d, #%d onto %s in %s/%s. Error: %v & %v", pr.ID, pr.Index, pr.BaseBranch, pr.BaseRepo.OwnerName, pr.BaseRepo.Name, err, err2)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
parentsString, _, err := gitcmd.NewCommand("rev-list", "--parents", "-n", "1").AddDynamicArguments(pr.MergedCommitID).RunStdString(ctx, &gitcmd.RunOpts{Dir: repoPath})
|
parentsString, err := gitrepo.RunCmdString(ctx, repo, gitcmd.NewCommand("rev-list", "--parents", "-n", "1").AddDynamicArguments(pr.MergedCommitID))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Warn("Unable to get parents for merged PR ID %d, #%d onto %s in %s/%s. Error: %v", pr.ID, pr.Index, pr.BaseBranch, pr.BaseRepo.OwnerName, pr.BaseRepo.Name, err)
|
logger.Warn("Unable to get parents for merged PR ID %d, #%d onto %s in %s/%s. Error: %v", pr.ID, pr.Index, pr.BaseBranch, pr.BaseRepo.OwnerName, pr.BaseRepo.Name, err)
|
||||||
return nil
|
return nil
|
||||||
@@ -66,7 +66,7 @@ func checkPRMergeBase(ctx context.Context, logger log.Logger, autofix bool) erro
|
|||||||
refs := append([]string{}, parents[1:]...)
|
refs := append([]string{}, parents[1:]...)
|
||||||
refs = append(refs, pr.GetGitHeadRefName())
|
refs = append(refs, pr.GetGitHeadRefName())
|
||||||
cmd := gitcmd.NewCommand("merge-base").AddDashesAndList(refs...)
|
cmd := gitcmd.NewCommand("merge-base").AddDashesAndList(refs...)
|
||||||
pr.MergeBase, _, err = cmd.RunStdString(ctx, &gitcmd.RunOpts{Dir: repoPath})
|
pr.MergeBase, err = gitrepo.RunCmdString(ctx, repo, cmd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Warn("Unable to get merge base for merged PR ID %d, #%d onto %s in %s/%s. Error: %v", pr.ID, pr.Index, pr.BaseBranch, pr.BaseRepo.OwnerName, pr.BaseRepo.Name, err)
|
logger.Warn("Unable to get merge base for merged PR ID %d, #%d onto %s in %s/%s. Error: %v", pr.ID, pr.Index, pr.BaseBranch, pr.BaseRepo.OwnerName, pr.BaseRepo.Name, err)
|
||||||
return nil
|
return nil
|
||||||
|
@@ -61,7 +61,7 @@ func runGitDiffTree(ctx context.Context, gitRepo *git.Repository, useMergeBase b
|
|||||||
cmd.AddArguments("--merge-base")
|
cmd.AddArguments("--merge-base")
|
||||||
}
|
}
|
||||||
cmd.AddDynamicArguments(baseCommitID, headCommitID)
|
cmd.AddDynamicArguments(baseCommitID, headCommitID)
|
||||||
stdout, _, runErr := cmd.RunStdString(ctx, &gitcmd.RunOpts{Dir: gitRepo.Path})
|
stdout, _, runErr := cmd.WithDir(gitRepo.Path).RunStdString(ctx)
|
||||||
if runErr != nil {
|
if runErr != nil {
|
||||||
log.Warn("git diff-tree: %v", runErr)
|
log.Warn("git diff-tree: %v", runErr)
|
||||||
return nil, runErr
|
return nil, runErr
|
||||||
|
@@ -1170,12 +1170,11 @@ func getDiffBasic(ctx context.Context, gitRepo *git.Repository, opts *DiffOption
|
|||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
stderr := &bytes.Buffer{}
|
stderr := &bytes.Buffer{}
|
||||||
if err := cmdDiff.Run(cmdCtx, &gitcmd.RunOpts{
|
if err := cmdDiff.WithTimeout(time.Duration(setting.Git.Timeout.Default) * time.Second).
|
||||||
Timeout: time.Duration(setting.Git.Timeout.Default) * time.Second,
|
WithDir(repoPath).
|
||||||
Dir: repoPath,
|
WithStdout(writer).
|
||||||
Stdout: writer,
|
WithStderr(stderr).
|
||||||
Stderr: stderr,
|
Run(cmdCtx); err != nil && !git.IsErrCanceledOrKilled(err) {
|
||||||
}); err != nil && !git.IsErrCanceledOrKilled(err) {
|
|
||||||
log.Error("error during GetDiff(git diff dir: %s): %v, stderr: %s", repoPath, err, stderr.String())
|
log.Error("error during GetDiff(git diff dir: %s): %v, stderr: %s", repoPath, err, stderr.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -489,7 +489,7 @@ func (g *RepositoryDumper) handlePullRequest(ctx context.Context, pr *base.PullR
|
|||||||
if pr.Head.CloneURL == "" || pr.Head.Ref == "" {
|
if pr.Head.CloneURL == "" || pr.Head.Ref == "" {
|
||||||
// Set head information if pr.Head.SHA is available
|
// Set head information if pr.Head.SHA is available
|
||||||
if pr.Head.SHA != "" {
|
if pr.Head.SHA != "" {
|
||||||
_, _, err = gitcmd.NewCommand("update-ref", "--no-deref").AddDynamicArguments(pr.GetGitHeadRefName(), pr.Head.SHA).RunStdString(ctx, &gitcmd.RunOpts{Dir: g.gitPath()})
|
_, _, err = gitcmd.NewCommand("update-ref", "--no-deref").AddDynamicArguments(pr.GetGitHeadRefName(), pr.Head.SHA).WithDir(g.gitPath()).RunStdString(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("PR #%d in %s/%s unable to update-ref for pr HEAD: %v", pr.Number, g.repoOwner, g.repoName, err)
|
log.Error("PR #%d in %s/%s unable to update-ref for pr HEAD: %v", pr.Number, g.repoOwner, g.repoName, err)
|
||||||
}
|
}
|
||||||
@@ -519,7 +519,7 @@ func (g *RepositoryDumper) handlePullRequest(ctx context.Context, pr *base.PullR
|
|||||||
if !ok {
|
if !ok {
|
||||||
// Set head information if pr.Head.SHA is available
|
// Set head information if pr.Head.SHA is available
|
||||||
if pr.Head.SHA != "" {
|
if pr.Head.SHA != "" {
|
||||||
_, _, err = gitcmd.NewCommand("update-ref", "--no-deref").AddDynamicArguments(pr.GetGitHeadRefName(), pr.Head.SHA).RunStdString(ctx, &gitcmd.RunOpts{Dir: g.gitPath()})
|
_, _, err = gitcmd.NewCommand("update-ref", "--no-deref").AddDynamicArguments(pr.GetGitHeadRefName(), pr.Head.SHA).WithDir(g.gitPath()).RunStdString(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("PR #%d in %s/%s unable to update-ref for pr HEAD: %v", pr.Number, g.repoOwner, g.repoName, err)
|
log.Error("PR #%d in %s/%s unable to update-ref for pr HEAD: %v", pr.Number, g.repoOwner, g.repoName, err)
|
||||||
}
|
}
|
||||||
@@ -554,7 +554,7 @@ func (g *RepositoryDumper) handlePullRequest(ctx context.Context, pr *base.PullR
|
|||||||
fetchArg = git.BranchPrefix + fetchArg
|
fetchArg = git.BranchPrefix + fetchArg
|
||||||
}
|
}
|
||||||
|
|
||||||
_, _, err = gitcmd.NewCommand("fetch", "--no-tags").AddDashesAndList(remote, fetchArg).RunStdString(ctx, &gitcmd.RunOpts{Dir: g.gitPath()})
|
_, _, err = gitcmd.NewCommand("fetch", "--no-tags").AddDashesAndList(remote, fetchArg).WithDir(g.gitPath()).RunStdString(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Fetch branch from %s failed: %v", pr.Head.CloneURL, err)
|
log.Error("Fetch branch from %s failed: %v", pr.Head.CloneURL, err)
|
||||||
// We need to continue here so that the Head.Ref is reset and we attempt to set the gitref for the PR
|
// We need to continue here so that the Head.Ref is reset and we attempt to set the gitref for the PR
|
||||||
@@ -578,7 +578,7 @@ func (g *RepositoryDumper) handlePullRequest(ctx context.Context, pr *base.PullR
|
|||||||
pr.Head.SHA = headSha
|
pr.Head.SHA = headSha
|
||||||
}
|
}
|
||||||
if pr.Head.SHA != "" {
|
if pr.Head.SHA != "" {
|
||||||
_, _, err = gitcmd.NewCommand("update-ref", "--no-deref").AddDynamicArguments(pr.GetGitHeadRefName(), pr.Head.SHA).RunStdString(ctx, &gitcmd.RunOpts{Dir: g.gitPath()})
|
_, _, err = gitcmd.NewCommand("update-ref", "--no-deref").AddDynamicArguments(pr.GetGitHeadRefName(), pr.Head.SHA).WithDir(g.gitPath()).RunStdString(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("unable to set %s as the local head for PR #%d from %s in %s/%s. Error: %v", pr.Head.SHA, pr.Number, pr.Head.Ref, g.repoOwner, g.repoName, err)
|
log.Error("unable to set %s as the local head for PR #%d from %s in %s/%s. Error: %v", pr.Head.SHA, pr.Number, pr.Head.Ref, g.repoOwner, g.repoName, err)
|
||||||
}
|
}
|
||||||
|
@@ -663,7 +663,7 @@ func (g *GiteaLocalUploader) updateGitForPullRequest(ctx context.Context, pr *ba
|
|||||||
fetchArg = git.BranchPrefix + fetchArg
|
fetchArg = git.BranchPrefix + fetchArg
|
||||||
}
|
}
|
||||||
|
|
||||||
_, _, err = gitcmd.NewCommand("fetch", "--no-tags").AddDashesAndList(remote, fetchArg).RunStdString(ctx, &gitcmd.RunOpts{Dir: g.repo.RepoPath()})
|
_, err = gitrepo.RunCmdString(ctx, g.repo, gitcmd.NewCommand("fetch", "--no-tags").AddDashesAndList(remote, fetchArg))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Fetch branch from %s failed: %v", pr.Head.CloneURL, err)
|
log.Error("Fetch branch from %s failed: %v", pr.Head.CloneURL, err)
|
||||||
return head, nil
|
return head, nil
|
||||||
@@ -698,7 +698,7 @@ func (g *GiteaLocalUploader) updateGitForPullRequest(ctx context.Context, pr *ba
|
|||||||
// The SHA is empty
|
// The SHA is empty
|
||||||
log.Warn("Empty reference, no pull head for PR #%d in %s/%s", pr.Number, g.repoOwner, g.repoName)
|
log.Warn("Empty reference, no pull head for PR #%d in %s/%s", pr.Number, g.repoOwner, g.repoName)
|
||||||
} else {
|
} else {
|
||||||
_, _, err = gitcmd.NewCommand("rev-list", "--quiet", "-1").AddDynamicArguments(pr.Head.SHA).RunStdString(ctx, &gitcmd.RunOpts{Dir: g.repo.RepoPath()})
|
_, err = gitrepo.RunCmdString(ctx, g.repo, gitcmd.NewCommand("rev-list", "--quiet", "-1").AddDynamicArguments(pr.Head.SHA))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// Git update-ref remove bad references with a relative path
|
// Git update-ref remove bad references with a relative path
|
||||||
log.Warn("Deprecated local head %s for PR #%d in %s/%s, removing %s", pr.Head.SHA, pr.Number, g.repoOwner, g.repoName, pr.GetGitHeadRefName())
|
log.Warn("Deprecated local head %s for PR #%d in %s/%s, removing %s", pr.Head.SHA, pr.Number, g.repoOwner, g.repoName, pr.GetGitHeadRefName())
|
||||||
|
@@ -239,7 +239,7 @@ func TestGiteaUploadUpdateGitForPullRequest(t *testing.T) {
|
|||||||
baseRef := "master"
|
baseRef := "master"
|
||||||
// this is very different from the real situation. It should be a bare repository for all the Gitea managed repositories
|
// this is very different from the real situation. It should be a bare repository for all the Gitea managed repositories
|
||||||
assert.NoError(t, git.InitRepository(t.Context(), fromRepo.RepoPath(), false, fromRepo.ObjectFormatName))
|
assert.NoError(t, git.InitRepository(t.Context(), fromRepo.RepoPath(), false, fromRepo.ObjectFormatName))
|
||||||
err := gitcmd.NewCommand("symbolic-ref").AddDynamicArguments("HEAD", git.BranchPrefix+baseRef).Run(t.Context(), &gitcmd.RunOpts{Dir: fromRepo.RepoPath()})
|
err := gitrepo.RunCmd(t.Context(), fromRepo, gitcmd.NewCommand("symbolic-ref").AddDynamicArguments("HEAD", git.BranchPrefix+baseRef))
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.NoError(t, os.WriteFile(filepath.Join(fromRepo.RepoPath(), "README.md"), []byte("# Testing Repository\n\nOriginally created in: "+fromRepo.RepoPath()), 0o644))
|
assert.NoError(t, os.WriteFile(filepath.Join(fromRepo.RepoPath(), "README.md"), []byte("# Testing Repository\n\nOriginally created in: "+fromRepo.RepoPath()), 0o644))
|
||||||
assert.NoError(t, git.AddChanges(t.Context(), fromRepo.RepoPath(), true))
|
assert.NoError(t, git.AddChanges(t.Context(), fromRepo.RepoPath(), true))
|
||||||
@@ -263,7 +263,7 @@ func TestGiteaUploadUpdateGitForPullRequest(t *testing.T) {
|
|||||||
// fromRepo branch1
|
// fromRepo branch1
|
||||||
//
|
//
|
||||||
headRef := "branch1"
|
headRef := "branch1"
|
||||||
_, _, err = gitcmd.NewCommand("checkout", "-b").AddDynamicArguments(headRef).RunStdString(t.Context(), &gitcmd.RunOpts{Dir: fromRepo.RepoPath()})
|
_, err = gitrepo.RunCmdString(t.Context(), fromRepo, gitcmd.NewCommand("checkout", "-b").AddDynamicArguments(headRef))
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.NoError(t, os.WriteFile(filepath.Join(fromRepo.RepoPath(), "README.md"), []byte("SOMETHING"), 0o644))
|
assert.NoError(t, os.WriteFile(filepath.Join(fromRepo.RepoPath(), "README.md"), []byte("SOMETHING"), 0o644))
|
||||||
assert.NoError(t, git.AddChanges(t.Context(), fromRepo.RepoPath(), true))
|
assert.NoError(t, git.AddChanges(t.Context(), fromRepo.RepoPath(), true))
|
||||||
@@ -287,7 +287,7 @@ func TestGiteaUploadUpdateGitForPullRequest(t *testing.T) {
|
|||||||
assert.NoError(t, git.Clone(t.Context(), fromRepo.RepoPath(), forkRepo.RepoPath(), git.CloneRepoOptions{
|
assert.NoError(t, git.Clone(t.Context(), fromRepo.RepoPath(), forkRepo.RepoPath(), git.CloneRepoOptions{
|
||||||
Branch: headRef,
|
Branch: headRef,
|
||||||
}))
|
}))
|
||||||
_, _, err = gitcmd.NewCommand("checkout", "-b").AddDynamicArguments(forkHeadRef).RunStdString(t.Context(), &gitcmd.RunOpts{Dir: forkRepo.RepoPath()})
|
_, err = gitrepo.RunCmdString(t.Context(), forkRepo, gitcmd.NewCommand("checkout", "-b").AddDynamicArguments(forkHeadRef))
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.NoError(t, os.WriteFile(filepath.Join(forkRepo.RepoPath(), "README.md"), []byte("# branch2 "+forkRepo.RepoPath()), 0o644))
|
assert.NoError(t, os.WriteFile(filepath.Join(forkRepo.RepoPath(), "README.md"), []byte("# branch2 "+forkRepo.RepoPath()), 0o644))
|
||||||
assert.NoError(t, git.AddChanges(t.Context(), forkRepo.RepoPath(), true))
|
assert.NoError(t, git.AddChanges(t.Context(), forkRepo.RepoPath(), true))
|
||||||
|
@@ -272,13 +272,10 @@ func runSync(ctx context.Context, m *repo_model.Mirror) ([]*mirrorSyncResult, bo
|
|||||||
|
|
||||||
stdoutBuilder := strings.Builder{}
|
stdoutBuilder := strings.Builder{}
|
||||||
stderrBuilder := strings.Builder{}
|
stderrBuilder := strings.Builder{}
|
||||||
if err := cmd.Run(ctx, &gitcmd.RunOpts{
|
if err := gitrepo.RunCmd(ctx, m.Repo, cmd.WithTimeout(timeout).
|
||||||
Timeout: timeout,
|
WithEnv(envs).
|
||||||
Dir: repoPath,
|
WithStdout(&stdoutBuilder).
|
||||||
Env: envs,
|
WithStderr(&stderrBuilder)); err != nil {
|
||||||
Stdout: &stdoutBuilder,
|
|
||||||
Stderr: &stderrBuilder,
|
|
||||||
}); err != nil {
|
|
||||||
stdout := stdoutBuilder.String()
|
stdout := stdoutBuilder.String()
|
||||||
stderr := stderrBuilder.String()
|
stderr := stderrBuilder.String()
|
||||||
|
|
||||||
@@ -297,12 +294,9 @@ func runSync(ctx context.Context, m *repo_model.Mirror) ([]*mirrorSyncResult, bo
|
|||||||
// Successful prune - reattempt mirror
|
// Successful prune - reattempt mirror
|
||||||
stderrBuilder.Reset()
|
stderrBuilder.Reset()
|
||||||
stdoutBuilder.Reset()
|
stdoutBuilder.Reset()
|
||||||
if err = cmd.Run(ctx, &gitcmd.RunOpts{
|
if err = gitrepo.RunCmd(ctx, m.Repo, cmd.WithTimeout(timeout).
|
||||||
Timeout: timeout,
|
WithStdout(&stdoutBuilder).
|
||||||
Dir: repoPath,
|
WithStderr(&stderrBuilder)); err != nil {
|
||||||
Stdout: &stdoutBuilder,
|
|
||||||
Stderr: &stderrBuilder,
|
|
||||||
}); err != nil {
|
|
||||||
stdout := stdoutBuilder.String()
|
stdout := stdoutBuilder.String()
|
||||||
stderr := stderrBuilder.String()
|
stderr := stderrBuilder.String()
|
||||||
|
|
||||||
@@ -640,7 +634,7 @@ func checkAndUpdateEmptyRepository(ctx context.Context, m *repo_model.Mirror, re
|
|||||||
// Update the is empty and default_branch columns
|
// Update the is empty and default_branch columns
|
||||||
if err := repo_model.UpdateRepositoryColsWithAutoTime(ctx, m.Repo, "default_branch", "is_empty"); err != nil {
|
if err := repo_model.UpdateRepositoryColsWithAutoTime(ctx, m.Repo, "default_branch", "is_empty"); err != nil {
|
||||||
log.Error("Failed to update default branch of repository %-v. Error: %v", m.Repo, err)
|
log.Error("Failed to update default branch of repository %-v. Error: %v", m.Repo, err)
|
||||||
desc := fmt.Sprintf("Failed to update default branch of repository '%s': %v", m.Repo.RepoPath(), err)
|
desc := fmt.Sprintf("Failed to update default branch of repository '%s': %v", m.Repo.RelativePath(), err)
|
||||||
if err = system_model.CreateRepositoryNotice(desc); err != nil {
|
if err = system_model.CreateRepositoryNotice(desc); err != nil {
|
||||||
log.Error("CreateRepositoryNotice: %v", err)
|
log.Error("CreateRepositoryNotice: %v", err)
|
||||||
}
|
}
|
||||||
|
@@ -281,9 +281,9 @@ func getMergeCommit(ctx context.Context, pr *issues_model.PullRequest) (*git.Com
|
|||||||
prHeadRef := pr.GetGitHeadRefName()
|
prHeadRef := pr.GetGitHeadRefName()
|
||||||
|
|
||||||
// Check if the pull request is merged into BaseBranch
|
// Check if the pull request is merged into BaseBranch
|
||||||
if _, _, err := gitcmd.NewCommand("merge-base", "--is-ancestor").
|
if _, err := gitrepo.RunCmdString(ctx, pr.BaseRepo,
|
||||||
AddDynamicArguments(prHeadRef, pr.BaseBranch).
|
gitcmd.NewCommand("merge-base", "--is-ancestor").
|
||||||
RunStdString(ctx, &gitcmd.RunOpts{Dir: pr.BaseRepo.RepoPath()}); err != nil {
|
AddDynamicArguments(prHeadRef, pr.BaseBranch)); err != nil {
|
||||||
if strings.Contains(err.Error(), "exit status 1") {
|
if strings.Contains(err.Error(), "exit status 1") {
|
||||||
// prHeadRef is not an ancestor of the base branch
|
// prHeadRef is not an ancestor of the base branch
|
||||||
return nil, nil
|
return nil, nil
|
||||||
@@ -309,9 +309,9 @@ func getMergeCommit(ctx context.Context, pr *issues_model.PullRequest) (*git.Com
|
|||||||
objectFormat := git.ObjectFormatFromName(pr.BaseRepo.ObjectFormatName)
|
objectFormat := git.ObjectFormatFromName(pr.BaseRepo.ObjectFormatName)
|
||||||
|
|
||||||
// Get the commit from BaseBranch where the pull request got merged
|
// Get the commit from BaseBranch where the pull request got merged
|
||||||
mergeCommit, _, err := gitcmd.NewCommand("rev-list", "--ancestry-path", "--merges", "--reverse").
|
mergeCommit, err := gitrepo.RunCmdString(ctx, pr.BaseRepo,
|
||||||
AddDynamicArguments(prHeadCommitID+".."+pr.BaseBranch).
|
gitcmd.NewCommand("rev-list", "--ancestry-path", "--merges", "--reverse").
|
||||||
RunStdString(ctx, &gitcmd.RunOpts{Dir: pr.BaseRepo.RepoPath()})
|
AddDynamicArguments(prHeadCommitID+".."+pr.BaseBranch))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("git rev-list --ancestry-path --merges --reverse: %w", err)
|
return nil, fmt.Errorf("git rev-list --ancestry-path --merges --reverse: %w", err)
|
||||||
} else if len(mergeCommit) < objectFormat.FullLength() {
|
} else if len(mergeCommit) < objectFormat.FullLength() {
|
||||||
|
@@ -406,7 +406,7 @@ func doMergeAndPush(ctx context.Context, pr *issues_model.PullRequest, doer *use
|
|||||||
// Push back to upstream.
|
// Push back to upstream.
|
||||||
// This cause an api call to "/api/internal/hook/post-receive/...",
|
// This cause an api call to "/api/internal/hook/post-receive/...",
|
||||||
// If it's merge, all db transaction and operations should be there but not here to prevent deadlock.
|
// If it's merge, all db transaction and operations should be there but not here to prevent deadlock.
|
||||||
if err := pushCmd.Run(ctx, mergeCtx.RunOpts()); err != nil {
|
if err := mergeCtx.PrepareGitCmd(pushCmd).Run(ctx); err != nil {
|
||||||
if strings.Contains(mergeCtx.errbuf.String(), "non-fast-forward") {
|
if strings.Contains(mergeCtx.errbuf.String(), "non-fast-forward") {
|
||||||
return "", &git.ErrPushOutOfDate{
|
return "", &git.ErrPushOutOfDate{
|
||||||
StdOut: mergeCtx.outbuf.String(),
|
StdOut: mergeCtx.outbuf.String(),
|
||||||
@@ -440,7 +440,7 @@ func commitAndSignNoAuthor(ctx *mergeContext, message string) error {
|
|||||||
}
|
}
|
||||||
cmdCommit.AddOptionFormat("-S%s", ctx.signKey.KeyID)
|
cmdCommit.AddOptionFormat("-S%s", ctx.signKey.KeyID)
|
||||||
}
|
}
|
||||||
if err := cmdCommit.Run(ctx, ctx.RunOpts()); err != nil {
|
if err := ctx.PrepareGitCmd(cmdCommit).Run(ctx); err != nil {
|
||||||
log.Error("git commit %-v: %v\n%s\n%s", ctx.pr, err, ctx.outbuf.String(), ctx.errbuf.String())
|
log.Error("git commit %-v: %v\n%s\n%s", ctx.pr, err, ctx.outbuf.String(), ctx.errbuf.String())
|
||||||
return fmt.Errorf("git commit %v: %w\n%s\n%s", ctx.pr, err, ctx.outbuf.String(), ctx.errbuf.String())
|
return fmt.Errorf("git commit %v: %w\n%s\n%s", ctx.pr, err, ctx.outbuf.String(), ctx.errbuf.String())
|
||||||
}
|
}
|
||||||
@@ -501,7 +501,7 @@ func (err ErrMergeDivergingFastForwardOnly) Error() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func runMergeCommand(ctx *mergeContext, mergeStyle repo_model.MergeStyle, cmd *gitcmd.Command) error {
|
func runMergeCommand(ctx *mergeContext, mergeStyle repo_model.MergeStyle, cmd *gitcmd.Command) error {
|
||||||
if err := cmd.Run(ctx, ctx.RunOpts()); err != nil {
|
if err := ctx.PrepareGitCmd(cmd).Run(ctx); err != nil {
|
||||||
// Merge will leave a MERGE_HEAD file in the .git folder if there is a conflict
|
// Merge will leave a MERGE_HEAD file in the .git folder if there is a conflict
|
||||||
if _, statErr := os.Stat(filepath.Join(ctx.tmpBasePath, ".git", "MERGE_HEAD")); statErr == nil {
|
if _, statErr := os.Stat(filepath.Join(ctx.tmpBasePath, ".git", "MERGE_HEAD")); statErr == nil {
|
||||||
// We have a merge conflict error
|
// We have a merge conflict error
|
||||||
|
@@ -32,15 +32,14 @@ type mergeContext struct {
|
|||||||
env []string
|
env []string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ctx *mergeContext) RunOpts() *gitcmd.RunOpts {
|
func (ctx *mergeContext) PrepareGitCmd(cmd *gitcmd.Command) *gitcmd.Command {
|
||||||
ctx.outbuf.Reset()
|
ctx.outbuf.Reset()
|
||||||
ctx.errbuf.Reset()
|
ctx.errbuf.Reset()
|
||||||
return &gitcmd.RunOpts{
|
return cmd.WithEnv(ctx.env).
|
||||||
Env: ctx.env,
|
WithDir(ctx.tmpBasePath).
|
||||||
Dir: ctx.tmpBasePath,
|
WithParentCallerInfo().
|
||||||
Stdout: ctx.outbuf,
|
WithStdout(ctx.outbuf).
|
||||||
Stderr: ctx.errbuf,
|
WithStderr(ctx.errbuf)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ErrSHADoesNotMatch represents a "SHADoesNotMatch" kind of error.
|
// ErrSHADoesNotMatch represents a "SHADoesNotMatch" kind of error.
|
||||||
@@ -74,7 +73,7 @@ func createTemporaryRepoForMerge(ctx context.Context, pr *issues_model.PullReque
|
|||||||
}
|
}
|
||||||
|
|
||||||
if expectedHeadCommitID != "" {
|
if expectedHeadCommitID != "" {
|
||||||
trackingCommitID, _, err := gitcmd.NewCommand("show-ref", "--hash").AddDynamicArguments(git.BranchPrefix+trackingBranch).RunStdString(ctx, &gitcmd.RunOpts{Dir: mergeCtx.tmpBasePath})
|
trackingCommitID, _, err := mergeCtx.PrepareGitCmd(gitcmd.NewCommand("show-ref", "--hash").AddDynamicArguments(git.BranchPrefix + trackingBranch)).RunStdString(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
defer cancel()
|
defer cancel()
|
||||||
log.Error("failed to get sha of head branch in %-v: show-ref[%s] --hash refs/heads/tracking: %v", mergeCtx.pr, mergeCtx.tmpBasePath, err)
|
log.Error("failed to get sha of head branch in %-v: show-ref[%s] --hash refs/heads/tracking: %v", mergeCtx.pr, mergeCtx.tmpBasePath, err)
|
||||||
@@ -152,8 +151,8 @@ func prepareTemporaryRepoForMerge(ctx *mergeContext) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
setConfig := func(key, value string) error {
|
setConfig := func(key, value string) error {
|
||||||
if err := gitcmd.NewCommand("config", "--local").AddDynamicArguments(key, value).
|
if err := ctx.PrepareGitCmd(gitcmd.NewCommand("config", "--local").AddDynamicArguments(key, value)).
|
||||||
Run(ctx, ctx.RunOpts()); err != nil {
|
Run(ctx); err != nil {
|
||||||
log.Error("git config [%s -> %q]: %v\n%s\n%s", key, value, err, ctx.outbuf.String(), ctx.errbuf.String())
|
log.Error("git config [%s -> %q]: %v\n%s\n%s", key, value, err, ctx.outbuf.String(), ctx.errbuf.String())
|
||||||
return fmt.Errorf("git config [%s -> %q]: %w\n%s\n%s", key, value, err, ctx.outbuf.String(), ctx.errbuf.String())
|
return fmt.Errorf("git config [%s -> %q]: %w\n%s\n%s", key, value, err, ctx.outbuf.String(), ctx.errbuf.String())
|
||||||
}
|
}
|
||||||
@@ -185,8 +184,8 @@ func prepareTemporaryRepoForMerge(ctx *mergeContext) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Read base branch index
|
// Read base branch index
|
||||||
if err := gitcmd.NewCommand("read-tree", "HEAD").
|
if err := ctx.PrepareGitCmd(gitcmd.NewCommand("read-tree", "HEAD")).
|
||||||
Run(ctx, ctx.RunOpts()); err != nil {
|
Run(ctx); err != nil {
|
||||||
log.Error("git read-tree HEAD: %v\n%s\n%s", err, ctx.outbuf.String(), ctx.errbuf.String())
|
log.Error("git read-tree HEAD: %v\n%s\n%s", err, ctx.outbuf.String(), ctx.errbuf.String())
|
||||||
return fmt.Errorf("Unable to read base branch in to the index: %w\n%s\n%s", err, ctx.outbuf.String(), ctx.errbuf.String())
|
return fmt.Errorf("Unable to read base branch in to the index: %w\n%s\n%s", err, ctx.outbuf.String(), ctx.errbuf.String())
|
||||||
}
|
}
|
||||||
@@ -222,31 +221,31 @@ func getDiffTree(ctx context.Context, repoPath, baseBranch, headBranch string, o
|
|||||||
return 0, nil, nil
|
return 0, nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
err = gitcmd.NewCommand("diff-tree", "--no-commit-id", "--name-only", "-r", "-r", "-z", "--root").AddDynamicArguments(baseBranch, headBranch).
|
err = gitcmd.NewCommand("diff-tree", "--no-commit-id", "--name-only", "-r", "-r", "-z", "--root").
|
||||||
Run(ctx, &gitcmd.RunOpts{
|
AddDynamicArguments(baseBranch, headBranch).
|
||||||
Dir: repoPath,
|
WithDir(repoPath).
|
||||||
Stdout: diffOutWriter,
|
WithStdout(diffOutWriter).
|
||||||
PipelineFunc: func(ctx context.Context, cancel context.CancelFunc) error {
|
WithPipelineFunc(func(ctx context.Context, cancel context.CancelFunc) error {
|
||||||
// Close the writer end of the pipe to begin processing
|
// Close the writer end of the pipe to begin processing
|
||||||
_ = diffOutWriter.Close()
|
_ = diffOutWriter.Close()
|
||||||
defer func() {
|
defer func() {
|
||||||
// Close the reader on return to terminate the git command if necessary
|
// Close the reader on return to terminate the git command if necessary
|
||||||
_ = diffOutReader.Close()
|
_ = diffOutReader.Close()
|
||||||
}()
|
}()
|
||||||
|
|
||||||
// Now scan the output from the command
|
// Now scan the output from the command
|
||||||
scanner := bufio.NewScanner(diffOutReader)
|
scanner := bufio.NewScanner(diffOutReader)
|
||||||
scanner.Split(scanNullTerminatedStrings)
|
scanner.Split(scanNullTerminatedStrings)
|
||||||
for scanner.Scan() {
|
for scanner.Scan() {
|
||||||
filepath := scanner.Text()
|
filepath := scanner.Text()
|
||||||
// escape '*', '?', '[', spaces and '!' prefix
|
// escape '*', '?', '[', spaces and '!' prefix
|
||||||
filepath = escapedSymbols.ReplaceAllString(filepath, `\$1`)
|
filepath = escapedSymbols.ReplaceAllString(filepath, `\$1`)
|
||||||
// no necessary to escape the first '#' symbol because the first symbol is '/'
|
// no necessary to escape the first '#' symbol because the first symbol is '/'
|
||||||
fmt.Fprintf(out, "/%s\n", filepath)
|
fmt.Fprintf(out, "/%s\n", filepath)
|
||||||
}
|
}
|
||||||
return scanner.Err()
|
return scanner.Err()
|
||||||
},
|
}).
|
||||||
})
|
Run(ctx)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -273,16 +272,16 @@ func (err ErrRebaseConflicts) Error() string {
|
|||||||
// if there is a conflict it will return an ErrRebaseConflicts
|
// if there is a conflict it will return an ErrRebaseConflicts
|
||||||
func rebaseTrackingOnToBase(ctx *mergeContext, mergeStyle repo_model.MergeStyle) error {
|
func rebaseTrackingOnToBase(ctx *mergeContext, mergeStyle repo_model.MergeStyle) error {
|
||||||
// Checkout head branch
|
// Checkout head branch
|
||||||
if err := gitcmd.NewCommand("checkout", "-b").AddDynamicArguments(stagingBranch, trackingBranch).
|
if err := ctx.PrepareGitCmd(gitcmd.NewCommand("checkout", "-b").AddDynamicArguments(stagingBranch, trackingBranch)).
|
||||||
Run(ctx, ctx.RunOpts()); err != nil {
|
Run(ctx); err != nil {
|
||||||
return fmt.Errorf("unable to git checkout tracking as staging in temp repo for %v: %w\n%s\n%s", ctx.pr, err, ctx.outbuf.String(), ctx.errbuf.String())
|
return fmt.Errorf("unable to git checkout tracking as staging in temp repo for %v: %w\n%s\n%s", ctx.pr, err, ctx.outbuf.String(), ctx.errbuf.String())
|
||||||
}
|
}
|
||||||
ctx.outbuf.Reset()
|
ctx.outbuf.Reset()
|
||||||
ctx.errbuf.Reset()
|
ctx.errbuf.Reset()
|
||||||
|
|
||||||
// Rebase before merging
|
// Rebase before merging
|
||||||
if err := gitcmd.NewCommand("rebase").AddDynamicArguments(baseBranch).
|
if err := ctx.PrepareGitCmd(gitcmd.NewCommand("rebase").AddDynamicArguments(baseBranch)).
|
||||||
Run(ctx, ctx.RunOpts()); err != nil {
|
Run(ctx); err != nil {
|
||||||
// Rebase will leave a REBASE_HEAD file in .git if there is a conflict
|
// Rebase will leave a REBASE_HEAD file in .git if there is a conflict
|
||||||
if _, statErr := os.Stat(filepath.Join(ctx.tmpBasePath, ".git", "REBASE_HEAD")); statErr == nil {
|
if _, statErr := os.Stat(filepath.Join(ctx.tmpBasePath, ".git", "REBASE_HEAD")); statErr == nil {
|
||||||
var commitSha string
|
var commitSha string
|
||||||
|
@@ -17,7 +17,7 @@ import (
|
|||||||
// getRebaseAmendMessage composes the message to amend commits in rebase merge of a pull request.
|
// getRebaseAmendMessage composes the message to amend commits in rebase merge of a pull request.
|
||||||
func getRebaseAmendMessage(ctx *mergeContext, baseGitRepo *git.Repository) (message string, err error) {
|
func getRebaseAmendMessage(ctx *mergeContext, baseGitRepo *git.Repository) (message string, err error) {
|
||||||
// Get existing commit message.
|
// Get existing commit message.
|
||||||
commitMessage, _, err := gitcmd.NewCommand("show", "--format=%B", "-s").RunStdString(ctx, &gitcmd.RunOpts{Dir: ctx.tmpBasePath})
|
commitMessage, _, err := gitcmd.NewCommand("show", "--format=%B", "-s").WithDir(ctx.tmpBasePath).RunStdString(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
@@ -74,7 +74,10 @@ func doMergeRebaseFastForward(ctx *mergeContext) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if newMessage != "" {
|
if newMessage != "" {
|
||||||
if err := gitcmd.NewCommand("commit", "--amend").AddOptionFormat("--message=%s", newMessage).Run(ctx, &gitcmd.RunOpts{Dir: ctx.tmpBasePath}); err != nil {
|
if err := gitcmd.NewCommand("commit", "--amend").
|
||||||
|
AddOptionFormat("--message=%s", newMessage).
|
||||||
|
WithDir(ctx.tmpBasePath).
|
||||||
|
Run(ctx); err != nil {
|
||||||
log.Error("Unable to amend commit message: %v", err)
|
log.Error("Unable to amend commit message: %v", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -106,8 +109,8 @@ func doMergeStyleRebase(ctx *mergeContext, mergeStyle repo_model.MergeStyle, mes
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Checkout base branch again
|
// Checkout base branch again
|
||||||
if err := gitcmd.NewCommand("checkout").AddDynamicArguments(baseBranch).
|
if err := ctx.PrepareGitCmd(gitcmd.NewCommand("checkout").AddDynamicArguments(baseBranch)).
|
||||||
Run(ctx, ctx.RunOpts()); err != nil {
|
Run(ctx); err != nil {
|
||||||
log.Error("git checkout base prior to merge post staging rebase %-v: %v\n%s\n%s", ctx.pr, err, ctx.outbuf.String(), ctx.errbuf.String())
|
log.Error("git checkout base prior to merge post staging rebase %-v: %v\n%s\n%s", ctx.pr, err, ctx.outbuf.String(), ctx.errbuf.String())
|
||||||
return fmt.Errorf("git checkout base prior to merge post staging rebase %v: %w\n%s\n%s", ctx.pr, err, ctx.outbuf.String(), ctx.errbuf.String())
|
return fmt.Errorf("git checkout base prior to merge post staging rebase %v: %w\n%s\n%s", ctx.pr, err, ctx.outbuf.String(), ctx.errbuf.String())
|
||||||
}
|
}
|
||||||
|
@@ -80,7 +80,7 @@ func doMergeStyleSquash(ctx *mergeContext, message string) error {
|
|||||||
}
|
}
|
||||||
cmdCommit.AddOptionFormat("-S%s", ctx.signKey.KeyID)
|
cmdCommit.AddOptionFormat("-S%s", ctx.signKey.KeyID)
|
||||||
}
|
}
|
||||||
if err := cmdCommit.Run(ctx, ctx.RunOpts()); err != nil {
|
if err := ctx.PrepareGitCmd(cmdCommit).Run(ctx); err != nil {
|
||||||
log.Error("git commit %-v: %v\n%s\n%s", ctx.pr, err, ctx.outbuf.String(), ctx.errbuf.String())
|
log.Error("git commit %-v: %v\n%s\n%s", ctx.pr, err, ctx.outbuf.String(), ctx.errbuf.String())
|
||||||
return fmt.Errorf("git commit [%s:%s -> %s:%s]: %w\n%s\n%s", ctx.pr.HeadRepo.FullName(), ctx.pr.HeadBranch, ctx.pr.BaseRepo.FullName(), ctx.pr.BaseBranch, err, ctx.outbuf.String(), ctx.errbuf.String())
|
return fmt.Errorf("git commit [%s:%s -> %s:%s]: %w\n%s\n%s", ctx.pr.HeadRepo.FullName(), ctx.pr.HeadBranch, ctx.pr.BaseRepo.FullName(), ctx.pr.BaseBranch, err, ctx.outbuf.String(), ctx.errbuf.String())
|
||||||
}
|
}
|
||||||
|
@@ -91,7 +91,7 @@ func testPullRequestTmpRepoBranchMergeable(ctx context.Context, prCtx *prTmpRepo
|
|||||||
defer gitRepo.Close()
|
defer gitRepo.Close()
|
||||||
|
|
||||||
// 1. update merge base
|
// 1. update merge base
|
||||||
pr.MergeBase, _, err = gitcmd.NewCommand("merge-base", "--", "base", "tracking").RunStdString(ctx, &gitcmd.RunOpts{Dir: prCtx.tmpBasePath})
|
pr.MergeBase, _, err = gitcmd.NewCommand("merge-base", "--", "base", "tracking").WithDir(prCtx.tmpBasePath).RunStdString(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
var err2 error
|
var err2 error
|
||||||
pr.MergeBase, err2 = gitRepo.GetRefCommitID(git.BranchPrefix + "base")
|
pr.MergeBase, err2 = gitRepo.GetRefCommitID(git.BranchPrefix + "base")
|
||||||
@@ -191,7 +191,7 @@ func attemptMerge(ctx context.Context, file *unmergedFile, tmpBasePath string, f
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Need to get the objects from the object db to attempt to merge
|
// Need to get the objects from the object db to attempt to merge
|
||||||
root, _, err := gitcmd.NewCommand("unpack-file").AddDynamicArguments(file.stage1.sha).RunStdString(ctx, &gitcmd.RunOpts{Dir: tmpBasePath})
|
root, _, err := gitcmd.NewCommand("unpack-file").AddDynamicArguments(file.stage1.sha).WithDir(tmpBasePath).RunStdString(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to get root object: %s at path: %s for merging. Error: %w", file.stage1.sha, file.stage1.path, err)
|
return fmt.Errorf("unable to get root object: %s at path: %s for merging. Error: %w", file.stage1.sha, file.stage1.path, err)
|
||||||
}
|
}
|
||||||
@@ -200,7 +200,7 @@ func attemptMerge(ctx context.Context, file *unmergedFile, tmpBasePath string, f
|
|||||||
_ = util.Remove(filepath.Join(tmpBasePath, root))
|
_ = util.Remove(filepath.Join(tmpBasePath, root))
|
||||||
}()
|
}()
|
||||||
|
|
||||||
base, _, err := gitcmd.NewCommand("unpack-file").AddDynamicArguments(file.stage2.sha).RunStdString(ctx, &gitcmd.RunOpts{Dir: tmpBasePath})
|
base, _, err := gitcmd.NewCommand("unpack-file").AddDynamicArguments(file.stage2.sha).WithDir(tmpBasePath).RunStdString(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to get base object: %s at path: %s for merging. Error: %w", file.stage2.sha, file.stage2.path, err)
|
return fmt.Errorf("unable to get base object: %s at path: %s for merging. Error: %w", file.stage2.sha, file.stage2.path, err)
|
||||||
}
|
}
|
||||||
@@ -208,7 +208,7 @@ func attemptMerge(ctx context.Context, file *unmergedFile, tmpBasePath string, f
|
|||||||
defer func() {
|
defer func() {
|
||||||
_ = util.Remove(base)
|
_ = util.Remove(base)
|
||||||
}()
|
}()
|
||||||
head, _, err := gitcmd.NewCommand("unpack-file").AddDynamicArguments(file.stage3.sha).RunStdString(ctx, &gitcmd.RunOpts{Dir: tmpBasePath})
|
head, _, err := gitcmd.NewCommand("unpack-file").AddDynamicArguments(file.stage3.sha).WithDir(tmpBasePath).RunStdString(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to get head object:%s at path: %s for merging. Error: %w", file.stage3.sha, file.stage3.path, err)
|
return fmt.Errorf("unable to get head object:%s at path: %s for merging. Error: %w", file.stage3.sha, file.stage3.path, err)
|
||||||
}
|
}
|
||||||
@@ -218,13 +218,13 @@ func attemptMerge(ctx context.Context, file *unmergedFile, tmpBasePath string, f
|
|||||||
}()
|
}()
|
||||||
|
|
||||||
// now git merge-file annoyingly takes a different order to the merge-tree ...
|
// now git merge-file annoyingly takes a different order to the merge-tree ...
|
||||||
_, _, conflictErr := gitcmd.NewCommand("merge-file").AddDynamicArguments(base, root, head).RunStdString(ctx, &gitcmd.RunOpts{Dir: tmpBasePath})
|
_, _, conflictErr := gitcmd.NewCommand("merge-file").AddDynamicArguments(base, root, head).WithDir(tmpBasePath).RunStdString(ctx)
|
||||||
if conflictErr != nil {
|
if conflictErr != nil {
|
||||||
return &errMergeConflict{file.stage2.path}
|
return &errMergeConflict{file.stage2.path}
|
||||||
}
|
}
|
||||||
|
|
||||||
// base now contains the merged data
|
// base now contains the merged data
|
||||||
hash, _, err := gitcmd.NewCommand("hash-object", "-w", "--path").AddDynamicArguments(file.stage2.path, base).RunStdString(ctx, &gitcmd.RunOpts{Dir: tmpBasePath})
|
hash, _, err := gitcmd.NewCommand("hash-object", "-w", "--path").AddDynamicArguments(file.stage2.path, base).WithDir(tmpBasePath).RunStdString(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -249,7 +249,7 @@ func AttemptThreeWayMerge(ctx context.Context, gitPath string, gitRepo *git.Repo
|
|||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
// First we use read-tree to do a simple three-way merge
|
// First we use read-tree to do a simple three-way merge
|
||||||
if _, _, err := gitcmd.NewCommand("read-tree", "-m").AddDynamicArguments(base, ours, theirs).RunStdString(ctx, &gitcmd.RunOpts{Dir: gitPath}); err != nil {
|
if _, _, err := gitcmd.NewCommand("read-tree", "-m").AddDynamicArguments(base, ours, theirs).WithDir(gitPath).RunStdString(ctx); err != nil {
|
||||||
log.Error("Unable to run read-tree -m! Error: %v", err)
|
log.Error("Unable to run read-tree -m! Error: %v", err)
|
||||||
return false, nil, fmt.Errorf("unable to run read-tree -m! Error: %w", err)
|
return false, nil, fmt.Errorf("unable to run read-tree -m! Error: %w", err)
|
||||||
}
|
}
|
||||||
@@ -323,9 +323,9 @@ func checkConflicts(ctx context.Context, pr *issues_model.PullRequest, gitRepo *
|
|||||||
// No conflicts detected so we need to check if the patch is empty...
|
// No conflicts detected so we need to check if the patch is empty...
|
||||||
// a. Write the newly merged tree and check the new tree-hash
|
// a. Write the newly merged tree and check the new tree-hash
|
||||||
var treeHash string
|
var treeHash string
|
||||||
treeHash, _, err = gitcmd.NewCommand("write-tree").RunStdString(ctx, &gitcmd.RunOpts{Dir: tmpBasePath})
|
treeHash, _, err = gitcmd.NewCommand("write-tree").WithDir(tmpBasePath).RunStdString(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
lsfiles, _, _ := gitcmd.NewCommand("ls-files", "-u").RunStdString(ctx, &gitcmd.RunOpts{Dir: tmpBasePath})
|
lsfiles, _, _ := gitcmd.NewCommand("ls-files", "-u").WithDir(tmpBasePath).RunStdString(ctx)
|
||||||
return false, fmt.Errorf("unable to write unconflicted tree: %w\n`git ls-files -u`:\n%s", err, lsfiles)
|
return false, fmt.Errorf("unable to write unconflicted tree: %w\n`git ls-files -u`:\n%s", err, lsfiles)
|
||||||
}
|
}
|
||||||
treeHash = strings.TrimSpace(treeHash)
|
treeHash = strings.TrimSpace(treeHash)
|
||||||
@@ -382,7 +382,7 @@ func checkConflicts(ctx context.Context, pr *issues_model.PullRequest, gitRepo *
|
|||||||
log.Trace("PullRequest[%d].testPullRequestTmpRepoBranchMergeable (patchPath): %s", pr.ID, patchPath)
|
log.Trace("PullRequest[%d].testPullRequestTmpRepoBranchMergeable (patchPath): %s", pr.ID, patchPath)
|
||||||
|
|
||||||
// 4. Read the base branch in to the index of the temporary repository
|
// 4. Read the base branch in to the index of the temporary repository
|
||||||
_, _, err = gitcmd.NewCommand("read-tree", "base").RunStdString(gitRepo.Ctx, &gitcmd.RunOpts{Dir: tmpBasePath})
|
_, _, err = gitcmd.NewCommand("read-tree", "base").WithDir(tmpBasePath).RunStdString(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, fmt.Errorf("git read-tree %s: %w", pr.BaseBranch, err)
|
return false, fmt.Errorf("git read-tree %s: %w", pr.BaseBranch, err)
|
||||||
}
|
}
|
||||||
@@ -426,10 +426,10 @@ func checkConflicts(ctx context.Context, pr *issues_model.PullRequest, gitRepo *
|
|||||||
|
|
||||||
// 8. Run the check command
|
// 8. Run the check command
|
||||||
conflict = false
|
conflict = false
|
||||||
err = cmdApply.Run(gitRepo.Ctx, &gitcmd.RunOpts{
|
err = cmdApply.
|
||||||
Dir: tmpBasePath,
|
WithDir(tmpBasePath).
|
||||||
Stderr: stderrWriter,
|
WithStderr(stderrWriter).
|
||||||
PipelineFunc: func(ctx context.Context, cancel context.CancelFunc) error {
|
WithPipelineFunc(func(ctx context.Context, cancel context.CancelFunc) error {
|
||||||
// Close the writer end of the pipe to begin processing
|
// Close the writer end of the pipe to begin processing
|
||||||
_ = stderrWriter.Close()
|
_ = stderrWriter.Close()
|
||||||
defer func() {
|
defer func() {
|
||||||
@@ -488,8 +488,8 @@ func checkConflicts(ctx context.Context, pr *issues_model.PullRequest, gitRepo *
|
|||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
},
|
}).
|
||||||
})
|
Run(gitRepo.Ctx)
|
||||||
|
|
||||||
// 9. Check if the found conflictedfiles is non-zero, "err" could be non-nil, so we should ignore it if we found conflicts.
|
// 9. Check if the found conflictedfiles is non-zero, "err" could be non-nil, so we should ignore it if we found conflicts.
|
||||||
// Note: `"err" could be non-nil` is due that if enable 3-way merge, it doesn't return any error on found conflicts.
|
// Note: `"err" could be non-nil` is due that if enable 3-way merge, it doesn't return any error on found conflicts.
|
||||||
|
@@ -73,48 +73,47 @@ func readUnmergedLsFileLines(ctx context.Context, tmpBasePath string, outputChan
|
|||||||
|
|
||||||
stderr := &strings.Builder{}
|
stderr := &strings.Builder{}
|
||||||
err = gitcmd.NewCommand("ls-files", "-u", "-z").
|
err = gitcmd.NewCommand("ls-files", "-u", "-z").
|
||||||
Run(ctx, &gitcmd.RunOpts{
|
WithDir(tmpBasePath).
|
||||||
Dir: tmpBasePath,
|
WithStdout(lsFilesWriter).
|
||||||
Stdout: lsFilesWriter,
|
WithStderr(stderr).
|
||||||
Stderr: stderr,
|
WithPipelineFunc(func(_ context.Context, _ context.CancelFunc) error {
|
||||||
PipelineFunc: func(_ context.Context, _ context.CancelFunc) error {
|
_ = lsFilesWriter.Close()
|
||||||
_ = lsFilesWriter.Close()
|
defer func() {
|
||||||
defer func() {
|
_ = lsFilesReader.Close()
|
||||||
_ = lsFilesReader.Close()
|
}()
|
||||||
}()
|
bufferedReader := bufio.NewReader(lsFilesReader)
|
||||||
bufferedReader := bufio.NewReader(lsFilesReader)
|
|
||||||
|
|
||||||
for {
|
for {
|
||||||
line, err := bufferedReader.ReadString('\000')
|
line, err := bufferedReader.ReadString('\000')
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err == io.EOF {
|
if err == io.EOF {
|
||||||
return nil
|
return nil
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
toemit := &lsFileLine{}
|
return err
|
||||||
|
|
||||||
split := strings.SplitN(line, " ", 3)
|
|
||||||
if len(split) < 3 {
|
|
||||||
return fmt.Errorf("malformed line: %s", line)
|
|
||||||
}
|
|
||||||
toemit.mode = split[0]
|
|
||||||
toemit.sha = split[1]
|
|
||||||
|
|
||||||
if len(split[2]) < 4 {
|
|
||||||
return fmt.Errorf("malformed line: %s", line)
|
|
||||||
}
|
|
||||||
|
|
||||||
toemit.stage, err = strconv.Atoi(split[2][0:1])
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("malformed line: %s", line)
|
|
||||||
}
|
|
||||||
|
|
||||||
toemit.path = split[2][2 : len(split[2])-1]
|
|
||||||
outputChan <- toemit
|
|
||||||
}
|
}
|
||||||
},
|
toemit := &lsFileLine{}
|
||||||
})
|
|
||||||
|
split := strings.SplitN(line, " ", 3)
|
||||||
|
if len(split) < 3 {
|
||||||
|
return fmt.Errorf("malformed line: %s", line)
|
||||||
|
}
|
||||||
|
toemit.mode = split[0]
|
||||||
|
toemit.sha = split[1]
|
||||||
|
|
||||||
|
if len(split[2]) < 4 {
|
||||||
|
return fmt.Errorf("malformed line: %s", line)
|
||||||
|
}
|
||||||
|
|
||||||
|
toemit.stage, err = strconv.Atoi(split[2][0:1])
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("malformed line: %s", line)
|
||||||
|
}
|
||||||
|
|
||||||
|
toemit.path = split[2][2 : len(split[2])-1]
|
||||||
|
outputChan <- toemit
|
||||||
|
}
|
||||||
|
}).
|
||||||
|
Run(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
outputChan <- &lsFileLine{err: fmt.Errorf("git ls-files -u -z: %w", gitcmd.ConcatenateError(err, stderr.String()))}
|
outputChan <- &lsFileLine{err: fmt.Errorf("git ls-files -u -z: %w", gitcmd.ConcatenateError(err, stderr.String()))}
|
||||||
}
|
}
|
||||||
|
@@ -516,18 +516,17 @@ func checkIfPRContentChanged(ctx context.Context, pr *issues_model.PullRequest,
|
|||||||
}
|
}
|
||||||
|
|
||||||
stderr := new(bytes.Buffer)
|
stderr := new(bytes.Buffer)
|
||||||
if err := cmd.Run(ctx, &gitcmd.RunOpts{
|
if err := cmd.WithDir(prCtx.tmpBasePath).
|
||||||
Dir: prCtx.tmpBasePath,
|
WithStdout(stdoutWriter).
|
||||||
Stdout: stdoutWriter,
|
WithStderr(stderr).
|
||||||
Stderr: stderr,
|
WithPipelineFunc(func(ctx context.Context, cancel context.CancelFunc) error {
|
||||||
PipelineFunc: func(ctx context.Context, cancel context.CancelFunc) error {
|
|
||||||
_ = stdoutWriter.Close()
|
_ = stdoutWriter.Close()
|
||||||
defer func() {
|
defer func() {
|
||||||
_ = stdoutReader.Close()
|
_ = stdoutReader.Close()
|
||||||
}()
|
}()
|
||||||
return util.IsEmptyReader(stdoutReader)
|
return util.IsEmptyReader(stdoutReader)
|
||||||
},
|
}).
|
||||||
}); err != nil {
|
Run(ctx); err != nil {
|
||||||
if err == util.ErrNotEmpty {
|
if err == util.ErrNotEmpty {
|
||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
@@ -37,14 +37,12 @@ type prTmpRepoContext struct {
|
|||||||
errbuf *strings.Builder // any use should be preceded by a Reset and preferably after use
|
errbuf *strings.Builder // any use should be preceded by a Reset and preferably after use
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ctx *prTmpRepoContext) RunOpts() *gitcmd.RunOpts {
|
func (ctx *prTmpRepoContext) PrepareGitCmd(cmd *gitcmd.Command) *gitcmd.Command {
|
||||||
ctx.outbuf.Reset()
|
ctx.outbuf.Reset()
|
||||||
ctx.errbuf.Reset()
|
ctx.errbuf.Reset()
|
||||||
return &gitcmd.RunOpts{
|
return cmd.WithDir(ctx.tmpBasePath).
|
||||||
Dir: ctx.tmpBasePath,
|
WithStdout(ctx.outbuf).
|
||||||
Stdout: ctx.outbuf,
|
WithStderr(ctx.errbuf)
|
||||||
Stderr: ctx.errbuf,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// createTemporaryRepoForPR creates a temporary repo with "base" for pr.BaseBranch and "tracking" for pr.HeadBranch
|
// createTemporaryRepoForPR creates a temporary repo with "base" for pr.BaseBranch and "tracking" for pr.HeadBranch
|
||||||
@@ -132,22 +130,23 @@ func createTemporaryRepoForPR(ctx context.Context, pr *issues_model.PullRequest)
|
|||||||
return nil, nil, fmt.Errorf("Unable to add base repository to temporary repo [%s -> tmpBasePath]: %w", pr.BaseRepo.FullName(), err)
|
return nil, nil, fmt.Errorf("Unable to add base repository to temporary repo [%s -> tmpBasePath]: %w", pr.BaseRepo.FullName(), err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := gitcmd.NewCommand("remote", "add", "-t").AddDynamicArguments(pr.BaseBranch).AddArguments("-m").AddDynamicArguments(pr.BaseBranch).AddDynamicArguments("origin", baseRepoPath).
|
if err := prCtx.PrepareGitCmd(gitcmd.NewCommand("remote", "add", "-t").AddDynamicArguments(pr.BaseBranch).AddArguments("-m").AddDynamicArguments(pr.BaseBranch).AddDynamicArguments("origin", baseRepoPath)).
|
||||||
Run(ctx, prCtx.RunOpts()); err != nil {
|
Run(ctx); err != nil {
|
||||||
log.Error("%-v Unable to add base repository as origin [%s -> %s]: %v\n%s\n%s", pr, pr.BaseRepo.FullName(), tmpBasePath, err, prCtx.outbuf.String(), prCtx.errbuf.String())
|
log.Error("%-v Unable to add base repository as origin [%s -> %s]: %v\n%s\n%s", pr, pr.BaseRepo.FullName(), tmpBasePath, err, prCtx.outbuf.String(), prCtx.errbuf.String())
|
||||||
cancel()
|
cancel()
|
||||||
return nil, nil, fmt.Errorf("Unable to add base repository as origin [%s -> tmpBasePath]: %w\n%s\n%s", pr.BaseRepo.FullName(), err, prCtx.outbuf.String(), prCtx.errbuf.String())
|
return nil, nil, fmt.Errorf("Unable to add base repository as origin [%s -> tmpBasePath]: %w\n%s\n%s", pr.BaseRepo.FullName(), err, prCtx.outbuf.String(), prCtx.errbuf.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := gitcmd.NewCommand("fetch", "origin").AddArguments(fetchArgs...).AddDashesAndList(git.BranchPrefix+pr.BaseBranch+":"+git.BranchPrefix+baseBranch, git.BranchPrefix+pr.BaseBranch+":"+git.BranchPrefix+"original_"+baseBranch).
|
if err := prCtx.PrepareGitCmd(gitcmd.NewCommand("fetch", "origin").AddArguments(fetchArgs...).
|
||||||
Run(ctx, prCtx.RunOpts()); err != nil {
|
AddDashesAndList(git.BranchPrefix+pr.BaseBranch+":"+git.BranchPrefix+baseBranch, git.BranchPrefix+pr.BaseBranch+":"+git.BranchPrefix+"original_"+baseBranch)).
|
||||||
|
Run(ctx); err != nil {
|
||||||
log.Error("%-v Unable to fetch origin base branch [%s:%s -> base, original_base in %s]: %v:\n%s\n%s", pr, pr.BaseRepo.FullName(), pr.BaseBranch, tmpBasePath, err, prCtx.outbuf.String(), prCtx.errbuf.String())
|
log.Error("%-v Unable to fetch origin base branch [%s:%s -> base, original_base in %s]: %v:\n%s\n%s", pr, pr.BaseRepo.FullName(), pr.BaseBranch, tmpBasePath, err, prCtx.outbuf.String(), prCtx.errbuf.String())
|
||||||
cancel()
|
cancel()
|
||||||
return nil, nil, fmt.Errorf("Unable to fetch origin base branch [%s:%s -> base, original_base in tmpBasePath]: %w\n%s\n%s", pr.BaseRepo.FullName(), pr.BaseBranch, err, prCtx.outbuf.String(), prCtx.errbuf.String())
|
return nil, nil, fmt.Errorf("Unable to fetch origin base branch [%s:%s -> base, original_base in tmpBasePath]: %w\n%s\n%s", pr.BaseRepo.FullName(), pr.BaseBranch, err, prCtx.outbuf.String(), prCtx.errbuf.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := gitcmd.NewCommand("symbolic-ref").AddDynamicArguments("HEAD", git.BranchPrefix+baseBranch).
|
if err := prCtx.PrepareGitCmd(gitcmd.NewCommand("symbolic-ref").AddDynamicArguments("HEAD", git.BranchPrefix+baseBranch)).
|
||||||
Run(ctx, prCtx.RunOpts()); err != nil {
|
Run(ctx); err != nil {
|
||||||
log.Error("%-v Unable to set HEAD as base branch in [%s]: %v\n%s\n%s", pr, tmpBasePath, err, prCtx.outbuf.String(), prCtx.errbuf.String())
|
log.Error("%-v Unable to set HEAD as base branch in [%s]: %v\n%s\n%s", pr, tmpBasePath, err, prCtx.outbuf.String(), prCtx.errbuf.String())
|
||||||
cancel()
|
cancel()
|
||||||
return nil, nil, fmt.Errorf("Unable to set HEAD as base branch in tmpBasePath: %w\n%s\n%s", err, prCtx.outbuf.String(), prCtx.errbuf.String())
|
return nil, nil, fmt.Errorf("Unable to set HEAD as base branch in tmpBasePath: %w\n%s\n%s", err, prCtx.outbuf.String(), prCtx.errbuf.String())
|
||||||
@@ -159,8 +158,8 @@ func createTemporaryRepoForPR(ctx context.Context, pr *issues_model.PullRequest)
|
|||||||
return nil, nil, fmt.Errorf("Unable to add head base repository to temporary repo [%s -> tmpBasePath]: %w", pr.HeadRepo.FullName(), err)
|
return nil, nil, fmt.Errorf("Unable to add head base repository to temporary repo [%s -> tmpBasePath]: %w", pr.HeadRepo.FullName(), err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := gitcmd.NewCommand("remote", "add").AddDynamicArguments(remoteRepoName, headRepoPath).
|
if err := prCtx.PrepareGitCmd(gitcmd.NewCommand("remote", "add").AddDynamicArguments(remoteRepoName, headRepoPath)).
|
||||||
Run(ctx, prCtx.RunOpts()); err != nil {
|
Run(ctx); err != nil {
|
||||||
log.Error("%-v Unable to add head repository as head_repo [%s -> %s]: %v\n%s\n%s", pr, pr.HeadRepo.FullName(), tmpBasePath, err, prCtx.outbuf.String(), prCtx.errbuf.String())
|
log.Error("%-v Unable to add head repository as head_repo [%s -> %s]: %v\n%s\n%s", pr, pr.HeadRepo.FullName(), tmpBasePath, err, prCtx.outbuf.String(), prCtx.errbuf.String())
|
||||||
cancel()
|
cancel()
|
||||||
return nil, nil, fmt.Errorf("Unable to add head repository as head_repo [%s -> tmpBasePath]: %w\n%s\n%s", pr.HeadRepo.FullName(), err, prCtx.outbuf.String(), prCtx.errbuf.String())
|
return nil, nil, fmt.Errorf("Unable to add head repository as head_repo [%s -> tmpBasePath]: %w\n%s\n%s", pr.HeadRepo.FullName(), err, prCtx.outbuf.String(), prCtx.errbuf.String())
|
||||||
@@ -177,8 +176,8 @@ func createTemporaryRepoForPR(ctx context.Context, pr *issues_model.PullRequest)
|
|||||||
} else {
|
} else {
|
||||||
headBranch = pr.GetGitHeadRefName()
|
headBranch = pr.GetGitHeadRefName()
|
||||||
}
|
}
|
||||||
if err := gitcmd.NewCommand("fetch").AddArguments(fetchArgs...).AddDynamicArguments(remoteRepoName, headBranch+":"+trackingBranch).
|
if err := prCtx.PrepareGitCmd(gitcmd.NewCommand("fetch").AddArguments(fetchArgs...).AddDynamicArguments(remoteRepoName, headBranch+":"+trackingBranch)).
|
||||||
Run(ctx, prCtx.RunOpts()); err != nil {
|
Run(ctx); err != nil {
|
||||||
cancel()
|
cancel()
|
||||||
if !gitrepo.IsBranchExist(ctx, pr.HeadRepo, pr.HeadBranch) {
|
if !gitrepo.IsBranchExist(ctx, pr.HeadRepo, pr.HeadBranch) {
|
||||||
return nil, nil, git_model.ErrBranchNotExist{
|
return nil, nil, git_model.ErrBranchNotExist{
|
||||||
|
@@ -28,7 +28,8 @@ func updateHeadByRebaseOnToBase(ctx context.Context, pr *issues_model.PullReques
|
|||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
// Determine the old merge-base before the rebase - we use this for LFS push later on
|
// Determine the old merge-base before the rebase - we use this for LFS push later on
|
||||||
oldMergeBase, _, _ := gitcmd.NewCommand("merge-base").AddDashesAndList(baseBranch, trackingBranch).RunStdString(ctx, &gitcmd.RunOpts{Dir: mergeCtx.tmpBasePath})
|
oldMergeBase, _, _ := gitcmd.NewCommand("merge-base").AddDashesAndList(baseBranch, trackingBranch).
|
||||||
|
WithDir(mergeCtx.tmpBasePath).RunStdString(ctx)
|
||||||
oldMergeBase = strings.TrimSpace(oldMergeBase)
|
oldMergeBase = strings.TrimSpace(oldMergeBase)
|
||||||
|
|
||||||
// Rebase the tracking branch on to the base as the staging branch
|
// Rebase the tracking branch on to the base as the staging branch
|
||||||
@@ -72,18 +73,18 @@ func updateHeadByRebaseOnToBase(ctx context.Context, pr *issues_model.PullReques
|
|||||||
mergeCtx.outbuf.Reset()
|
mergeCtx.outbuf.Reset()
|
||||||
mergeCtx.errbuf.Reset()
|
mergeCtx.errbuf.Reset()
|
||||||
|
|
||||||
if err := pushCmd.Run(ctx, &gitcmd.RunOpts{
|
if err := pushCmd.
|
||||||
Env: repo_module.FullPushingEnvironment(
|
WithEnv(repo_module.FullPushingEnvironment(
|
||||||
headUser,
|
headUser,
|
||||||
doer,
|
doer,
|
||||||
pr.HeadRepo,
|
pr.HeadRepo,
|
||||||
pr.HeadRepo.Name,
|
pr.HeadRepo.Name,
|
||||||
pr.ID,
|
pr.ID,
|
||||||
),
|
)).
|
||||||
Dir: mergeCtx.tmpBasePath,
|
WithDir(mergeCtx.tmpBasePath).
|
||||||
Stdout: mergeCtx.outbuf,
|
WithStdout(mergeCtx.outbuf).
|
||||||
Stderr: mergeCtx.errbuf,
|
WithStderr(mergeCtx.errbuf).
|
||||||
}); err != nil {
|
Run(ctx); err != nil {
|
||||||
if strings.Contains(mergeCtx.errbuf.String(), "non-fast-forward") {
|
if strings.Contains(mergeCtx.errbuf.String(), "non-fast-forward") {
|
||||||
return &git.ErrPushOutOfDate{
|
return &git.ErrPushOutOfDate{
|
||||||
StdOut: mergeCtx.outbuf.String(),
|
StdOut: mergeCtx.outbuf.String(),
|
||||||
|
@@ -371,8 +371,9 @@ func DeleteReleaseByID(ctx context.Context, repo *repo_model.Repository, rel *re
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if stdout, _, err := gitcmd.NewCommand("tag", "-d").AddDashesAndList(rel.TagName).
|
if stdout, err := gitrepo.RunCmdString(ctx, repo,
|
||||||
RunStdString(ctx, &gitcmd.RunOpts{Dir: repo.RepoPath()}); err != nil && !strings.Contains(err.Error(), "not found") {
|
gitcmd.NewCommand("tag", "-d").AddDashesAndList(rel.TagName),
|
||||||
|
); err != nil && !strings.Contains(err.Error(), "not found") {
|
||||||
log.Error("DeleteReleaseByID (git tag -d): %d in %v Failed:\nStdout: %s\nError: %v", rel.ID, repo, stdout, err)
|
log.Error("DeleteReleaseByID (git tag -d): %d in %v Failed:\nStdout: %s\nError: %v", rel.ID, repo, stdout, err)
|
||||||
return fmt.Errorf("git tag -d: %w", err)
|
return fmt.Errorf("git tag -d: %w", err)
|
||||||
}
|
}
|
||||||
|
@@ -43,7 +43,7 @@ func UploadAvatar(ctx context.Context, repo *repo_model.Repository, data []byte)
|
|||||||
_, err := w.Write(avatarData)
|
_, err := w.Write(avatarData)
|
||||||
return err
|
return err
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
return fmt.Errorf("UploadAvatar %s failed: Failed to remove old repo avatar %s: %w", repo.RepoPath(), newAvatar, err)
|
return fmt.Errorf("UploadAvatar %s failed: Failed to remove old repo avatar %s: %w", repo.RelativePath(), newAvatar, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(oldAvatarPath) > 0 {
|
if len(oldAvatarPath) > 0 {
|
||||||
|
@@ -17,7 +17,6 @@ import (
|
|||||||
"code.gitea.io/gitea/modules/gitrepo"
|
"code.gitea.io/gitea/modules/gitrepo"
|
||||||
"code.gitea.io/gitea/modules/log"
|
"code.gitea.io/gitea/modules/log"
|
||||||
repo_module "code.gitea.io/gitea/modules/repository"
|
repo_module "code.gitea.io/gitea/modules/repository"
|
||||||
"code.gitea.io/gitea/modules/util"
|
|
||||||
|
|
||||||
"xorm.io/builder"
|
"xorm.io/builder"
|
||||||
)
|
)
|
||||||
@@ -89,24 +88,24 @@ func GitGcRepo(ctx context.Context, repo *repo_model.Repository, timeout time.Du
|
|||||||
command := gitcmd.NewCommand("gc").AddArguments(args...)
|
command := gitcmd.NewCommand("gc").AddArguments(args...)
|
||||||
var stdout string
|
var stdout string
|
||||||
var err error
|
var err error
|
||||||
stdout, _, err = command.RunStdString(ctx, &gitcmd.RunOpts{Timeout: timeout, Dir: repo.RepoPath()})
|
stdout, err = gitrepo.RunCmdString(ctx, repo, command)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Repository garbage collection failed for %-v. Stdout: %s\nError: %v", repo, stdout, err)
|
log.Error("Repository garbage collection failed for %-v. Stdout: %s\nError: %v", repo, stdout, err)
|
||||||
desc := fmt.Sprintf("Repository garbage collection failed for %s. Stdout: %s\nError: %v", repo.RepoPath(), stdout, err)
|
desc := fmt.Sprintf("Repository garbage collection failed for %s. Stdout: %s\nError: %v", repo.RelativePath(), stdout, err)
|
||||||
if err := system_model.CreateRepositoryNotice(desc); err != nil {
|
if err := system_model.CreateRepositoryNotice(desc); err != nil {
|
||||||
log.Error("CreateRepositoryNotice: %v", err)
|
log.Error("CreateRepositoryNotice: %v", err)
|
||||||
}
|
}
|
||||||
return fmt.Errorf("Repository garbage collection failed in repo: %s: Error: %w", repo.FullName(), err)
|
return fmt.Errorf("Repository garbage collection failed in repo: %s: Error: %w", repo.RelativePath(), err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now update the size of the repository
|
// Now update the size of the repository
|
||||||
if err := repo_module.UpdateRepoSize(ctx, repo); err != nil {
|
if err := repo_module.UpdateRepoSize(ctx, repo); err != nil {
|
||||||
log.Error("Updating size as part of garbage collection failed for %-v. Stdout: %s\nError: %v", repo, stdout, err)
|
log.Error("Updating size as part of garbage collection failed for %-v. Stdout: %s\nError: %v", repo, stdout, err)
|
||||||
desc := fmt.Sprintf("Updating size as part of garbage collection failed for %s. Stdout: %s\nError: %v", repo.RepoPath(), stdout, err)
|
desc := fmt.Sprintf("Updating size as part of garbage collection failed for %s. Stdout: %s\nError: %v", repo.RelativePath(), stdout, err)
|
||||||
if err := system_model.CreateRepositoryNotice(desc); err != nil {
|
if err := system_model.CreateRepositoryNotice(desc); err != nil {
|
||||||
log.Error("CreateRepositoryNotice: %v", err)
|
log.Error("CreateRepositoryNotice: %v", err)
|
||||||
}
|
}
|
||||||
return fmt.Errorf("Updating size as part of garbage collection failed in repo: %s: Error: %w", repo.FullName(), err)
|
return fmt.Errorf("Updating size as part of garbage collection failed in repo: %s: Error: %w", repo.RelativePath(), err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@@ -123,11 +122,11 @@ func gatherMissingRepoRecords(ctx context.Context) (repo_model.RepositoryList, e
|
|||||||
return db.ErrCancelledf("during gathering missing repo records before checking %s", repo.FullName())
|
return db.ErrCancelledf("during gathering missing repo records before checking %s", repo.FullName())
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
isDir, err := util.IsDir(repo.RepoPath())
|
exist, err := gitrepo.IsRepositoryExist(ctx, repo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Unable to check dir for %s. %w", repo.FullName(), err)
|
return fmt.Errorf("Unable to check dir for %s. %w", repo.FullName(), err)
|
||||||
}
|
}
|
||||||
if !isDir {
|
if !exist {
|
||||||
repos = append(repos, repo)
|
repos = append(repos, repo)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@@ -191,7 +190,7 @@ func ReinitMissingRepositories(ctx context.Context) error {
|
|||||||
}
|
}
|
||||||
log.Trace("Initializing %d/%d...", repo.OwnerID, repo.ID)
|
log.Trace("Initializing %d/%d...", repo.OwnerID, repo.ID)
|
||||||
if err := gitrepo.InitRepository(ctx, repo, repo.ObjectFormatName); err != nil {
|
if err := gitrepo.InitRepository(ctx, repo, repo.ObjectFormatName); err != nil {
|
||||||
log.Error("Unable (re)initialize repository %d at %s. Error: %v", repo.ID, repo.RepoPath(), err)
|
log.Error("Unable (re)initialize repository %d at %s. Error: %v", repo.ID, repo.RelativePath(), err)
|
||||||
if err2 := system_model.CreateRepositoryNotice("InitRepository [%d]: %v", repo.ID, err); err2 != nil {
|
if err2 := system_model.CreateRepositoryNotice("InitRepository [%d]: %v", repo.ID, err); err2 != nil {
|
||||||
log.Error("CreateRepositoryNotice: %v", err2)
|
log.Error("CreateRepositoryNotice: %v", err2)
|
||||||
}
|
}
|
||||||
|
@@ -69,12 +69,10 @@ func deleteCommitStatusCache(repoID int64, branchName string) error {
|
|||||||
// NOTE: All text-values will be trimmed from whitespaces.
|
// NOTE: All text-values will be trimmed from whitespaces.
|
||||||
// Requires: Repo, Creator, SHA
|
// Requires: Repo, Creator, SHA
|
||||||
func CreateCommitStatus(ctx context.Context, repo *repo_model.Repository, creator *user_model.User, sha string, status *git_model.CommitStatus) error {
|
func CreateCommitStatus(ctx context.Context, repo *repo_model.Repository, creator *user_model.User, sha string, status *git_model.CommitStatus) error {
|
||||||
repoPath := repo.RepoPath()
|
|
||||||
|
|
||||||
// confirm that commit is exist
|
// confirm that commit is exist
|
||||||
gitRepo, closer, err := gitrepo.RepositoryFromContextOrOpen(ctx, repo)
|
gitRepo, closer, err := gitrepo.RepositoryFromContextOrOpen(ctx, repo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("OpenRepository[%s]: %w", repoPath, err)
|
return fmt.Errorf("OpenRepository[%s]: %w", repo.RelativePath(), err)
|
||||||
}
|
}
|
||||||
defer closer.Close()
|
defer closer.Close()
|
||||||
|
|
||||||
|
@@ -132,11 +132,10 @@ func getExtendedCommitStats(repo *git.Repository, revision string /*, limit int
|
|||||||
|
|
||||||
var extendedCommitStats []*ExtendedCommitStats
|
var extendedCommitStats []*ExtendedCommitStats
|
||||||
stderr := new(strings.Builder)
|
stderr := new(strings.Builder)
|
||||||
err = gitCmd.Run(repo.Ctx, &gitcmd.RunOpts{
|
err = gitCmd.WithDir(repo.Path).
|
||||||
Dir: repo.Path,
|
WithStdout(stdoutWriter).
|
||||||
Stdout: stdoutWriter,
|
WithStderr(stderr).
|
||||||
Stderr: stderr,
|
WithPipelineFunc(func(ctx context.Context, cancel context.CancelFunc) error {
|
||||||
PipelineFunc: func(ctx context.Context, cancel context.CancelFunc) error {
|
|
||||||
_ = stdoutWriter.Close()
|
_ = stdoutWriter.Close()
|
||||||
scanner := bufio.NewScanner(stdoutReader)
|
scanner := bufio.NewScanner(stdoutReader)
|
||||||
|
|
||||||
@@ -191,8 +190,8 @@ func getExtendedCommitStats(repo *git.Repository, revision string /*, limit int
|
|||||||
}
|
}
|
||||||
_ = stdoutReader.Close()
|
_ = stdoutReader.Close()
|
||||||
return nil
|
return nil
|
||||||
},
|
}).
|
||||||
})
|
Run(repo.Ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("Failed to get ContributorsCommitStats for repository.\nError: %w\nStderr: %s", err, stderr)
|
return nil, fmt.Errorf("Failed to get ContributorsCommitStats for repository.\nError: %w\nStderr: %s", err, stderr)
|
||||||
}
|
}
|
||||||
|
@@ -70,7 +70,7 @@ func prepareRepoCommit(ctx context.Context, repo *repo_model.Repository, tmpDir
|
|||||||
|
|
||||||
// Clone to temporary path and do the init commit.
|
// Clone to temporary path and do the init commit.
|
||||||
if stdout, _, err := gitcmd.NewCommand("clone").AddDynamicArguments(repo.RepoPath(), tmpDir).
|
if stdout, _, err := gitcmd.NewCommand("clone").AddDynamicArguments(repo.RepoPath(), tmpDir).
|
||||||
RunStdString(ctx, &gitcmd.RunOpts{Dir: "", Env: env}); err != nil {
|
WithEnv(env).RunStdString(ctx); err != nil {
|
||||||
log.Error("Failed to clone from %v into %s: stdout: %s\nError: %v", repo, tmpDir, stdout, err)
|
log.Error("Failed to clone from %v into %s: stdout: %s\nError: %v", repo, tmpDir, stdout, err)
|
||||||
return fmt.Errorf("git clone: %w", err)
|
return fmt.Errorf("git clone: %w", err)
|
||||||
}
|
}
|
||||||
@@ -314,7 +314,7 @@ func CreateRepositoryDirectly(ctx context.Context, doer, owner *user_model.User,
|
|||||||
licenses = append(licenses, opts.License)
|
licenses = append(licenses, opts.License)
|
||||||
|
|
||||||
var stdout string
|
var stdout string
|
||||||
stdout, _, err = gitcmd.NewCommand("rev-parse", "HEAD").RunStdString(ctx, &gitcmd.RunOpts{Dir: repo.RepoPath()})
|
stdout, err = gitrepo.RunCmdString(ctx, repo, gitcmd.NewCommand("rev-parse", "HEAD"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("CreateRepository(git rev-parse HEAD) in %v: Stdout: %s\nError: %v", repo, stdout, err)
|
log.Error("CreateRepository(git rev-parse HEAD) in %v: Stdout: %s\nError: %v", repo, stdout, err)
|
||||||
return nil, fmt.Errorf("CreateRepository(git rev-parse HEAD): %w", err)
|
return nil, fmt.Errorf("CreateRepository(git rev-parse HEAD): %w", err)
|
||||||
@@ -475,8 +475,8 @@ func updateGitRepoAfterCreate(ctx context.Context, repo *repo_model.Repository)
|
|||||||
return fmt.Errorf("checkDaemonExportOK: %w", err)
|
return fmt.Errorf("checkDaemonExportOK: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if stdout, _, err := gitcmd.NewCommand("update-server-info").
|
if stdout, err := gitrepo.RunCmdString(ctx, repo,
|
||||||
RunStdString(ctx, &gitcmd.RunOpts{Dir: repo.RepoPath()}); err != nil {
|
gitcmd.NewCommand("update-server-info")); err != nil {
|
||||||
log.Error("CreateRepository(git update-server-info) in %v: Stdout: %s\nError: %v", repo, stdout, err)
|
log.Error("CreateRepository(git update-server-info) in %v: Stdout: %s\nError: %v", repo, stdout, err)
|
||||||
return fmt.Errorf("CreateRepository(git update-server-info): %w", err)
|
return fmt.Errorf("CreateRepository(git update-server-info): %w", err)
|
||||||
}
|
}
|
||||||
|
@@ -165,12 +165,11 @@ func ApplyDiffPatch(ctx context.Context, repo *repo_model.Repository, doer *user
|
|||||||
cmdApply.AddArguments("-3")
|
cmdApply.AddArguments("-3")
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := cmdApply.Run(ctx, &gitcmd.RunOpts{
|
if err := cmdApply.WithDir(t.basePath).
|
||||||
Dir: t.basePath,
|
WithStdout(stdout).
|
||||||
Stdout: stdout,
|
WithStderr(stderr).
|
||||||
Stderr: stderr,
|
WithStdin(strings.NewReader(opts.Content)).
|
||||||
Stdin: strings.NewReader(opts.Content),
|
Run(ctx); err != nil {
|
||||||
}); err != nil {
|
|
||||||
return nil, fmt.Errorf("Error: Stdout: %s\nStderr: %s\nErr: %w", stdout.String(), stderr.String(), err)
|
return nil, fmt.Errorf("Error: Stdout: %s\nStderr: %s\nErr: %w", stdout.String(), stderr.String(), err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -59,7 +59,7 @@ func (t *TemporaryUploadRepository) Clone(ctx context.Context, branch string, ba
|
|||||||
cmd.AddArguments("--bare")
|
cmd.AddArguments("--bare")
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, _, err := cmd.RunStdString(ctx, nil); err != nil {
|
if _, _, err := cmd.RunStdString(ctx); err != nil {
|
||||||
stderr := err.Error()
|
stderr := err.Error()
|
||||||
if matched, _ := regexp.MatchString(".*Remote branch .* not found in upstream origin.*", stderr); matched {
|
if matched, _ := regexp.MatchString(".*Remote branch .* not found in upstream origin.*", stderr); matched {
|
||||||
return git.ErrBranchNotExist{
|
return git.ErrBranchNotExist{
|
||||||
@@ -98,7 +98,7 @@ func (t *TemporaryUploadRepository) Init(ctx context.Context, objectFormatName s
|
|||||||
|
|
||||||
// SetDefaultIndex sets the git index to our HEAD
|
// SetDefaultIndex sets the git index to our HEAD
|
||||||
func (t *TemporaryUploadRepository) SetDefaultIndex(ctx context.Context) error {
|
func (t *TemporaryUploadRepository) SetDefaultIndex(ctx context.Context) error {
|
||||||
if _, _, err := gitcmd.NewCommand("read-tree", "HEAD").RunStdString(ctx, &gitcmd.RunOpts{Dir: t.basePath}); err != nil {
|
if _, _, err := gitcmd.NewCommand("read-tree", "HEAD").WithDir(t.basePath).RunStdString(ctx); err != nil {
|
||||||
return fmt.Errorf("SetDefaultIndex: %w", err)
|
return fmt.Errorf("SetDefaultIndex: %w", err)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@@ -106,7 +106,7 @@ func (t *TemporaryUploadRepository) SetDefaultIndex(ctx context.Context) error {
|
|||||||
|
|
||||||
// RefreshIndex looks at the current index and checks to see if merges or updates are needed by checking stat() information.
|
// RefreshIndex looks at the current index and checks to see if merges or updates are needed by checking stat() information.
|
||||||
func (t *TemporaryUploadRepository) RefreshIndex(ctx context.Context) error {
|
func (t *TemporaryUploadRepository) RefreshIndex(ctx context.Context) error {
|
||||||
if _, _, err := gitcmd.NewCommand("update-index", "--refresh").RunStdString(ctx, &gitcmd.RunOpts{Dir: t.basePath}); err != nil {
|
if _, _, err := gitcmd.NewCommand("update-index", "--refresh").WithDir(t.basePath).RunStdString(ctx); err != nil {
|
||||||
return fmt.Errorf("RefreshIndex: %w", err)
|
return fmt.Errorf("RefreshIndex: %w", err)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@@ -118,11 +118,10 @@ func (t *TemporaryUploadRepository) LsFiles(ctx context.Context, filenames ...st
|
|||||||
stdErr := new(bytes.Buffer)
|
stdErr := new(bytes.Buffer)
|
||||||
|
|
||||||
if err := gitcmd.NewCommand("ls-files", "-z").AddDashesAndList(filenames...).
|
if err := gitcmd.NewCommand("ls-files", "-z").AddDashesAndList(filenames...).
|
||||||
Run(ctx, &gitcmd.RunOpts{
|
WithDir(t.basePath).
|
||||||
Dir: t.basePath,
|
WithStdout(stdOut).
|
||||||
Stdout: stdOut,
|
WithStderr(stdErr).
|
||||||
Stderr: stdErr,
|
Run(ctx); err != nil {
|
||||||
}); err != nil {
|
|
||||||
log.Error("Unable to run git ls-files for temporary repo: %s (%s) Error: %v\nstdout: %s\nstderr: %s", t.repo.FullName(), t.basePath, err, stdOut.String(), stdErr.String())
|
log.Error("Unable to run git ls-files for temporary repo: %s (%s) Error: %v\nstdout: %s\nstderr: %s", t.repo.FullName(), t.basePath, err, stdOut.String(), stdErr.String())
|
||||||
err = fmt.Errorf("Unable to run git ls-files for temporary repo of: %s Error: %w\nstdout: %s\nstderr: %s", t.repo.FullName(), err, stdOut.String(), stdErr.String())
|
err = fmt.Errorf("Unable to run git ls-files for temporary repo of: %s Error: %w\nstdout: %s\nstderr: %s", t.repo.FullName(), err, stdOut.String(), stdErr.String())
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -154,12 +153,11 @@ func (t *TemporaryUploadRepository) RemoveFilesFromIndex(ctx context.Context, fi
|
|||||||
}
|
}
|
||||||
|
|
||||||
if err := gitcmd.NewCommand("update-index", "--remove", "-z", "--index-info").
|
if err := gitcmd.NewCommand("update-index", "--remove", "-z", "--index-info").
|
||||||
Run(ctx, &gitcmd.RunOpts{
|
WithDir(t.basePath).
|
||||||
Dir: t.basePath,
|
WithStdout(stdOut).
|
||||||
Stdin: stdIn,
|
WithStderr(stdErr).
|
||||||
Stdout: stdOut,
|
WithStdin(stdIn).
|
||||||
Stderr: stdErr,
|
Run(ctx); err != nil {
|
||||||
}); err != nil {
|
|
||||||
return fmt.Errorf("unable to update-index for temporary repo: %q, error: %w\nstdout: %s\nstderr: %s", t.repo.FullName(), err, stdOut.String(), stdErr.String())
|
return fmt.Errorf("unable to update-index for temporary repo: %q, error: %w\nstdout: %s\nstderr: %s", t.repo.FullName(), err, stdOut.String(), stdErr.String())
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@@ -171,12 +169,11 @@ func (t *TemporaryUploadRepository) HashObjectAndWrite(ctx context.Context, cont
|
|||||||
stdErr := new(bytes.Buffer)
|
stdErr := new(bytes.Buffer)
|
||||||
|
|
||||||
if err := gitcmd.NewCommand("hash-object", "-w", "--stdin").
|
if err := gitcmd.NewCommand("hash-object", "-w", "--stdin").
|
||||||
Run(ctx, &gitcmd.RunOpts{
|
WithDir(t.basePath).
|
||||||
Dir: t.basePath,
|
WithStdout(stdOut).
|
||||||
Stdin: content,
|
WithStderr(stdErr).
|
||||||
Stdout: stdOut,
|
WithStdin(content).
|
||||||
Stderr: stdErr,
|
Run(ctx); err != nil {
|
||||||
}); err != nil {
|
|
||||||
log.Error("Unable to hash-object to temporary repo: %s (%s) Error: %v\nstdout: %s\nstderr: %s", t.repo.FullName(), t.basePath, err, stdOut.String(), stdErr.String())
|
log.Error("Unable to hash-object to temporary repo: %s (%s) Error: %v\nstdout: %s\nstderr: %s", t.repo.FullName(), t.basePath, err, stdOut.String(), stdErr.String())
|
||||||
return "", fmt.Errorf("Unable to hash-object to temporary repo: %s Error: %w\nstdout: %s\nstderr: %s", t.repo.FullName(), err, stdOut.String(), stdErr.String())
|
return "", fmt.Errorf("Unable to hash-object to temporary repo: %s Error: %w\nstdout: %s\nstderr: %s", t.repo.FullName(), err, stdOut.String(), stdErr.String())
|
||||||
}
|
}
|
||||||
@@ -186,7 +183,8 @@ func (t *TemporaryUploadRepository) HashObjectAndWrite(ctx context.Context, cont
|
|||||||
|
|
||||||
// AddObjectToIndex adds the provided object hash to the index with the provided mode and path
|
// AddObjectToIndex adds the provided object hash to the index with the provided mode and path
|
||||||
func (t *TemporaryUploadRepository) AddObjectToIndex(ctx context.Context, mode, objectHash, objectPath string) error {
|
func (t *TemporaryUploadRepository) AddObjectToIndex(ctx context.Context, mode, objectHash, objectPath string) error {
|
||||||
if _, _, err := gitcmd.NewCommand("update-index", "--add", "--replace", "--cacheinfo").AddDynamicArguments(mode, objectHash, objectPath).RunStdString(ctx, &gitcmd.RunOpts{Dir: t.basePath}); err != nil {
|
if _, _, err := gitcmd.NewCommand("update-index", "--add", "--replace", "--cacheinfo").
|
||||||
|
AddDynamicArguments(mode, objectHash, objectPath).WithDir(t.basePath).RunStdString(ctx); err != nil {
|
||||||
stderr := err.Error()
|
stderr := err.Error()
|
||||||
if matched, _ := regexp.MatchString(".*Invalid path '.*", stderr); matched {
|
if matched, _ := regexp.MatchString(".*Invalid path '.*", stderr); matched {
|
||||||
return ErrFilePathInvalid{
|
return ErrFilePathInvalid{
|
||||||
@@ -202,7 +200,7 @@ func (t *TemporaryUploadRepository) AddObjectToIndex(ctx context.Context, mode,
|
|||||||
|
|
||||||
// WriteTree writes the current index as a tree to the object db and returns its hash
|
// WriteTree writes the current index as a tree to the object db and returns its hash
|
||||||
func (t *TemporaryUploadRepository) WriteTree(ctx context.Context) (string, error) {
|
func (t *TemporaryUploadRepository) WriteTree(ctx context.Context) (string, error) {
|
||||||
stdout, _, err := gitcmd.NewCommand("write-tree").RunStdString(ctx, &gitcmd.RunOpts{Dir: t.basePath})
|
stdout, _, err := gitcmd.NewCommand("write-tree").WithDir(t.basePath).RunStdString(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Unable to write tree in temporary repo: %s(%s): Error: %v", t.repo.FullName(), t.basePath, err)
|
log.Error("Unable to write tree in temporary repo: %s(%s): Error: %v", t.repo.FullName(), t.basePath, err)
|
||||||
return "", fmt.Errorf("Unable to write-tree in temporary repo for: %s Error: %w", t.repo.FullName(), err)
|
return "", fmt.Errorf("Unable to write-tree in temporary repo for: %s Error: %w", t.repo.FullName(), err)
|
||||||
@@ -220,7 +218,7 @@ func (t *TemporaryUploadRepository) GetLastCommitByRef(ctx context.Context, ref
|
|||||||
if ref == "" {
|
if ref == "" {
|
||||||
ref = "HEAD"
|
ref = "HEAD"
|
||||||
}
|
}
|
||||||
stdout, _, err := gitcmd.NewCommand("rev-parse").AddDynamicArguments(ref).RunStdString(ctx, &gitcmd.RunOpts{Dir: t.basePath})
|
stdout, _, err := gitcmd.NewCommand("rev-parse").AddDynamicArguments(ref).WithDir(t.basePath).RunStdString(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Unable to get last ref for %s in temporary repo: %s(%s): Error: %v", ref, t.repo.FullName(), t.basePath, err)
|
log.Error("Unable to get last ref for %s in temporary repo: %s(%s): Error: %v", ref, t.repo.FullName(), t.basePath, err)
|
||||||
return "", fmt.Errorf("Unable to rev-parse %s in temporary repo for: %s Error: %w", ref, t.repo.FullName(), err)
|
return "", fmt.Errorf("Unable to rev-parse %s in temporary repo for: %s Error: %w", ref, t.repo.FullName(), err)
|
||||||
@@ -338,13 +336,12 @@ func (t *TemporaryUploadRepository) CommitTree(ctx context.Context, opts *Commit
|
|||||||
stdout := new(bytes.Buffer)
|
stdout := new(bytes.Buffer)
|
||||||
stderr := new(bytes.Buffer)
|
stderr := new(bytes.Buffer)
|
||||||
if err := cmdCommitTree.
|
if err := cmdCommitTree.
|
||||||
Run(ctx, &gitcmd.RunOpts{
|
WithEnv(env).
|
||||||
Env: env,
|
WithDir(t.basePath).
|
||||||
Dir: t.basePath,
|
WithStdout(stdout).
|
||||||
Stdin: messageBytes,
|
WithStderr(stderr).
|
||||||
Stdout: stdout,
|
WithStdin(messageBytes).
|
||||||
Stderr: stderr,
|
Run(ctx); err != nil {
|
||||||
}); err != nil {
|
|
||||||
log.Error("Unable to commit-tree in temporary repo: %s (%s) Error: %v\nStdout: %s\nStderr: %s",
|
log.Error("Unable to commit-tree in temporary repo: %s (%s) Error: %v\nStdout: %s\nStderr: %s",
|
||||||
t.repo.FullName(), t.basePath, err, stdout, stderr)
|
t.repo.FullName(), t.basePath, err, stdout, stderr)
|
||||||
return "", fmt.Errorf("Unable to commit-tree in temporary repo: %s Error: %w\nStdout: %s\nStderr: %s",
|
return "", fmt.Errorf("Unable to commit-tree in temporary repo: %s Error: %w\nStdout: %s\nStderr: %s",
|
||||||
@@ -389,24 +386,23 @@ func (t *TemporaryUploadRepository) DiffIndex(ctx context.Context) (*gitdiff.Dif
|
|||||||
stderr := new(bytes.Buffer)
|
stderr := new(bytes.Buffer)
|
||||||
var diff *gitdiff.Diff
|
var diff *gitdiff.Diff
|
||||||
err = gitcmd.NewCommand("diff-index", "--src-prefix=\\a/", "--dst-prefix=\\b/", "--cached", "-p", "HEAD").
|
err = gitcmd.NewCommand("diff-index", "--src-prefix=\\a/", "--dst-prefix=\\b/", "--cached", "-p", "HEAD").
|
||||||
Run(ctx, &gitcmd.RunOpts{
|
WithTimeout(30 * time.Second).
|
||||||
Timeout: 30 * time.Second,
|
WithDir(t.basePath).
|
||||||
Dir: t.basePath,
|
WithStdout(stdoutWriter).
|
||||||
Stdout: stdoutWriter,
|
WithStderr(stderr).
|
||||||
Stderr: stderr,
|
WithPipelineFunc(func(ctx context.Context, cancel context.CancelFunc) error {
|
||||||
PipelineFunc: func(ctx context.Context, cancel context.CancelFunc) error {
|
_ = stdoutWriter.Close()
|
||||||
_ = stdoutWriter.Close()
|
defer cancel()
|
||||||
defer cancel()
|
var diffErr error
|
||||||
var diffErr error
|
diff, diffErr = gitdiff.ParsePatch(ctx, setting.Git.MaxGitDiffLines, setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles, stdoutReader, "")
|
||||||
diff, diffErr = gitdiff.ParsePatch(ctx, setting.Git.MaxGitDiffLines, setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles, stdoutReader, "")
|
_ = stdoutReader.Close()
|
||||||
_ = stdoutReader.Close()
|
if diffErr != nil {
|
||||||
if diffErr != nil {
|
// if the diffErr is not nil, it will be returned as the error of "Run()"
|
||||||
// if the diffErr is not nil, it will be returned as the error of "Run()"
|
return fmt.Errorf("ParsePatch: %w", diffErr)
|
||||||
return fmt.Errorf("ParsePatch: %w", diffErr)
|
}
|
||||||
}
|
return nil
|
||||||
return nil
|
}).
|
||||||
},
|
Run(ctx)
|
||||||
})
|
|
||||||
if err != nil && !git.IsErrCanceledOrKilled(err) {
|
if err != nil && !git.IsErrCanceledOrKilled(err) {
|
||||||
log.Error("Unable to diff-index in temporary repo %s (%s). Error: %v\nStderr: %s", t.repo.FullName(), t.basePath, err, stderr)
|
log.Error("Unable to diff-index in temporary repo %s (%s). Error: %v\nStderr: %s", t.repo.FullName(), t.basePath, err, stderr)
|
||||||
return nil, fmt.Errorf("unable to run diff-index pipeline in temporary repo: %w", err)
|
return nil, fmt.Errorf("unable to run diff-index pipeline in temporary repo: %w", err)
|
||||||
|
@@ -153,7 +153,8 @@ func ForkRepository(ctx context.Context, doer, owner *user_model.User, opts Fork
|
|||||||
}
|
}
|
||||||
var stdout []byte
|
var stdout []byte
|
||||||
if stdout, _, err = cloneCmd.AddDynamicArguments(opts.BaseRepo.RepoPath(), repo.RepoPath()).
|
if stdout, _, err = cloneCmd.AddDynamicArguments(opts.BaseRepo.RepoPath(), repo.RepoPath()).
|
||||||
RunStdBytes(ctx, &gitcmd.RunOpts{Timeout: 10 * time.Minute}); err != nil {
|
WithTimeout(10 * time.Minute).
|
||||||
|
RunStdBytes(ctx); err != nil {
|
||||||
log.Error("Fork Repository (git clone) Failed for %v (from %v):\nStdout: %s\nError: %v", repo, opts.BaseRepo, stdout, err)
|
log.Error("Fork Repository (git clone) Failed for %v (from %v):\nStdout: %s\nError: %v", repo, opts.BaseRepo, stdout, err)
|
||||||
return nil, fmt.Errorf("git clone: %w", err)
|
return nil, fmt.Errorf("git clone: %w", err)
|
||||||
}
|
}
|
||||||
|
@@ -235,8 +235,11 @@ func generateRepoCommit(ctx context.Context, repo, templateRepo, generateRepo *r
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if stdout, _, err := gitcmd.NewCommand("remote", "add", "origin").AddDynamicArguments(repo.RepoPath()).
|
if stdout, _, err := gitcmd.NewCommand("remote", "add", "origin").
|
||||||
RunStdString(ctx, &gitcmd.RunOpts{Dir: tmpDir, Env: env}); err != nil {
|
AddDynamicArguments(repo.RepoPath()).
|
||||||
|
WithDir(tmpDir).
|
||||||
|
WithEnv(env).
|
||||||
|
RunStdString(ctx); err != nil {
|
||||||
log.Error("Unable to add %v as remote origin to temporary repo to %s: stdout %s\nError: %v", repo, tmpDir, stdout, err)
|
log.Error("Unable to add %v as remote origin to temporary repo to %s: stdout %s\nError: %v", repo, tmpDir, stdout, err)
|
||||||
return fmt.Errorf("git remote add: %w", err)
|
return fmt.Errorf("git remote add: %w", err)
|
||||||
}
|
}
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user