diff options
author | Lunny Xiao <xiaolunwen@gmail.com> | 2019-06-27 02:15:26 +0800 |
---|---|---|
committer | techknowlogick <techknowlogick@gitea.io> | 2019-06-26 14:15:26 -0400 |
commit | edc94c70413048107ea728ff330f32ca3de6df88 (patch) | |
tree | cf5bcc5ba8ee4b2e585dc14a6cf7440ce88bc073 /models | |
parent | 161e12e157a48f9bcd2de50c187c77444aa2a9a8 (diff) | |
download | gitea-edc94c70413048107ea728ff330f32ca3de6df88.tar.gz gitea-edc94c70413048107ea728ff330f32ca3de6df88.zip |
Monitor all git commands; move blame to git package and replace git as a variable (#6864)
* monitor all git commands; move blame to git package and replace git as a variable
* use git command but not other commands
* fix build
* move exec.Command to git.NewCommand
* fix fmt
* remove unrelated changes
* remove unrelated changes
* refactor IsEmpty and add tests
* fix tests
* fix tests
* fix tests
* fix tests
* remove gitLogger
* fix fmt
* fix isEmpty
* fix lint
* fix tests
Diffstat (limited to 'models')
-rw-r--r-- | models/git_blame.go | 124 | ||||
-rw-r--r-- | models/git_blame_test.go | 141 | ||||
-rw-r--r-- | models/git_diff.go | 16 | ||||
-rw-r--r-- | models/pull.go | 8 | ||||
-rw-r--r-- | models/release.go | 2 | ||||
-rw-r--r-- | models/repo.go | 34 | ||||
-rw-r--r-- | models/repo_mirror.go | 4 | ||||
-rw-r--r-- | models/update.go | 6 |
8 files changed, 32 insertions, 303 deletions
diff --git a/models/git_blame.go b/models/git_blame.go deleted file mode 100644 index 2b439a23b9..0000000000 --- a/models/git_blame.go +++ /dev/null @@ -1,124 +0,0 @@ -// Copyright 2019 The Gitea Authors. All rights reserved. -// Use of this source code is governed by a MIT-style -// license that can be found in the LICENSE file. - -package models - -import ( - "bufio" - "fmt" - "io" - "os" - "os/exec" - "regexp" - - "code.gitea.io/gitea/modules/git" - "code.gitea.io/gitea/modules/process" -) - -// BlamePart represents block of blame - continuous lines with one sha -type BlamePart struct { - Sha string - Lines []string -} - -// BlameReader returns part of file blame one by one -type BlameReader struct { - cmd *exec.Cmd - pid int64 - output io.ReadCloser - scanner *bufio.Scanner - lastSha *string -} - -var shaLineRegex = regexp.MustCompile("^([a-z0-9]{40})") - -// NextPart returns next part of blame (sequencial code lines with the same commit) -func (r *BlameReader) NextPart() (*BlamePart, error) { - var blamePart *BlamePart - - scanner := r.scanner - - if r.lastSha != nil { - blamePart = &BlamePart{*r.lastSha, make([]string, 0)} - } - - for scanner.Scan() { - line := scanner.Text() - - // Skip empty lines - if len(line) == 0 { - continue - } - - lines := shaLineRegex.FindStringSubmatch(line) - if lines != nil { - sha1 := lines[1] - - if blamePart == nil { - blamePart = &BlamePart{sha1, make([]string, 0)} - } - - if blamePart.Sha != sha1 { - r.lastSha = &sha1 - return blamePart, nil - } - } else if line[0] == '\t' { - code := line[1:] - - blamePart.Lines = append(blamePart.Lines, code) - } - } - - r.lastSha = nil - - return blamePart, nil -} - -// Close BlameReader - don't run NextPart after invoking that -func (r *BlameReader) Close() error { - process.GetManager().Remove(r.pid) - - if err := r.cmd.Wait(); err != nil { - return fmt.Errorf("Wait: %v", err) - } - - return nil -} - -// CreateBlameReader creates reader for given repository, commit and file -func CreateBlameReader(repoPath, commitID, file string) (*BlameReader, error) { - _, err := git.OpenRepository(repoPath) - if err != nil { - return nil, err - } - - return createBlameReader(repoPath, "git", "blame", commitID, "--porcelain", "--", file) -} - -func createBlameReader(dir string, command ...string) (*BlameReader, error) { - cmd := exec.Command(command[0], command[1:]...) - cmd.Dir = dir - cmd.Stderr = os.Stderr - - stdout, err := cmd.StdoutPipe() - if err != nil { - return nil, fmt.Errorf("StdoutPipe: %v", err) - } - - if err = cmd.Start(); err != nil { - return nil, fmt.Errorf("Start: %v", err) - } - - pid := process.GetManager().Add(fmt.Sprintf("GetBlame [repo_path: %s]", dir), cmd) - - scanner := bufio.NewScanner(stdout) - - return &BlameReader{ - cmd, - pid, - stdout, - scanner, - nil, - }, nil -} diff --git a/models/git_blame_test.go b/models/git_blame_test.go deleted file mode 100644 index eb0b35380b..0000000000 --- a/models/git_blame_test.go +++ /dev/null @@ -1,141 +0,0 @@ -// Copyright 2019 The Gitea Authors. All rights reserved. -// Use of this source code is governed by a MIT-style -// license that can be found in the LICENSE file. - -package models - -import ( - "io/ioutil" - "testing" - - "github.com/stretchr/testify/assert" -) - -const exampleBlame = ` -4b92a6c2df28054ad766bc262f308db9f6066596 1 1 1 -author Unknown -author-mail <joe2010xtmf@163.com> -author-time 1392833071 -author-tz -0500 -committer Unknown -committer-mail <joe2010xtmf@163.com> -committer-time 1392833071 -committer-tz -0500 -summary Add code of delete user -previous be0ba9ea88aff8a658d0495d36accf944b74888d gogs.go -filename gogs.go - // Copyright 2014 The Gogs Authors. All rights reserved. -ce21ed6c3490cdfad797319cbb1145e2330a8fef 2 2 1 -author Joubert RedRat -author-mail <eu+github@redrat.com.br> -author-time 1482322397 -author-tz -0200 -committer Lunny Xiao -committer-mail <xiaolunwen@gmail.com> -committer-time 1482322397 -committer-tz +0800 -summary Remove remaining Gogs reference on locales and cmd (#430) -previous 618407c018cdf668ceedde7454c42fb22ba422d8 main.go -filename main.go - // Copyright 2016 The Gitea Authors. All rights reserved. -4b92a6c2df28054ad766bc262f308db9f6066596 2 3 2 -author Unknown -author-mail <joe2010xtmf@163.com> -author-time 1392833071 -author-tz -0500 -committer Unknown -committer-mail <joe2010xtmf@163.com> -committer-time 1392833071 -committer-tz -0500 -summary Add code of delete user -previous be0ba9ea88aff8a658d0495d36accf944b74888d gogs.go -filename gogs.go - // Use of this source code is governed by a MIT-style -4b92a6c2df28054ad766bc262f308db9f6066596 3 4 -author Unknown -author-mail <joe2010xtmf@163.com> -author-time 1392833071 -author-tz -0500 -committer Unknown -committer-mail <joe2010xtmf@163.com> -committer-time 1392833071 -committer-tz -0500 -summary Add code of delete user -previous be0ba9ea88aff8a658d0495d36accf944b74888d gogs.go -filename gogs.go - // license that can be found in the LICENSE file. - -e2aa991e10ffd924a828ec149951f2f20eecead2 6 6 2 -author Lunny Xiao -author-mail <xiaolunwen@gmail.com> -author-time 1478872595 -author-tz +0800 -committer Sandro Santilli -committer-mail <strk@kbt.io> -committer-time 1478872595 -committer-tz +0100 -summary ask for go get from code.gitea.io/gitea and change gogs to gitea on main file (#146) -previous 5fc370e332171b8658caed771b48585576f11737 main.go -filename main.go - // Gitea (git with a cup of tea) is a painless self-hosted Git Service. -e2aa991e10ffd924a828ec149951f2f20eecead2 7 7 - package main // import "code.gitea.io/gitea" -` - -func TestReadingBlameOutput(t *testing.T) { - tempFile, err := ioutil.TempFile("", ".txt") - if err != nil { - panic(err) - } - - defer tempFile.Close() - - if _, err = tempFile.WriteString(exampleBlame); err != nil { - panic(err) - } - - blameReader, err := createBlameReader("", "cat", tempFile.Name()) - if err != nil { - panic(err) - } - defer blameReader.Close() - - parts := []*BlamePart{ - { - "4b92a6c2df28054ad766bc262f308db9f6066596", - []string{ - "// Copyright 2014 The Gogs Authors. All rights reserved.", - }, - }, - { - "ce21ed6c3490cdfad797319cbb1145e2330a8fef", - []string{ - "// Copyright 2016 The Gitea Authors. All rights reserved.", - }, - }, - { - "4b92a6c2df28054ad766bc262f308db9f6066596", - []string{ - "// Use of this source code is governed by a MIT-style", - "// license that can be found in the LICENSE file.", - "", - }, - }, - { - "e2aa991e10ffd924a828ec149951f2f20eecead2", - []string{ - "// Gitea (git with a cup of tea) is a painless self-hosted Git Service.", - "package main // import \"code.gitea.io/gitea\"", - }, - }, - nil, - } - - for _, part := range parts { - actualPart, err := blameReader.NextPart() - if err != nil { - panic(err) - } - assert.Equal(t, part, actualPart) - } -} diff --git a/models/git_diff.go b/models/git_diff.go index 29c424c11c..bc79a73a4e 100644 --- a/models/git_diff.go +++ b/models/git_diff.go @@ -675,7 +675,7 @@ func GetDiffRangeWithWhitespaceBehavior(repoPath, beforeCommitID, afterCommitID var cmd *exec.Cmd if len(beforeCommitID) == 0 && commit.ParentCount() == 0 { - cmd = exec.Command("git", "show", afterCommitID) + cmd = exec.Command(git.GitExecutable, "show", afterCommitID) } else { actualBeforeCommitID := beforeCommitID if len(actualBeforeCommitID) == 0 { @@ -688,7 +688,7 @@ func GetDiffRangeWithWhitespaceBehavior(repoPath, beforeCommitID, afterCommitID } diffArgs = append(diffArgs, actualBeforeCommitID) diffArgs = append(diffArgs, afterCommitID) - cmd = exec.Command("git", diffArgs...) + cmd = exec.Command(git.GitExecutable, diffArgs...) } cmd.Dir = repoPath cmd.Stderr = os.Stderr @@ -752,23 +752,23 @@ func GetRawDiffForFile(repoPath, startCommit, endCommit string, diffType RawDiff switch diffType { case RawDiffNormal: if len(startCommit) != 0 { - cmd = exec.Command("git", append([]string{"diff", "-M", startCommit, endCommit}, fileArgs...)...) + cmd = exec.Command(git.GitExecutable, append([]string{"diff", "-M", startCommit, endCommit}, fileArgs...)...) } else if commit.ParentCount() == 0 { - cmd = exec.Command("git", append([]string{"show", endCommit}, fileArgs...)...) + cmd = exec.Command(git.GitExecutable, append([]string{"show", endCommit}, fileArgs...)...) } else { c, _ := commit.Parent(0) - cmd = exec.Command("git", append([]string{"diff", "-M", c.ID.String(), endCommit}, fileArgs...)...) + cmd = exec.Command(git.GitExecutable, append([]string{"diff", "-M", c.ID.String(), endCommit}, fileArgs...)...) } case RawDiffPatch: if len(startCommit) != 0 { query := fmt.Sprintf("%s...%s", endCommit, startCommit) - cmd = exec.Command("git", append([]string{"format-patch", "--no-signature", "--stdout", "--root", query}, fileArgs...)...) + cmd = exec.Command(git.GitExecutable, append([]string{"format-patch", "--no-signature", "--stdout", "--root", query}, fileArgs...)...) } else if commit.ParentCount() == 0 { - cmd = exec.Command("git", append([]string{"format-patch", "--no-signature", "--stdout", "--root", endCommit}, fileArgs...)...) + cmd = exec.Command(git.GitExecutable, append([]string{"format-patch", "--no-signature", "--stdout", "--root", endCommit}, fileArgs...)...) } else { c, _ := commit.Parent(0) query := fmt.Sprintf("%s...%s", endCommit, c.ID.String()) - cmd = exec.Command("git", append([]string{"format-patch", "--no-signature", "--stdout", query}, fileArgs...)...) + cmd = exec.Command(git.GitExecutable, append([]string{"format-patch", "--no-signature", "--stdout", query}, fileArgs...)...) } default: return fmt.Errorf("invalid diffType: %s", diffType) diff --git a/models/pull.go b/models/pull.go index 38976d37ec..2f5412651b 100644 --- a/models/pull.go +++ b/models/pull.go @@ -463,7 +463,7 @@ func (pr *PullRequest) getMergeCommit() (*git.Commit, error) { // Check if a pull request is merged into BaseBranch _, stderr, err := process.GetManager().ExecDirEnv(-1, "", fmt.Sprintf("isMerged (git merge-base --is-ancestor): %d", pr.BaseRepo.ID), []string{"GIT_INDEX_FILE=" + indexTmpPath, "GIT_DIR=" + pr.BaseRepo.RepoPath()}, - "git", "merge-base", "--is-ancestor", headFile, pr.BaseBranch) + git.GitExecutable, "merge-base", "--is-ancestor", headFile, pr.BaseBranch) if err != nil { // Errors are signaled by a non-zero status that is not 1 @@ -486,7 +486,7 @@ func (pr *PullRequest) getMergeCommit() (*git.Commit, error) { // Get the commit from BaseBranch where the pull request got merged mergeCommit, stderr, err := process.GetManager().ExecDirEnv(-1, "", fmt.Sprintf("isMerged (git rev-list --ancestry-path --merges --reverse): %d", pr.BaseRepo.ID), []string{"GIT_INDEX_FILE=" + indexTmpPath, "GIT_DIR=" + pr.BaseRepo.RepoPath()}, - "git", "rev-list", "--ancestry-path", "--merges", "--reverse", cmd) + git.GitExecutable, "rev-list", "--ancestry-path", "--merges", "--reverse", cmd) if err != nil { return nil, fmt.Errorf("git rev-list --ancestry-path --merges --reverse: %v %v", stderr, err) } else if len(mergeCommit) < 40 { @@ -548,7 +548,7 @@ func (pr *PullRequest) testPatch(e Engine) (err error) { var stderr string _, stderr, err = process.GetManager().ExecDirEnv(-1, "", fmt.Sprintf("testPatch (git read-tree): %d", pr.BaseRepo.ID), []string{"GIT_DIR=" + pr.BaseRepo.RepoPath(), "GIT_INDEX_FILE=" + indexTmpPath}, - "git", "read-tree", pr.BaseBranch) + git.GitExecutable, "read-tree", pr.BaseBranch) if err != nil { return fmt.Errorf("git read-tree --index-output=%s %s: %v - %s", indexTmpPath, pr.BaseBranch, err, stderr) } @@ -568,7 +568,7 @@ func (pr *PullRequest) testPatch(e Engine) (err error) { _, stderr, err = process.GetManager().ExecDirEnv(-1, "", fmt.Sprintf("testPatch (git apply --check): %d", pr.BaseRepo.ID), []string{"GIT_INDEX_FILE=" + indexTmpPath, "GIT_DIR=" + pr.BaseRepo.RepoPath()}, - "git", args...) + git.GitExecutable, args...) if err != nil { for i := range patchConflicts { if strings.Contains(stderr, patchConflicts[i]) { diff --git a/models/release.go b/models/release.go index 036b5f78b9..f8e8c17e74 100644 --- a/models/release.go +++ b/models/release.go @@ -434,7 +434,7 @@ func DeleteReleaseByID(id int64, u *User, delTag bool) error { if delTag { _, stderr, err := process.GetManager().ExecDir(-1, repo.RepoPath(), fmt.Sprintf("DeleteReleaseByID (git tag -d): %d", rel.ID), - "git", "tag", "-d", rel.TagName) + git.GitExecutable, "tag", "-d", rel.TagName) if err != nil && !strings.Contains(stderr, "not found") { return fmt.Errorf("git tag -d: %v - %s", err, stderr) } diff --git a/models/repo.go b/models/repo.go index 2f732d0e26..1b4ff1f186 100644 --- a/models/repo.go +++ b/models/repo.go @@ -932,22 +932,18 @@ func MigrateRepository(doer, u *User, opts MigrateRepoOptions) (*Repository, err } } - // Check if repository is empty. - _, stderr, err := com.ExecCmdDir(repoPath, "git", "log", "-1") + gitRepo, err := git.OpenRepository(repoPath) if err != nil { - if strings.Contains(stderr, "fatal: bad default revision 'HEAD'") { - repo.IsEmpty = true - } else { - return repo, fmt.Errorf("check empty: %v - %s", err, stderr) - } + return repo, fmt.Errorf("OpenRepository: %v", err) + } + + repo.IsEmpty, err = gitRepo.IsEmpty() + if err != nil { + return repo, fmt.Errorf("git.IsEmpty: %v", err) } if !repo.IsEmpty { // Try to get HEAD branch and set it as default branch. - gitRepo, err := git.OpenRepository(repoPath) - if err != nil { - return repo, fmt.Errorf("OpenRepository: %v", err) - } headBranch, err := gitRepo.GetHEADBranch() if err != nil { return repo, fmt.Errorf("GetHEADBranch: %v", err) @@ -1072,20 +1068,20 @@ func initRepoCommit(tmpPath string, sig *git.Signature) (err error) { var stderr string if _, stderr, err = process.GetManager().ExecDir(-1, tmpPath, fmt.Sprintf("initRepoCommit (git add): %s", tmpPath), - "git", "add", "--all"); err != nil { + git.GitExecutable, "add", "--all"); err != nil { return fmt.Errorf("git add: %s", stderr) } if _, stderr, err = process.GetManager().ExecDir(-1, tmpPath, fmt.Sprintf("initRepoCommit (git commit): %s", tmpPath), - "git", "commit", fmt.Sprintf("--author='%s <%s>'", sig.Name, sig.Email), + git.GitExecutable, "commit", fmt.Sprintf("--author='%s <%s>'", sig.Name, sig.Email), "-m", "Initial commit"); err != nil { return fmt.Errorf("git commit: %s", stderr) } if _, stderr, err = process.GetManager().ExecDir(-1, tmpPath, fmt.Sprintf("initRepoCommit (git push): %s", tmpPath), - "git", "push", "origin", "master"); err != nil { + git.GitExecutable, "push", "origin", "master"); err != nil { return fmt.Errorf("git push: %s", stderr) } return nil @@ -1131,7 +1127,7 @@ func prepareRepoCommit(e Engine, repo *Repository, tmpDir, repoPath string, opts // Clone to temporary path and do the init commit. _, stderr, err := process.GetManager().Exec( fmt.Sprintf("initRepository(git clone): %s", repoPath), - "git", "clone", repoPath, tmpDir, + git.GitExecutable, "clone", repoPath, tmpDir, ) if err != nil { return fmt.Errorf("git clone: %v - %s", err, stderr) @@ -1390,7 +1386,7 @@ func CreateRepository(doer, u *User, opts CreateRepoOptions) (_ *Repository, err _, stderr, err := process.GetManager().ExecDir(-1, repoPath, fmt.Sprintf("CreateRepository(git update-server-info): %s", repoPath), - "git", "update-server-info") + git.GitExecutable, "update-server-info") if err != nil { return nil, errors.New("CreateRepository(git update-server-info): " + stderr) } @@ -2239,7 +2235,7 @@ func GitGcRepos() error { _, stderr, err := process.GetManager().ExecDir( time.Duration(setting.Git.Timeout.GC)*time.Second, RepoPath(repo.Owner.Name, repo.Name), "Repository garbage collection", - "git", args...) + git.GitExecutable, args...) if err != nil { return fmt.Errorf("%v: %v", err, stderr) } @@ -2429,14 +2425,14 @@ func ForkRepository(doer, u *User, oldRepo *Repository, name, desc string) (_ *R repoPath := RepoPath(u.Name, repo.Name) _, stderr, err := process.GetManager().ExecTimeout(10*time.Minute, fmt.Sprintf("ForkRepository(git clone): %s/%s", u.Name, repo.Name), - "git", "clone", "--bare", oldRepo.repoPath(sess), repoPath) + git.GitExecutable, "clone", "--bare", oldRepo.repoPath(sess), repoPath) if err != nil { return nil, fmt.Errorf("git clone: %v", stderr) } _, stderr, err = process.GetManager().ExecDir(-1, repoPath, fmt.Sprintf("ForkRepository(git update-server-info): %s", repoPath), - "git", "update-server-info") + git.GitExecutable, "update-server-info") if err != nil { return nil, fmt.Errorf("git update-server-info: %v", stderr) } diff --git a/models/repo_mirror.go b/models/repo_mirror.go index 7579231d8c..c62834f6fb 100644 --- a/models/repo_mirror.go +++ b/models/repo_mirror.go @@ -216,7 +216,7 @@ func (m *Mirror) runSync() ([]*mirrorSyncResult, bool) { _, stderr, err := process.GetManager().ExecDir( timeout, repoPath, fmt.Sprintf("Mirror.runSync: %s", repoPath), - "git", gitArgs...) + git.GitExecutable, gitArgs...) if err != nil { // sanitize the output, since it may contain the remote address, which may // contain a password @@ -250,7 +250,7 @@ func (m *Mirror) runSync() ([]*mirrorSyncResult, bool) { if m.Repo.HasWiki() { if _, stderr, err := process.GetManager().ExecDir( timeout, wikiPath, fmt.Sprintf("Mirror.runSync: %s", wikiPath), - "git", "remote", "update", "--prune"); err != nil { + git.GitExecutable, "remote", "update", "--prune"); err != nil { // sanitize the output, since it may contain the remote address, which may // contain a password message, err := sanitizeOutput(stderr, wikiPath) diff --git a/models/update.go b/models/update.go index 3eb0990d3d..411f7d5be1 100644 --- a/models/update.go +++ b/models/update.go @@ -7,7 +7,6 @@ package models import ( "container/list" "fmt" - "os/exec" "strings" "time" @@ -193,9 +192,8 @@ func pushUpdate(opts PushUpdateOptions) (repo *Repository, err error) { repoPath := RepoPath(opts.RepoUserName, opts.RepoName) - gitUpdate := exec.Command("git", "update-server-info") - gitUpdate.Dir = repoPath - if err = gitUpdate.Run(); err != nil { + _, err = git.NewCommand("update-server-info").RunInDir(repoPath) + if err != nil { return nil, fmt.Errorf("Failed to call 'git update-server-info': %v", err) } |