summaryrefslogtreecommitdiffstats
path: root/models
diff options
context:
space:
mode:
authorLunny Xiao <xiaolunwen@gmail.com>2019-06-27 02:15:26 +0800
committertechknowlogick <techknowlogick@gitea.io>2019-06-26 14:15:26 -0400
commitedc94c70413048107ea728ff330f32ca3de6df88 (patch)
treecf5bcc5ba8ee4b2e585dc14a6cf7440ce88bc073 /models
parent161e12e157a48f9bcd2de50c187c77444aa2a9a8 (diff)
downloadgitea-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.go124
-rw-r--r--models/git_blame_test.go141
-rw-r--r--models/git_diff.go16
-rw-r--r--models/pull.go8
-rw-r--r--models/release.go2
-rw-r--r--models/repo.go34
-rw-r--r--models/repo_mirror.go4
-rw-r--r--models/update.go6
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)
}