diff options
author | zeripath <art27@cantab.net> | 2021-11-30 20:06:32 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-11-30 20:06:32 +0000 |
commit | 01087e9eef21ff5ea1cebbb1e84933954671fdf2 (patch) | |
tree | ae618785a3bd46e012096683e2fd2309f87c571d /modules/git | |
parent | d894c90b703ce215e2319ae2e2bf95989f77805d (diff) | |
download | gitea-01087e9eef21ff5ea1cebbb1e84933954671fdf2.tar.gz gitea-01087e9eef21ff5ea1cebbb1e84933954671fdf2.zip |
Make Requests Processes and create process hierarchy. Associate OpenRepository with context. (#17125)
This PR registers requests with the process manager and manages hierarchy within the processes.
Git repos are then associated with a context, (usually the request's context) - with sub commands using this context as their base context.
Signed-off-by: Andrew Thornton <art27@cantab.net>
Diffstat (limited to 'modules/git')
31 files changed, 169 insertions, 149 deletions
diff --git a/modules/git/batch_reader.go b/modules/git/batch_reader.go index 8e3c23251b..71045adbc9 100644 --- a/modules/git/batch_reader.go +++ b/modules/git/batch_reader.go @@ -28,17 +28,15 @@ type WriteCloserError interface { } // CatFileBatchCheck opens git cat-file --batch-check in the provided repo and returns a stdin pipe, a stdout reader and cancel function -func CatFileBatchCheck(repoPath string) (WriteCloserError, *bufio.Reader, func()) { +func CatFileBatchCheck(ctx context.Context, repoPath string) (WriteCloserError, *bufio.Reader, func()) { batchStdinReader, batchStdinWriter := io.Pipe() batchStdoutReader, batchStdoutWriter := io.Pipe() - ctx, ctxCancel := context.WithCancel(DefaultContext) + ctx, ctxCancel := context.WithCancel(ctx) closed := make(chan struct{}) cancel := func() { - _ = batchStdinReader.Close() - _ = batchStdinWriter.Close() - _ = batchStdoutReader.Close() - _ = batchStdoutWriter.Close() ctxCancel() + _ = batchStdoutReader.Close() + _ = batchStdinWriter.Close() <-closed } @@ -67,19 +65,17 @@ func CatFileBatchCheck(repoPath string) (WriteCloserError, *bufio.Reader, func() } // CatFileBatch opens git cat-file --batch in the provided repo and returns a stdin pipe, a stdout reader and cancel function -func CatFileBatch(repoPath string) (WriteCloserError, *bufio.Reader, func()) { +func CatFileBatch(ctx context.Context, repoPath string) (WriteCloserError, *bufio.Reader, func()) { // We often want to feed the commits in order into cat-file --batch, followed by their trees and sub trees as necessary. // so let's create a batch stdin and stdout batchStdinReader, batchStdinWriter := io.Pipe() batchStdoutReader, batchStdoutWriter := nio.Pipe(buffer.New(32 * 1024)) - ctx, ctxCancel := context.WithCancel(DefaultContext) + ctx, ctxCancel := context.WithCancel(ctx) closed := make(chan struct{}) cancel := func() { - _ = batchStdinReader.Close() + ctxCancel() _ = batchStdinWriter.Close() _ = batchStdoutReader.Close() - _ = batchStdoutWriter.Close() - ctxCancel() <-closed } diff --git a/modules/git/blame.go b/modules/git/blame.go index fcbf183981..b30124594d 100644 --- a/modules/git/blame.go +++ b/modules/git/blame.go @@ -24,12 +24,12 @@ type BlamePart struct { // BlameReader returns part of file blame one by one type BlameReader struct { - cmd *exec.Cmd - pid int64 - output io.ReadCloser - reader *bufio.Reader - lastSha *string - cancel context.CancelFunc + cmd *exec.Cmd + output io.ReadCloser + reader *bufio.Reader + lastSha *string + cancel context.CancelFunc // Cancels the context that this reader runs in + finished process.FinishedFunc // Tells the process manager we're finished and it can remove the associated process from the process table } var shaLineRegex = regexp.MustCompile("^([a-z0-9]{40})") @@ -100,8 +100,8 @@ func (r *BlameReader) NextPart() (*BlamePart, error) { // Close BlameReader - don't run NextPart after invoking that func (r *BlameReader) Close() error { - defer process.GetManager().Remove(r.pid) - r.cancel() + defer r.finished() // Only remove the process from the process table when the underlying command is closed + r.cancel() // However, first cancel our own context early _ = r.output.Close() @@ -114,7 +114,7 @@ func (r *BlameReader) Close() error { // CreateBlameReader creates reader for given repository, commit and file func CreateBlameReader(ctx context.Context, repoPath, commitID, file string) (*BlameReader, error) { - gitRepo, err := OpenRepository(repoPath) + gitRepo, err := OpenRepositoryCtx(ctx, repoPath) if err != nil { return nil, err } @@ -125,32 +125,31 @@ func CreateBlameReader(ctx context.Context, repoPath, commitID, file string) (*B func createBlameReader(ctx context.Context, dir string, command ...string) (*BlameReader, error) { // Here we use the provided context - this should be tied to the request performing the blame so that it does not hang around. - ctx, cancel := context.WithCancel(ctx) + ctx, cancel, finished := process.GetManager().AddContext(ctx, fmt.Sprintf("GetBlame [repo_path: %s]", dir)) + cmd := exec.CommandContext(ctx, command[0], command[1:]...) cmd.Dir = dir cmd.Stderr = os.Stderr stdout, err := cmd.StdoutPipe() if err != nil { - defer cancel() + defer finished() return nil, fmt.Errorf("StdoutPipe: %v", err) } if err = cmd.Start(); err != nil { - defer cancel() + defer finished() + _ = stdout.Close() return nil, fmt.Errorf("Start: %v", err) } - pid := process.GetManager().Add(fmt.Sprintf("GetBlame [repo_path: %s]", dir), cancel) - reader := bufio.NewReader(stdout) return &BlameReader{ - cmd, - pid, - stdout, - reader, - nil, - cancel, + cmd: cmd, + output: stdout, + reader: reader, + cancel: cancel, + finished: finished, }, nil } diff --git a/modules/git/blob_nogogit.go b/modules/git/blob_nogogit.go index 65a73ebc52..aabf1b34ad 100644 --- a/modules/git/blob_nogogit.go +++ b/modules/git/blob_nogogit.go @@ -29,7 +29,7 @@ type Blob struct { // DataAsync gets a ReadCloser for the contents of a blob without reading it all. // Calling the Close function on the result will discard all unread output. func (b *Blob) DataAsync() (io.ReadCloser, error) { - wr, rd, cancel := b.repo.CatFileBatch() + wr, rd, cancel := b.repo.CatFileBatch(b.repo.Ctx) _, err := wr.Write([]byte(b.ID.String() + "\n")) if err != nil { @@ -67,7 +67,7 @@ func (b *Blob) Size() int64 { return b.size } - wr, rd, cancel := b.repo.CatFileBatchCheck() + wr, rd, cancel := b.repo.CatFileBatchCheck(b.repo.Ctx) defer cancel() _, err := wr.Write([]byte(b.ID.String() + "\n")) if err != nil { diff --git a/modules/git/command.go b/modules/git/command.go index e7496f072c..3cf85c2d85 100644 --- a/modules/git/command.go +++ b/modules/git/command.go @@ -143,8 +143,13 @@ func (c *Command) RunWithContext(rc *RunContext) error { log.Debug("%s: %v", rc.Dir, c) } - ctx, cancel := context.WithTimeout(c.parentContext, rc.Timeout) - defer cancel() + desc := c.desc + if desc == "" { + desc = fmt.Sprintf("%s %s [repo_path: %s]", c.name, strings.Join(c.args, " "), rc.Dir) + } + + ctx, cancel, finished := process.GetManager().AddContextTimeout(c.parentContext, rc.Timeout, desc) + defer finished() cmd := exec.CommandContext(ctx, c.name, c.args...) if rc.Env == nil { @@ -172,13 +177,6 @@ func (c *Command) RunWithContext(rc *RunContext) error { return err } - desc := c.desc - if desc == "" { - desc = fmt.Sprintf("%s %s %s [repo_path: %s]", GitExecutable, c.name, strings.Join(c.args, " "), rc.Dir) - } - pid := process.GetManager().Add(desc, cancel) - defer process.GetManager().Remove(pid) - if rc.PipelineFunc != nil { err := rc.PipelineFunc(ctx, cancel) if err != nil { diff --git a/modules/git/commit_info_nogogit.go b/modules/git/commit_info_nogogit.go index 261252dab1..b58c1885b6 100644 --- a/modules/git/commit_info_nogogit.go +++ b/modules/git/commit_info_nogogit.go @@ -100,7 +100,7 @@ func (tes Entries) GetCommitsInfo(ctx context.Context, commit *Commit, treePath } func getLastCommitForPathsByCache(ctx context.Context, commitID, treePath string, paths []string, cache *LastCommitCache) (map[string]*Commit, []string, error) { - wr, rd, cancel := cache.repo.CatFileBatch() + wr, rd, cancel := cache.repo.CatFileBatch(ctx) defer cancel() var unHitEntryPaths []string @@ -129,7 +129,7 @@ func GetLastCommitForPaths(ctx context.Context, cache *LastCommitCache, commit * return nil, err } - batchStdinWriter, batchReader, cancel := commit.repo.CatFileBatch() + batchStdinWriter, batchReader, cancel := commit.repo.CatFileBatch(ctx) defer cancel() commitsMap := map[string]*Commit{} diff --git a/modules/git/diff.go b/modules/git/diff.go index b473dc73f6..3a82cda1ce 100644 --- a/modules/git/diff.go +++ b/modules/git/diff.go @@ -56,8 +56,8 @@ func GetRepoRawDiffForFile(repo *Repository, startCommit, endCommit string, diff fileArgs = append(fileArgs, "--", file) } // FIXME: graceful: These commands should have a timeout - ctx, cancel := context.WithCancel(DefaultContext) - defer cancel() + ctx, _, finished := process.GetManager().AddContext(repo.Ctx, fmt.Sprintf("GetRawDiffForFile: [repo_path: %s]", repo.Path)) + defer finished() var cmd *exec.Cmd switch diffType { @@ -90,8 +90,6 @@ func GetRepoRawDiffForFile(repo *Repository, startCommit, endCommit string, diff cmd.Dir = repo.Path cmd.Stdout = writer cmd.Stderr = stderr - pid := process.GetManager().Add(fmt.Sprintf("GetRawDiffForFile: [repo_path: %s]", repo.Path), cancel) - defer process.GetManager().Remove(pid) if err = cmd.Run(); err != nil { return fmt.Errorf("Run: %v - %s", err, stderr) diff --git a/modules/git/pipeline/lfs_nogogit.go b/modules/git/pipeline/lfs_nogogit.go index 4aa21dd05f..1352aa7662 100644 --- a/modules/git/pipeline/lfs_nogogit.go +++ b/modules/git/pipeline/lfs_nogogit.go @@ -63,7 +63,7 @@ func FindLFSFile(repo *git.Repository, hash git.SHA1) ([]*LFSResult, error) { // Next feed the commits in order into cat-file --batch, followed by their trees and sub trees as necessary. // so let's create a batch stdin and stdout - batchStdinWriter, batchReader, cancel := repo.CatFileBatch() + batchStdinWriter, batchReader, cancel := repo.CatFileBatch(repo.Ctx) defer cancel() // We'll use a scanner for the revList because it's simpler than a bufio.Reader diff --git a/modules/git/remote.go b/modules/git/remote.go index 7ba2b35a5e..5ed02300d4 100644 --- a/modules/git/remote.go +++ b/modules/git/remote.go @@ -4,19 +4,22 @@ package git -import "net/url" +import ( + "context" + "net/url" +) // GetRemoteAddress returns the url of a specific remote of the repository. -func GetRemoteAddress(repoPath, remoteName string) (*url.URL, error) { +func GetRemoteAddress(ctx context.Context, repoPath, remoteName string) (*url.URL, error) { err := LoadGitVersion() if err != nil { return nil, err } var cmd *Command if CheckGitVersionAtLeast("2.7") == nil { - cmd = NewCommand("remote", "get-url", remoteName) + cmd = NewCommandContext(ctx, "remote", "get-url", remoteName) } else { - cmd = NewCommand("config", "--get", "remote."+remoteName+".url") + cmd = NewCommandContext(ctx, "config", "--get", "remote."+remoteName+".url") } result, err := cmd.RunInDir(repoPath) diff --git a/modules/git/repo.go b/modules/git/repo.go index 89af7aa9e1..3ff2b6fe2d 100644 --- a/modules/git/repo.go +++ b/modules/git/repo.go @@ -211,8 +211,8 @@ type PushOptions struct { } // Push pushs local commits to given remote branch. -func Push(repoPath string, opts PushOptions) error { - cmd := NewCommand("push") +func Push(ctx context.Context, repoPath string, opts PushOptions) error { + cmd := NewCommandContext(ctx, "push") if opts.Force { cmd.AddArguments("-f") } diff --git a/modules/git/repo_attribute.go b/modules/git/repo_attribute.go index 88fb7810a6..0bb550bb4b 100644 --- a/modules/git/repo_attribute.go +++ b/modules/git/repo_attribute.go @@ -74,7 +74,7 @@ func (repo *Repository) CheckAttribute(opts CheckAttributeOpts) (map[string]map[ } } - cmd := NewCommand(cmdArgs...) + cmd := NewCommandContext(repo.Ctx, cmdArgs...) if err := cmd.RunInDirTimeoutEnvPipeline(env, -1, repo.Path, stdOut, stdErr); err != nil { return nil, fmt.Errorf("failed to run check-attr: %v\n%s\n%s", err, stdOut.String(), stdErr.String()) diff --git a/modules/git/repo_base_gogit.go b/modules/git/repo_base_gogit.go index afa5383b11..7299526562 100644 --- a/modules/git/repo_base_gogit.go +++ b/modules/git/repo_base_gogit.go @@ -9,6 +9,7 @@ package git import ( + "context" "errors" "path/filepath" @@ -30,10 +31,17 @@ type Repository struct { gogitRepo *gogit.Repository gogitStorage *filesystem.Storage gpgSettings *GPGSettings + + Ctx context.Context } // OpenRepository opens the repository at the given path. func OpenRepository(repoPath string) (*Repository, error) { + return OpenRepositoryCtx(DefaultContext, repoPath) +} + +// OpenRepositoryCtx opens the repository at the given path within the context.Context +func OpenRepositoryCtx(ctx context.Context, repoPath string) (*Repository, error) { repoPath, err := filepath.Abs(repoPath) if err != nil { return nil, err @@ -60,6 +68,7 @@ func OpenRepository(repoPath string) (*Repository, error) { gogitRepo: gogitRepo, gogitStorage: storage, tagCache: newObjectCache(), + Ctx: ctx, }, nil } diff --git a/modules/git/repo_base_nogogit.go b/modules/git/repo_base_nogogit.go index 22c4dfdcb3..14a6cacb44 100644 --- a/modules/git/repo_base_nogogit.go +++ b/modules/git/repo_base_nogogit.go @@ -32,10 +32,17 @@ type Repository struct { checkCancel context.CancelFunc checkReader *bufio.Reader checkWriter WriteCloserError + + Ctx context.Context } // OpenRepository opens the repository at the given path. func OpenRepository(repoPath string) (*Repository, error) { + return OpenRepositoryCtx(DefaultContext, repoPath) +} + +// OpenRepositoryCtx opens the repository at the given path with the provided context. +func OpenRepositoryCtx(ctx context.Context, repoPath string) (*Repository, error) { repoPath, err := filepath.Abs(repoPath) if err != nil { return nil, err @@ -46,28 +53,29 @@ func OpenRepository(repoPath string) (*Repository, error) { repo := &Repository{ Path: repoPath, tagCache: newObjectCache(), + Ctx: ctx, } - repo.batchWriter, repo.batchReader, repo.batchCancel = CatFileBatch(repoPath) - repo.checkWriter, repo.checkReader, repo.checkCancel = CatFileBatchCheck(repo.Path) + repo.batchWriter, repo.batchReader, repo.batchCancel = CatFileBatch(ctx, repoPath) + repo.checkWriter, repo.checkReader, repo.checkCancel = CatFileBatchCheck(ctx, repo.Path) return repo, nil } // CatFileBatch obtains a CatFileBatch for this repository -func (repo *Repository) CatFileBatch() (WriteCloserError, *bufio.Reader, func()) { +func (repo *Repository) CatFileBatch(ctx context.Context) (WriteCloserError, *bufio.Reader, func()) { if repo.batchCancel == nil || repo.batchReader.Buffered() > 0 { log.Debug("Opening temporary cat file batch for: %s", repo.Path) - return CatFileBatch(repo.Path) + return CatFileBatch(ctx, repo.Path) } return repo.batchWriter, repo.batchReader, func() {} } // CatFileBatchCheck obtains a CatFileBatchCheck for this repository -func (repo *Repository) CatFileBatchCheck() (WriteCloserError, *bufio.Reader, func()) { +func (repo *Repository) CatFileBatchCheck(ctx context.Context) (WriteCloserError, *bufio.Reader, func()) { if repo.checkCancel == nil || repo.checkReader.Buffered() > 0 { log.Debug("Opening temporary cat file batch-check: %s", repo.Path) - return CatFileBatchCheck(repo.Path) + return CatFileBatchCheck(ctx, repo.Path) } return repo.checkWriter, repo.checkReader, func() {} } diff --git a/modules/git/repo_blame.go b/modules/git/repo_blame.go index 5c023554f1..4ca05e3ba4 100644 --- a/modules/git/repo_blame.go +++ b/modules/git/repo_blame.go @@ -8,12 +8,12 @@ import "fmt" // FileBlame return the Blame object of file func (repo *Repository) FileBlame(revision, path, file string) ([]byte, error) { - return NewCommand("blame", "--root", "--", file).RunInDirBytes(path) + return NewCommandContext(repo.Ctx, "blame", "--root", "--", file).RunInDirBytes(path) } // LineBlame returns the latest commit at the given line func (repo *Repository) LineBlame(revision, path, file string, line uint) (*Commit, error) { - res, err := NewCommand("blame", fmt.Sprintf("-L %d,%d", line, line), "-p", revision, "--", file).RunInDir(path) + res, err := NewCommandContext(repo.Ctx, "blame", fmt.Sprintf("-L %d,%d", line, line), "-p", revision, "--", file).RunInDir(path) if err != nil { return nil, err } diff --git a/modules/git/repo_branch.go b/modules/git/repo_branch.go index 96f692826e..98b1bc8ae7 100644 --- a/modules/git/repo_branch.go +++ b/modules/git/repo_branch.go @@ -6,6 +6,7 @@ package git import ( + "context" "fmt" "strings" ) @@ -22,14 +23,14 @@ const PullRequestPrefix = "refs/for/" // TODO: /refs/for-review for suggest change interface // IsReferenceExist returns true if given reference exists in the repository. -func IsReferenceExist(repoPath, name string) bool { - _, err := NewCommand("show-ref", "--verify", "--", name).RunInDir(repoPath) +func IsReferenceExist(ctx context.Context, repoPath, name string) bool { + _, err := NewCommandContext(ctx, "show-ref", "--verify", "--", name).RunInDir(repoPath) return err == nil } // IsBranchExist returns true if given branch exists in the repository. -func IsBranchExist(repoPath, name string) bool { - return IsReferenceExist(repoPath, BranchPrefix+name) +func IsBranchExist(ctx context.Context, repoPath, name string) bool { + return IsReferenceExist(ctx, repoPath, BranchPrefix+name) } // Branch represents a Git branch. @@ -45,7 +46,7 @@ func (repo *Repository) GetHEADBranch() (*Branch, error) { if repo == nil { return nil, fmt.Errorf("nil repo") } - stdout, err := NewCommand("symbolic-ref", "HEAD").RunInDir(repo.Path) + stdout, err := NewCommandContext(repo.Ctx, "symbolic-ref", "HEAD").RunInDir(repo.Path) if err != nil { return nil, err } @@ -64,13 +65,13 @@ func (repo *Repository) GetHEADBranch() (*Branch, error) { // SetDefaultBranch sets default branch of repository. func (repo *Repository) SetDefaultBranch(name string) error { - _, err := NewCommand("symbolic-ref", "HEAD", BranchPrefix+name).RunInDir(repo.Path) + _, err := NewCommandContext(repo.Ctx, "symbolic-ref", "HEAD", BranchPrefix+name).RunInDir(repo.Path) return err } // GetDefaultBranch gets default branch of repository. func (repo *Repository) GetDefaultBranch() (string, error) { - return NewCommand("symbolic-ref", "HEAD").RunInDir(repo.Path) + return NewCommandContext(repo.Ctx, "symbolic-ref", "HEAD").RunInDir(repo.Path) } // GetBranch returns a branch by it's name @@ -118,7 +119,7 @@ type DeleteBranchOptions struct { // DeleteBranch delete a branch by name on repository. func (repo *Repository) DeleteBranch(name string, opts DeleteBranchOptions) error { - cmd := NewCommand("branch") + cmd := NewCommandContext(repo.Ctx, "branch") if opts.Force { cmd.AddArguments("-D") @@ -134,7 +135,7 @@ func (repo *Repository) DeleteBranch(name string, opts DeleteBranchOptions) erro // CreateBranch create a new branch func (repo *Repository) CreateBranch(branch, oldbranchOrCommit string) error { - cmd := NewCommand("branch") + cmd := NewCommandContext(repo.Ctx, "branch") cmd.AddArguments("--", branch, oldbranchOrCommit) _, err := cmd.RunInDir(repo.Path) @@ -144,7 +145,7 @@ func (repo *Repository) CreateBranch(branch, oldbranchOrCommit string) error { // AddRemote adds a new remote to repository. func (repo *Repository) AddRemote(name, url string, fetch bool) error { - cmd := NewCommand("remote", "add") + cmd := NewCommandContext(repo.Ctx, "remote", "add") if fetch { cmd.AddArguments("-f") } @@ -156,7 +157,7 @@ func (repo *Repository) AddRemote(name, url string, fetch bool) error { // RemoveRemote removes a remote from repository. func (repo *Repository) RemoveRemote(name string) error { - _, err := NewCommand("remote", "rm", name).RunInDir(repo.Path) + _, err := NewCommandContext(repo.Ctx, "remote", "rm", name).RunInDir(repo.Path) return err } @@ -167,6 +168,6 @@ func (branch *Branch) GetCommit() (*Commit, error) { // RenameBranch rename a branch func (repo *Repository) RenameBranch(from, to string) error { - _, err := NewCommand("branch", "-m", from, to).RunInDir(repo.Path) + _, err := NewCommandContext(repo.Ctx, "branch", "-m", from, to).RunInDir(repo.Path) return err } diff --git a/modules/git/repo_branch_nogogit.go b/modules/git/repo_branch_nogogit.go index 666ca81c1e..1928c7515b 100644 --- a/modules/git/repo_branch_nogogit.go +++ b/modules/git/repo_branch_nogogit.go @@ -11,6 +11,7 @@ package git import ( "bufio" "bytes" + "context" "io" "strings" @@ -23,7 +24,7 @@ func (repo *Repository) IsObjectExist(name string) bool { return false } - wr, rd, cancel := repo.CatFileBatchCheck() + wr, rd, cancel := repo.CatFileBatchCheck(repo.Ctx) defer cancel() _, err := wr.Write([]byte(name + "\n")) if err != nil { @@ -40,7 +41,7 @@ func (repo *Repository) IsReferenceExist(name string) bool { return false } - wr, rd, cancel := repo.CatFileBatchCheck() + wr, rd, cancel := repo.CatFileBatchCheck(repo.Ctx) defer cancel() _, err := wr.Write([]byte(name + "\n")) if err != nil { @@ -63,11 +64,11 @@ func (repo *Repository) IsBranchExist(name string) bool { // GetBranches returns branches from the repository, skipping skip initial branches and // returning at most limit branches, or all branches if limit is 0. func (repo *Repository) GetBranches(skip, limit int) ([]string, int, error) { - return callShowRef(repo.Path, BranchPrefix, "--heads", skip, limit) + return callShowRef(repo.Ctx, repo.Path, BranchPrefix, "--heads", skip, limit) } // callShowRef return refs, if limit = 0 it will not limit -func callShowRef(repoPath, prefix, arg string, skip, limit int) (branchNames []string, countAll int, err error) { +func callShowRef(ctx context.Context, repoPath, prefix, arg string, skip, limit int) (branchNames []string, countAll int, err error) { stdoutReader, stdoutWriter := io.Pipe() defer func() { _ = stdoutReader.Close() @@ -76,7 +77,7 @@ func callShowRef(repoPath, prefix, arg string, skip, limit int) (branchNames []s go func() { stderrBuilder := &strings.Builder{} - err := NewCommand("show-ref", arg).RunInDirPipeline(repoPath, stdoutWriter, stderrBuilder) + err := NewCommandContext(ctx, "show-ref", arg).RunInDirPipeline(repoPath, stdoutWriter, stderrBuilder) if err != nil { if stderrBuilder.Len() == 0 { _ = stdoutWriter.Close() diff --git a/modules/git/repo_commit.go b/modules/git/repo_commit.go index 25060f56da..3afabac27b 100644 --- a/modules/git/repo_commit.go +++ b/modules/git/repo_commit.go @@ -58,7 +58,7 @@ func (repo *Repository) getCommitByPathWithID(id SHA1, relpath string) (*Commit, relpath = `\` + relpath } - stdout, err := NewCommand("log", "-1", prettyLogFormat, id.String(), "--", relpath).RunInDir(repo.Path) + stdout, err := NewCommandContext(repo.Ctx, "log", "-1", prettyLogFormat, id.String(), "--", relpath).RunInDir(repo.Path) if err != nil { return nil, err } @@ -73,7 +73,7 @@ func (repo *Repository) getCommitByPathWithID(id SHA1, relpath string) (*Commit, // GetCommitByPath returns the last commit of relative path. func (repo *Repository) GetCommitByPath(relpath string) (*Commit, error) { - stdout, err := NewCommand("log", "-1", prettyLogFormat, "--", relpath).RunInDirBytes(repo.Path) + stdout, err := NewCommandContext(repo.Ctx, "log", "-1", prettyLogFormat, "--", relpath).RunInDirBytes(repo.Path) if err != nil { return nil, err } @@ -86,7 +86,7 @@ func (repo *Repository) GetCommitByPath(relpath string) (*Commit, error) { } func (repo *Repository) commitsByRange(id SHA1, page, pageSize int) ([]*Commit, error) { - stdout, err := NewCommand("log", id.String(), "--skip="+strconv.Itoa((page-1)*pageSize), + stdout, err := NewCommandContext(repo.Ctx, "log", id.String(), "--skip="+strconv.Itoa((page-1)*pageSize), "--max-count="+strconv.Itoa(pageSize), prettyLogFormat).RunInDirBytes(repo.Path) if err != nil { @@ -97,7 +97,7 @@ func (repo *Repository) commitsByRange(id SHA1, page, pageSize int) ([]*Commit, func (repo *Repository) searchCommits(id SHA1, opts SearchCommitsOptions) ([]*Commit, error) { // create new git log command with limit of 100 commis - cmd := NewCommand("log", id.String(), "-100", prettyLogFormat) + cmd := NewCommandContext(repo.Ctx, "log", id.String(), "-100", prettyLogFormat) // ignore case args := []string{"-i"} @@ -155,7 +155,7 @@ func (repo *Repository) searchCommits(id SHA1, opts SearchCommitsOptions) ([]*Co // ignore anything below 4 characters as too unspecific if len(v) >= 4 { // create new git log command with 1 commit limit - hashCmd := NewCommand("log", "-1", prettyLogFormat) + hashCmd := NewCommandContext(repo.Ctx, "log", "-1", prettyLogFormat) // add previous arguments except for --grep and --all hashCmd.AddArguments(args...) // add keyword as <commit> @@ -176,7 +176,7 @@ func (repo *Repository) searchCommits(id SHA1, opts SearchCommitsOptions) ([]*Co } func (repo *Repository) getFilesChanged(id1, id2 string) ([]string, error) { - stdout, err := NewCommand("diff", "--name-only", id1, id2).RunInDirBytes(repo.Path) + stdout, err := NewCommandContext(repo.Ctx, "diff", "--name-only", id1, id2).RunInDirBytes(repo.Path) if err != nil { return nil, err } @@ -186,7 +186,7 @@ func (repo *Repository) getFilesChanged(id1, id2 string) ([]string, error) { // FileChangedBetweenCommits Returns true if the file changed between commit IDs id1 and id2 // You must ensure that id1 and id2 are valid commit ids. func (repo *Repository) FileChangedBetweenCommits(filename, id1, id2 string) (bool, error) { - stdout, err := NewCommand("diff", "--name-only", "-z", id1, id2, "--", filename).RunInDirBytes(repo.Path) + stdout, err := NewCommandContext(repo.Ctx, "diff", "--name-only", "-z", id1, id2, "--", filename).RunInDirBytes(repo.Path) if err != nil { return false, err } @@ -209,7 +209,7 @@ func (repo *Repository) CommitsByFileAndRange(revision, file string, page int) ( }() go func() { stderr := strings.Builder{} - err := NewCommand("log", revision, "--follow", + err := NewCommandContext(repo.Ctx, "log", revision, "--follow", "--max-count="+strconv.Itoa(setting.Git.CommitsRangeSize*page), prettyLogFormat, "--", file). RunInDirPipeline(repo.Path, stdoutWriter, &stderr) @@ -240,7 +240,7 @@ func (repo *Repository) CommitsByFileAndRange(revision, file string, page int) ( // CommitsByFileAndRangeNoFollow return the commits according revision file and the page func (repo *Repository) CommitsByFileAndRangeNoFollow(revision, file string, page int) ([]*Commit, error) { - stdout, err := NewCommand("log", revision, "--skip="+strconv.Itoa((page-1)*50), + stdout, err := NewCommandContext(repo.Ctx, "log", revision, "--skip="+strconv.Itoa((page-1)*50), "--max-count="+strconv.Itoa(setting.Git.CommitsRangeSize), prettyLogFormat, "--", file).RunInDirBytes(repo.Path) if err != nil { return nil, err @@ -250,11 +250,11 @@ func (repo *Repository) CommitsByFileAndRangeNoFollow(revision, file string, pag // FilesCountBetween return the number of files changed between two commits func (repo *Repository) FilesCountBetween(startCommitID, endCommitID string) (int, error) { - stdout, err := NewCommand("diff", "--name-only", startCommitID+"..."+endCommitID).RunInDir(repo.Path) + stdout, err := NewCommandContext(repo.Ctx, "diff", "--name-only", startCommitID+"..."+endCommitID).RunInDir(repo.Path) if err != nil && strings.Contains(err.Error(), "no merge base") { // 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... - stdout, err = NewCommand("diff", "--name-only", startCommitID, endCommitID).RunInDir(repo.Path) + stdout, err = NewCommandContext(repo.Ctx, "diff", "--name-only", startCommitID, endCommitID).RunInDir(repo.Path) } if err != nil { return 0, err @@ -268,13 +268,13 @@ func (repo *Repository) CommitsBetween(last *Commit, before *Commit) ([]*Commit, var stdout []byte var err error if before == nil { - stdout, err = NewCommand("rev-list", last.ID.String()).RunInDirBytes(repo.Path) + stdout, err = NewCommandContext(repo.Ctx, "rev-list", last.ID.String()).RunInDirBytes(repo.Path) } else { - stdout, err = NewCommand("rev-list", before.ID.String()+".."+last.ID.String()).RunInDirBytes(repo.Path) + stdout, err = NewCommandContext(repo.Ctx, "rev-list", before.ID.String()+".."+last.ID.String()).RunInDirBytes(repo.Path) 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. // previously it would return the results of git rev-list before last so let's try that... - stdout, err = NewCommand("rev-list", before.ID.String(), last.ID.String()).RunInDirBytes(repo.Path) + stdout, err = NewCommandContext(repo.Ctx, "rev-list", before.ID.String(), last.ID.String()).RunInDirBytes(repo.Path) } } if err != nil { @@ -288,13 +288,13 @@ func (repo *Repository) CommitsBetweenLimit(last *Commit, before *Commit, limit, var stdout []byte var err error if before == nil { - stdout, err = NewCommand("rev-list", "--max-count", strconv.Itoa(limit), "--skip", strconv.Itoa(skip), last.ID.String()).RunInDirBytes(repo.Path) + stdout, err = NewCommandContext(repo.Ctx, "rev-list", "--max-count", strconv.Itoa(limit), "--skip", strconv.Itoa(skip), last.ID.String()).RunInDirBytes(repo.Path) } else { - stdout, err = NewCommand("rev-list", "--max-count", strconv.Itoa(limit), "--skip", strconv.Itoa(skip), before.ID.String()+".."+last.ID.String()).RunInDirBytes(repo.Path) + stdout, err = NewCommandContext(repo.Ctx, "rev-list", "--max-count", strconv.Itoa(limit), "--skip", strconv.Itoa(skip), before.ID.String()+".."+last.ID.String()).RunInDirBytes(repo.Path) 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. // previously it would return the results of git rev-list --max-count n before last so let's try that... - stdout, err = NewCommand("rev-list", "--max-count", strconv.Itoa(limit), "--skip", strconv.Itoa(skip), before.ID.String(), last.ID.String()).RunInDirBytes(repo.Path) + stdout, err = NewCommandContext(repo.Ctx, "rev-list", "--max-count", strconv.Itoa(limit), "--skip", strconv.Itoa(skip), before.ID.String(), last.ID.String()).RunInDirBytes(repo.Path) } } if err != nil { @@ -333,7 +333,7 @@ func (repo *Repository) CommitsCountBetween(start, end string) (int64, error) { // commitsBefore the limit is depth, not total number of returned commits. func (repo *Repository) commitsBefore(id SHA1, limit int) ([]*Commit, error) { - cmd := NewCommand("log") + cmd := NewCommandContext(repo.Ctx, "log") if limit > 0 { cmd.AddArguments("-"+strconv.Itoa(limit), prettyLogFormat, id.String()) } else { @@ -377,7 +377,7 @@ func (repo *Repository) getCommitsBeforeLimit(id SHA1, num int) ([]*Commit, erro func (repo *Repository) getBranches(commit *Commit, limit int) ([]string, error) { if CheckGitVersionAtLeast("2.7.0") == nil { - stdout, err := NewCommand("for-each-ref", "--count="+strconv.Itoa(limit), "--format=%(refname:strip=2)", "--contains", commit.ID.String(), BranchPrefix).RunInDir(repo.Path) + stdout, err := NewCommandContext(repo.Ctx, "for-each-ref", "--count="+strconv.Itoa(limit), "--format=%(refname:strip=2)", "--contains", commit.ID.String(), BranchPrefix).RunInDir(repo.Path) if err != nil { return nil, err } @@ -386,7 +386,7 @@ func (repo *Repository) getBranches(commit *Commit, limit int) ([]string, error) return branches, nil } - stdout, err := NewCommand("branch", "--contains", commit.ID.String()).RunInDir(repo.Path) + stdout, err := NewCommandContext(repo.Ctx, "branch", "--contains", commit.ID.String()).RunInDir(repo.Path) if err != nil { return nil, err } @@ -425,7 +425,7 @@ func (repo *Repository) GetCommitsFromIDs(commitIDs []string) []*Commit { // IsCommitInBranch check if the commit is on the branch func (repo *Repository) IsCommitInBranch(commitID, branch string) (r bool, err error) { - stdout, err := NewCommand("branch", "--contains", commitID, branch).RunInDir(repo.Path) + stdout, err := NewCommandContext(repo.Ctx, "branch", "--contains", commitID, branch).RunInDir(repo.Path) if err != nil { return false, err } diff --git a/modules/git/repo_commit_gogit.go b/modules/git/repo_commit_gogit.go index 175b6e6446..f00b340d15 100644 --- a/modules/git/repo_commit_gogit.go +++ b/modules/git/repo_commit_gogit.go @@ -40,7 +40,7 @@ func (repo *Repository) ConvertToSHA1(commitID string) (SHA1, error) { } } - actualCommitID, err := NewCommand("rev-parse", "--verify", commitID).RunInDir(repo.Path) + actualCommitID, err := NewCommandContext(repo.Ctx, "rev-parse", "--verify", commitID).RunInDir(repo.Path) if err != nil { if strings.Contains(err.Error(), "unknown revision or path") || strings.Contains(err.Error(), "fatal: Needed a single revision") { diff --git a/modules/git/repo_commit_nogogit.go b/modules/git/repo_commit_nogogit.go index 8bfc953759..d86e7d3268 100644 --- a/modules/git/repo_commit_nogogit.go +++ b/modules/git/repo_commit_nogogit.go @@ -18,7 +18,7 @@ import ( // ResolveReference resolves a name to a reference func (repo *Repository) ResolveReference(name string) (string, error) { - stdout, err := NewCommand("show-ref", "--hash", name).RunInDir(repo.Path) + stdout, err := NewCommandContext(repo.Ctx, "show-ref", "--hash", name).RunInDir(repo.Path) if err != nil { if strings.Contains(err.Error(), "not a valid ref") { return "", ErrNotExist{name, ""} @@ -35,7 +35,7 @@ func (repo *Repository) ResolveReference(name string) (string, error) { // GetRefCommitID returns the last commit ID string of given reference (branch or tag). func (repo *Repository) GetRefCommitID(name string) (string, error) { - wr, rd, cancel := repo.CatFileBatchCheck() + wr, rd, cancel := repo.CatFileBatchCheck(repo.Ctx) defer cancel() _, _ = wr.Write([]byte(name + "\n")) shaBs, _, _, err := ReadBatchLine(rd) @@ -48,12 +48,12 @@ func (repo *Repository) GetRefCommitID(name string) (string, error) { // IsCommitExist returns true if given commit exists in current repository. func (repo *Repository) IsCommitExist(name string) bool { - _, err := NewCommand("cat-file", "-e", name).RunInDir(repo.Path) + _, err := NewCommandContext(repo.Ctx, "cat-file", "-e", name).RunInDir(repo.Path) return err == nil } func (repo *Repository) getCommit(id SHA1) (*Commit, error) { - wr, rd, cancel := repo.CatFileBatch() + wr, rd, cancel := repo.CatFileBatch(repo.Ctx) defer cancel() _, _ = wr.Write([]byte(id.String() + "\n")) @@ -132,7 +132,7 @@ func (repo *Repository) ConvertToSHA1(commitID string) (SHA1, error) { } } - wr, rd, cancel := repo.CatFileBatchCheck() + wr, rd, cancel := repo.CatFileBatchCheck(repo.Ctx) defer cancel() _, err := wr.Write([]byte(commitID + "\n")) if err != nil { diff --git a/modules/git/repo_compare.go b/modules/git/repo_compare.go index 019c9bc806..303bb5bc03 100644 --- a/modules/git/repo_compare.go +++ b/modules/git/repo_compare.go @@ -35,13 +35,13 @@ func (repo *Repository) GetMergeBase(tmpRemote string, base, head string) (strin if tmpRemote != "origin" { tmpBaseName := "refs/remotes/" + tmpRemote + "/tmp_" + base // Fetch commit into a temporary branch in order to be able to handle commits and tags - _, err := NewCommand("fetch", tmpRemote, base+":"+tmpBaseName).RunInDir(repo.Path) + _, err := NewCommandContext(repo.Ctx, "fetch", tmpRemote, base+":"+tmpBaseName).RunInDir(repo.Path) if err == nil { base = tmpBaseName } } - stdout, err := NewCommand("merge-base", "--", base, head).RunInDir(repo.Path) + stdout, err := NewCommandContext(repo.Ctx, "merge-base", "--", base, head).RunInDir(repo.Path) return strings.TrimSpace(stdout), base, err } @@ -88,7 +88,7 @@ func (repo *Repository) GetCompareInfo(basePath, baseBranch, headBranch string, // We have a common base - therefore we know that ... should work if !fileOnly { - logs, err := NewCommand("log", baseCommitID+separator+headBranch, prettyLogFormat).RunInDirBytes(repo.Path) + logs, err := NewCommandContext(repo.Ctx, "log", baseCommitID+separator+headBranch, prettyLogFormat).RunInDirBytes(repo.Path) if err != nil { return nil, err } @@ -141,14 +141,14 @@ func (repo *Repository) GetDiffNumChangedFiles(base, head string, directComparis separator = ".." } - if err := NewCommand("diff", "-z", "--name-only", base+separator+head). + if err := NewCommandContext(repo.Ctx, "diff", "-z", "--name-only", base+separator+head). RunInDirPipeline(repo.Path, w, stderr); err != nil { if strings.Contains(stderr.String(), "no merge base") { // 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... w = &lineCountWriter{} stderr.Reset() - if err = NewCommand("diff", "-z", "--name-only", base, head).RunInDirPipeline(repo.Path, w, stderr); err == nil { + if err = NewCommandContext(repo.Ctx, "diff", "-z", "--name-only", base, head).RunInDirPipeline(repo.Path, w, stderr); err == nil { return w.numLines, nil } } @@ -231,23 +231,23 @@ func (repo *Repository) GetDiffOrPatch(base, head string, w io.Writer, patch, bi // GetDiff generates and returns patch data between given revisions, optimized for human readability func (repo *Repository) GetDiff(base, head string, w io.Writer) error { - return NewCommand("diff", "-p", base, head). + return NewCommandContext(repo.Ctx, "diff", "-p", base, head). RunInDirPipeline(repo.Path, w, nil) } // GetDiffBinary generates and returns patch data between given revisions, including binary diffs. func (repo *Repository) GetDiffBinary(base, head string, w io.Writer) error { - return NewCommand("diff", "-p", "--binary", base, head). + return NewCommandContext(repo.Ctx, "diff", "-p", "--binary", base, head). RunInDirPipeline(repo.Path, w, nil) } // GetPatch generates and returns format-patch data between given revisions, able to be used with `git apply` func (repo *Repository) GetPatch(base, head string, w io.Writer) error { stderr := new(bytes.Buffer) - err := NewCommand("format-patch", "--binary", "--stdout", base+"..."+head). + err := NewCommandContext(repo.Ctx, "format-patch", "--binary", "--stdout", base+"..."+head). RunInDirPipeline(repo.Path, w, stderr) if err != nil && bytes.Contains(stderr.Bytes(), []byte("no merge base")) { - return NewCommand("format-patch", "--binary", "--stdout", base, head). + return NewCommandContext(repo.Ctx, "format-patch", "--binary", "--stdout", base, head). RunInDirPipeline(repo.Path, w, nil) } return err @@ -256,7 +256,7 @@ func (repo *Repository) GetPatch(base, head string, w io.Writer) error { // GetDiffFromMergeBase generates and return patch data from merge base to head func (repo *Repository) GetDiffFromMergeBase(base, head string, w io.Writer) error { stderr := new(bytes.Buffer) - err := NewCommand("diff", "-p", "--binary", base+"..."+head). + err := NewCommandContext(repo.Ctx, "diff", "-p", "--binary", base+"..."+head). RunInDirPipeline(repo.Path, w, stderr) if err != nil && bytes.Contains(stderr.Bytes(), []byte("no merge base")) { return repo.GetDiffBinary(base, head, w) diff --git a/modules/git/repo_gpg.go b/modules/git/repo_gpg.go index b4c3f3b431..addf6a6b62 100644 --- a/modules/git/repo_gpg.go +++ b/modules/git/repo_gpg.go @@ -34,7 +34,7 @@ func (repo *Repository) GetDefaultPublicGPGKey(forceUpdate bool) (*GPGSettings, Sign: true, } - value, _ := NewCommand("config", "--get", "commit.gpgsign").RunInDir(repo.Path) + value, _ := NewCommandContext(repo.Ctx, "config", "--get", "commit.gpgsign").RunInDir(repo.Path) sign, valid := ParseBool(strings.TrimSpace(value)) if !sign || !valid { gpgSettings.Sign = false @@ -42,13 +42,13 @@ func (repo *Repository) GetDefaultPublicGPGKey(forceUpdate bool) (*GPGSettings, return gpgSettings, nil } - signingKey, _ := NewCommand("config", "--get", "user.signingkey").RunInDir(repo.Path) + signingKey, _ := NewCommandContext(repo.Ctx, "config", "--get", "user.signingkey").RunInDir(repo.Path) gpgSettings.KeyID = strings.TrimSpace(signingKey) - defaultEmail, _ := NewCommand("config", "--get", "user.email").RunInDir(repo.Path) + defaultEmail, _ := NewCommandContext(repo.Ctx, "config", "--get", "user.email").RunInDir(repo.Path) gpgSettings.Email = strings.TrimSpace(defaultEmail) - defaultName, _ := NewCommand("config", "--get", "user.name").RunInDir(repo.Path) + defaultName, _ := NewCommandContext(repo.Ctx, "config", "--get", "user.name").RunInDir(repo.Path) gpgSettings.Name = strings.TrimSpace(defaultName) if err := gpgSettings.LoadPublicKeyContent(); err != nil { diff --git a/modules/git/repo_index.go b/modules/git/repo_index.go index 38c01295b6..f5533b25e7 100644 --- a/modules/git/repo_index.go +++ b/modules/git/repo_index.go @@ -18,7 +18,7 @@ import ( // ReadTreeToIndex reads a treeish to the index func (repo *Repository) ReadTreeToIndex(treeish string, indexFilename ...string) error { if len(treeish) != 40 { - res, err := NewCommand("rev-parse", "--verify", treeish).RunInDir(repo.Path) + res, err := NewCommandContext(repo.Ctx, "rev-parse", "--verify", treeish).RunInDir(repo.Path) if err != nil { return err } @@ -38,7 +38,7 @@ func (repo *Repository) readTreeToIndex(id SHA1, indexFilename ...string) error if len(indexFilename) > 0 { env = append(os.Environ(), "GIT_INDEX_FILE="+indexFilename[0]) } - _, err := NewCommand("read-tree", id.String()).RunInDirWithEnv(repo.Path, env) + _, err := NewCommandContext(repo.Ctx, "read-tree", id.String()).RunInDirWithEnv(repo.Path, env) if err != nil { return err } @@ -69,13 +69,13 @@ func (repo *Repository) ReadTreeToTemporaryIndex(treeish string) (filename, tmpD // EmptyIndex empties the index func (repo *Repository) EmptyIndex() error { - _, err := NewCommand("read-tree", "--empty").RunInDir(repo.Path) + _, err := NewCommandContext(repo.Ctx, "read-tree", "--empty").RunInDir(repo.Path) return err } // LsFiles checks if the given filenames are in the index func (repo *Repository) LsFiles(filenames ...string) ([]string, error) { - cmd := NewCommand("ls-files", "-z", "--") + cmd := NewCommandContext(repo.Ctx, "ls-files", "-z", "--") for _, arg := range filenames { if arg != "" { cmd.AddArguments(arg) @@ -95,7 +95,7 @@ func (repo *Repository) LsFiles(filenames ...string) ([]string, error) { // RemoveFilesFromIndex removes given filenames from the index - it does not check whether they are present. func (repo *Repository) RemoveFilesFromIndex(filenames ...string) error { - cmd := NewCommand("update-index", "--remove", "-z", "--index-info") + cmd := NewCommandContext(repo.Ctx, "update-index", "--remove", "-z", "--index-info") stdout := new(bytes.Buffer) stderr := new(bytes.Buffer) buffer := new(bytes.Buffer) @@ -111,14 +111,14 @@ func (repo *Repository) RemoveFilesFromIndex(filenames ...string) error { // AddObjectToIndex adds the provided object hash to the index at the provided filename func (repo *Repository) AddObjectToIndex(mode string, object SHA1, filename string) error { - cmd := NewCommand("update-index", "--add", "--replace", "--cacheinfo", mode, object.String(), filename) + cmd := NewCommandContext(repo.Ctx, "update-index", "--add", "--replace", "--cacheinfo", mode, object.String(), filename) _, err := cmd.RunInDir(repo.Path) return err } // WriteTree writes the current index as a tree to the object db and returns its hash func (repo *Repository) WriteTree() (*Tree, error) { - res, err := NewCommand("write-tree").RunInDir(repo.Path) + res, err := NewCommandContext(repo.Ctx, "write-tree").RunInDir(repo.Path) if err != nil { return nil, err } diff --git a/modules/git/repo_language_stats_nogogit.go b/modules/git/repo_language_stats_nogogit.go index 4fda7ab627..0b21bf6344 100644 --- a/modules/git/repo_language_stats_nogogit.go +++ b/modules/git/repo_language_stats_nogogit.go @@ -25,7 +25,7 @@ import ( func (repo *Repository) GetLanguageStats(commitID string) (map[string]int64, error) { // We will feed the commit IDs in order into cat-file --batch, followed by blobs as necessary. // so let's create a batch stdin and stdout - batchStdinWriter, batchReader, cancel := repo.CatFileBatch() + batchStdinWriter, batchReader, cancel := repo.CatFileBatch(repo.Ctx) defer cancel() writeID := func(id string) error { @@ -76,7 +76,7 @@ func (repo *Repository) GetLanguageStats(commitID string) (map[string]int64, err IndexFile: indexFilename, WorkTree: worktree, } - ctx, cancel := context.WithCancel(DefaultContext) + ctx, cancel := context.WithCancel(repo.Ctx) if err := checker.Init(ctx); err != nil { log.Error("Unable to open checker for %s. Error: %v", commitID, err) } else { @@ -96,6 +96,12 @@ func (repo *Repository) GetLanguageStats(commitID string) (map[string]int64, err var content []byte sizes := make(map[string]int64) for _, f := range entries { + select { + case <-repo.Ctx.Done(): + return sizes, repo.Ctx.Err() + default: + } + contentBuf.Reset() content = contentBuf.Bytes() diff --git a/modules/git/repo_object.go b/modules/git/repo_object.go index f054c34902..3921e6a1d4 100644 --- a/modules/git/repo_object.go +++ b/modules/git/repo_object.go @@ -42,7 +42,7 @@ func (repo *Repository) HashObject(reader io.Reader) (SHA1, error) { } func (repo *Repository) hashObject(reader io.Reader) (string, error) { - cmd := NewCommand("hash-object", "-w", "--stdin") + cmd := NewCommandContext(repo.Ctx, "hash-object", "-w", "--stdin") stdout := new(bytes.Buffer) stderr := new(bytes.Buffer) err := cmd.RunInDirFullPipeline(repo.Path, stdout, stderr, reader) diff --git a/modules/git/repo_ref_nogogit.go b/modules/git/repo_ref_nogogit.go index ec0c5ec4ca..790b717d38 100644 --- a/modules/git/repo_ref_nogogit.go +++ b/modules/git/repo_ref_nogogit.go @@ -23,7 +23,7 @@ func (repo *Repository) GetRefsFiltered(pattern string) ([]*Reference, error) { go func() { stderrBuilder := &strings.Builder{} - err := NewCommand("for-each-ref").RunInDirPipeline(repo.Path, stdoutWriter, stderrBuilder) + err := NewCommandContext(repo.Ctx, "for-each-ref").RunInDirPipeline(repo.Path, stdoutWriter, stderrBuilder) if err != nil { _ = stdoutWriter.CloseWithError(ConcatenateError(err, stderrBuilder.String())) } else { diff --git a/modules/git/repo_stats.go b/modules/git/repo_stats.go index aca5ab21cc..caf2caabcc 100644 --- a/modules/git/repo_stats.go +++ b/modules/git/repo_stats.go @@ -39,7 +39,7 @@ func (repo *Repository) GetCodeActivityStats(fromTime time.Time, branch string) since := fromTime.Format(time.RFC3339) - stdout, err := NewCommand("rev-list", "--count", "--no-merges", "--branches=*", "--date=iso", fmt.Sprintf("--since='%s'", since)).RunInDirBytes(repo.Path) + stdout, err := NewCommandContext(repo.Ctx, "rev-list", "--count", "--no-merges", "--branches=*", "--date=iso", fmt.Sprintf("--since='%s'", since)).RunInDirBytes(repo.Path) if err != nil { return nil, err } @@ -67,7 +67,7 @@ func (repo *Repository) GetCodeActivityStats(fromTime time.Time, branch string) } stderr := new(strings.Builder) - err = NewCommand(args...).RunInDirTimeoutEnvFullPipelineFunc( + err = NewCommandContext(repo.Ctx, args...).RunInDirTimeoutEnvFullPipelineFunc( nil, -1, repo.Path, stdoutWriter, stderr, nil, func(ctx context.Context, cancel context.CancelFunc) error { diff --git a/modules/git/repo_tag.go b/modules/git/repo_tag.go index 44d7a048bc..4262e0804f 100644 --- a/modules/git/repo_tag.go +++ b/modules/git/repo_tag.go @@ -6,6 +6,7 @@ package git import ( + "context" "fmt" "strings" @@ -17,19 +18,19 @@ import ( const TagPrefix = "refs/tags/" // IsTagExist returns true if given tag exists in the repository. -func IsTagExist(repoPath, name string) bool { - return IsReferenceExist(repoPath, TagPrefix+name) +func IsTagExist(ctx context.Context, repoPath, name string) bool { + return IsReferenceExist(ctx, repoPath, TagPrefix+name) } // CreateTag create one tag in the repository func (repo *Repository) CreateTag(name, revision string) error { - _, err := NewCommand("tag", "--", name, revision).RunInDir(repo.Path) + _, err := NewCommandContext(repo.Ctx, "tag", "--", name, revision).RunInDir(repo.Path) return err } // CreateAnnotatedTag create one annotated tag in the repository func (repo *Repository) CreateAnnotatedTag(name, message, revision string) error { - _, err := NewCommand("tag", "-a", "-m", message, "--", name, revision).RunInDir(repo.Path) + _, err := NewCommandContext(repo.Ctx, "tag", "-a", "-m", message, "--", name, revision).RunInDir(repo.Path) return err } @@ -79,7 +80,7 @@ func (repo *Repository) getTag(tagID SHA1, name string) (*Tag, error) { } // The tag is an annotated tag with a message. - data, err := NewCommand("cat-file", "-p", tagID.String()).RunInDirBytes(repo.Path) + data, err := NewCommandContext(repo.Ctx, "cat-file", "-p", tagID.String()).RunInDirBytes(repo.Path) if err != nil { return nil, err } @@ -104,7 +105,7 @@ func (repo *Repository) GetTagNameBySHA(sha string) (string, error) { return "", fmt.Errorf("SHA is too short: %s", sha) } - stdout, err := NewCommand("show-ref", "--tags", "-d").RunInDir(repo.Path) + stdout, err := NewCommandContext(repo.Ctx, "show-ref", "--tags", "-d").RunInDir(repo.Path) if err != nil { return "", err } @@ -127,7 +128,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) func (repo *Repository) GetTagID(name string) (string, error) { - stdout, err := NewCommand("show-ref", "--tags", "--", name).RunInDir(repo.Path) + stdout, err := NewCommandContext(repo.Ctx, "show-ref", "--tags", "--", name).RunInDir(repo.Path) if err != nil { return "", err } @@ -163,7 +164,7 @@ func (repo *Repository) GetTag(name string) (*Tag, error) { // GetTagInfos returns all tag infos of the repository. func (repo *Repository) GetTagInfos(page, pageSize int) ([]*Tag, int, error) { // TODO this a slow implementation, makes one git command per tag - stdout, err := NewCommand("tag").RunInDir(repo.Path) + stdout, err := NewCommandContext(repo.Ctx, "tag").RunInDir(repo.Path) if err != nil { return nil, 0, err } @@ -196,7 +197,7 @@ func (repo *Repository) GetTagInfos(page, pageSize int) ([]*Tag, int, error) { // GetTagType gets the type of the tag, either commit (simple) or tag (annotated) func (repo *Repository) GetTagType(id SHA1) (string, error) { // Get tag type - stdout, err := NewCommand("cat-file", "-t", id.String()).RunInDir(repo.Path) + stdout, err := NewCommandContext(repo.Ctx, "cat-file", "-t", id.String()).RunInDir(repo.Path) if err != nil { return "", err } diff --git a/modules/git/repo_tag_nogogit.go b/modules/git/repo_tag_nogogit.go index 172b6fd66c..1a23755aa6 100644 --- a/modules/git/repo_tag_nogogit.go +++ b/modules/git/repo_tag_nogogit.go @@ -20,6 +20,6 @@ func (repo *Repository) IsTagExist(name string) bool { // GetTags returns all tags of the repository. // returning at most limit tags, or all if limit is 0. func (repo *Repository) GetTags(skip, limit int) (tags []string, err error) { - tags, _, err = callShowRef(repo.Path, TagPrefix, "--tags", skip, limit) + tags, _, err = callShowRef(repo.Ctx, repo.Path, TagPrefix, "--tags", skip, limit) return } diff --git a/modules/git/repo_tree.go b/modules/git/repo_tree.go index 2053b6a1de..f57c26ffee 100644 --- a/modules/git/repo_tree.go +++ b/modules/git/repo_tree.go @@ -40,7 +40,7 @@ func (repo *Repository) CommitTree(author *Signature, committer *Signature, tree "GIT_COMMITTER_EMAIL="+committer.Email, "GIT_COMMITTER_DATE="+commitTimeStr, ) - cmd := NewCommand("commit-tree", tree.ID.String()) + cmd := NewCommandContext(repo.Ctx, "commit-tree", tree.ID.String()) for _, parent := range opts.Parents { cmd.AddArguments("-p", parent) diff --git a/modules/git/repo_tree_gogit.go b/modules/git/repo_tree_gogit.go index 2ddffcf79b..5a90cbe802 100644 --- a/modules/git/repo_tree_gogit.go +++ b/modules/git/repo_tree_gogit.go @@ -22,7 +22,7 @@ func (repo *Repository) getTree(id SHA1) (*Tree, error) { // GetTree find the tree object in the repository. func (repo *Repository) GetTree(idStr string) (*Tree, error) { if len(idStr) != 40 { - res, err := NewCommand("rev-parse", "--verify", idStr).RunInDir(repo.Path) + res, err := NewCommandContext(repo.Ctx, "rev-parse", "--verify", idStr).RunInDir(repo.Path) if err != nil { return nil, err } diff --git a/modules/git/repo_tree_nogogit.go b/modules/git/repo_tree_nogogit.go index b27abb6e02..56a4a732e0 100644 --- a/modules/git/repo_tree_nogogit.go +++ b/modules/git/repo_tree_nogogit.go @@ -12,7 +12,7 @@ import ( ) func (repo *Repository) getTree(id SHA1) (*Tree, error) { - wr, rd, cancel := repo.CatFileBatch() + wr, rd, cancel := repo.CatFileBatch(repo.Ctx) defer cancel() _, _ = wr.Write([]byte(id.String() + "\n")) diff --git a/modules/git/tree_nogogit.go b/modules/git/tree_nogogit.go index 3d3fd26ece..cfa2291e8f 100644 --- a/modules/git/tree_nogogit.go +++ b/modules/git/tree_nogogit.go @@ -36,7 +36,7 @@ func (t *Tree) ListEntries() (Entries, error) { } if t.repo != nil { - wr, rd, cancel := t.repo.CatFileBatch() + wr, rd, cancel := t.repo.CatFileBatch(t.repo.Ctx) defer cancel() _, _ = wr.Write([]byte(t.ID.String() + "\n")) |