Skip to content

Commit edc94c7

Browse files
lunnytechknowlogick
authored andcommitted
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
1 parent 161e12e commit edc94c7

34 files changed

+750
-74
lines changed

Diff for: contrib/pr/checkout.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -20,20 +20,20 @@ import (
2020
"strconv"
2121
"time"
2222

23+
"code.gitea.io/gitea/models"
2324
"code.gitea.io/gitea/modules/markup"
2425
"code.gitea.io/gitea/modules/markup/external"
26+
"code.gitea.io/gitea/modules/setting"
2527
"code.gitea.io/gitea/routers"
2628
"code.gitea.io/gitea/routers/routes"
29+
2730
"github.com/Unknwon/com"
2831
"github.com/go-xorm/xorm"
2932
context2 "github.com/gorilla/context"
3033
"gopkg.in/src-d/go-git.v4"
3134
"gopkg.in/src-d/go-git.v4/config"
3235
"gopkg.in/src-d/go-git.v4/plumbing"
3336
"gopkg.in/testfixtures.v2"
34-
35-
"code.gitea.io/gitea/models"
36-
"code.gitea.io/gitea/modules/setting"
3737
)
3838

3939
var codeFilePath = "contrib/pr/checkout.go"

Diff for: models/git_diff.go

+8-8
Original file line numberDiff line numberDiff line change
@@ -675,7 +675,7 @@ func GetDiffRangeWithWhitespaceBehavior(repoPath, beforeCommitID, afterCommitID
675675

676676
var cmd *exec.Cmd
677677
if len(beforeCommitID) == 0 && commit.ParentCount() == 0 {
678-
cmd = exec.Command("git", "show", afterCommitID)
678+
cmd = exec.Command(git.GitExecutable, "show", afterCommitID)
679679
} else {
680680
actualBeforeCommitID := beforeCommitID
681681
if len(actualBeforeCommitID) == 0 {
@@ -688,7 +688,7 @@ func GetDiffRangeWithWhitespaceBehavior(repoPath, beforeCommitID, afterCommitID
688688
}
689689
diffArgs = append(diffArgs, actualBeforeCommitID)
690690
diffArgs = append(diffArgs, afterCommitID)
691-
cmd = exec.Command("git", diffArgs...)
691+
cmd = exec.Command(git.GitExecutable, diffArgs...)
692692
}
693693
cmd.Dir = repoPath
694694
cmd.Stderr = os.Stderr
@@ -752,23 +752,23 @@ func GetRawDiffForFile(repoPath, startCommit, endCommit string, diffType RawDiff
752752
switch diffType {
753753
case RawDiffNormal:
754754
if len(startCommit) != 0 {
755-
cmd = exec.Command("git", append([]string{"diff", "-M", startCommit, endCommit}, fileArgs...)...)
755+
cmd = exec.Command(git.GitExecutable, append([]string{"diff", "-M", startCommit, endCommit}, fileArgs...)...)
756756
} else if commit.ParentCount() == 0 {
757-
cmd = exec.Command("git", append([]string{"show", endCommit}, fileArgs...)...)
757+
cmd = exec.Command(git.GitExecutable, append([]string{"show", endCommit}, fileArgs...)...)
758758
} else {
759759
c, _ := commit.Parent(0)
760-
cmd = exec.Command("git", append([]string{"diff", "-M", c.ID.String(), endCommit}, fileArgs...)...)
760+
cmd = exec.Command(git.GitExecutable, append([]string{"diff", "-M", c.ID.String(), endCommit}, fileArgs...)...)
761761
}
762762
case RawDiffPatch:
763763
if len(startCommit) != 0 {
764764
query := fmt.Sprintf("%s...%s", endCommit, startCommit)
765-
cmd = exec.Command("git", append([]string{"format-patch", "--no-signature", "--stdout", "--root", query}, fileArgs...)...)
765+
cmd = exec.Command(git.GitExecutable, append([]string{"format-patch", "--no-signature", "--stdout", "--root", query}, fileArgs...)...)
766766
} else if commit.ParentCount() == 0 {
767-
cmd = exec.Command("git", append([]string{"format-patch", "--no-signature", "--stdout", "--root", endCommit}, fileArgs...)...)
767+
cmd = exec.Command(git.GitExecutable, append([]string{"format-patch", "--no-signature", "--stdout", "--root", endCommit}, fileArgs...)...)
768768
} else {
769769
c, _ := commit.Parent(0)
770770
query := fmt.Sprintf("%s...%s", endCommit, c.ID.String())
771-
cmd = exec.Command("git", append([]string{"format-patch", "--no-signature", "--stdout", query}, fileArgs...)...)
771+
cmd = exec.Command(git.GitExecutable, append([]string{"format-patch", "--no-signature", "--stdout", query}, fileArgs...)...)
772772
}
773773
default:
774774
return fmt.Errorf("invalid diffType: %s", diffType)

Diff for: models/pull.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -463,7 +463,7 @@ func (pr *PullRequest) getMergeCommit() (*git.Commit, error) {
463463
// Check if a pull request is merged into BaseBranch
464464
_, stderr, err := process.GetManager().ExecDirEnv(-1, "", fmt.Sprintf("isMerged (git merge-base --is-ancestor): %d", pr.BaseRepo.ID),
465465
[]string{"GIT_INDEX_FILE=" + indexTmpPath, "GIT_DIR=" + pr.BaseRepo.RepoPath()},
466-
"git", "merge-base", "--is-ancestor", headFile, pr.BaseBranch)
466+
git.GitExecutable, "merge-base", "--is-ancestor", headFile, pr.BaseBranch)
467467

468468
if err != nil {
469469
// Errors are signaled by a non-zero status that is not 1
@@ -486,7 +486,7 @@ func (pr *PullRequest) getMergeCommit() (*git.Commit, error) {
486486
// Get the commit from BaseBranch where the pull request got merged
487487
mergeCommit, stderr, err := process.GetManager().ExecDirEnv(-1, "", fmt.Sprintf("isMerged (git rev-list --ancestry-path --merges --reverse): %d", pr.BaseRepo.ID),
488488
[]string{"GIT_INDEX_FILE=" + indexTmpPath, "GIT_DIR=" + pr.BaseRepo.RepoPath()},
489-
"git", "rev-list", "--ancestry-path", "--merges", "--reverse", cmd)
489+
git.GitExecutable, "rev-list", "--ancestry-path", "--merges", "--reverse", cmd)
490490
if err != nil {
491491
return nil, fmt.Errorf("git rev-list --ancestry-path --merges --reverse: %v %v", stderr, err)
492492
} else if len(mergeCommit) < 40 {
@@ -548,7 +548,7 @@ func (pr *PullRequest) testPatch(e Engine) (err error) {
548548
var stderr string
549549
_, stderr, err = process.GetManager().ExecDirEnv(-1, "", fmt.Sprintf("testPatch (git read-tree): %d", pr.BaseRepo.ID),
550550
[]string{"GIT_DIR=" + pr.BaseRepo.RepoPath(), "GIT_INDEX_FILE=" + indexTmpPath},
551-
"git", "read-tree", pr.BaseBranch)
551+
git.GitExecutable, "read-tree", pr.BaseBranch)
552552
if err != nil {
553553
return fmt.Errorf("git read-tree --index-output=%s %s: %v - %s", indexTmpPath, pr.BaseBranch, err, stderr)
554554
}
@@ -568,7 +568,7 @@ func (pr *PullRequest) testPatch(e Engine) (err error) {
568568

569569
_, stderr, err = process.GetManager().ExecDirEnv(-1, "", fmt.Sprintf("testPatch (git apply --check): %d", pr.BaseRepo.ID),
570570
[]string{"GIT_INDEX_FILE=" + indexTmpPath, "GIT_DIR=" + pr.BaseRepo.RepoPath()},
571-
"git", args...)
571+
git.GitExecutable, args...)
572572
if err != nil {
573573
for i := range patchConflicts {
574574
if strings.Contains(stderr, patchConflicts[i]) {

Diff for: models/release.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -434,7 +434,7 @@ func DeleteReleaseByID(id int64, u *User, delTag bool) error {
434434
if delTag {
435435
_, stderr, err := process.GetManager().ExecDir(-1, repo.RepoPath(),
436436
fmt.Sprintf("DeleteReleaseByID (git tag -d): %d", rel.ID),
437-
"git", "tag", "-d", rel.TagName)
437+
git.GitExecutable, "tag", "-d", rel.TagName)
438438
if err != nil && !strings.Contains(stderr, "not found") {
439439
return fmt.Errorf("git tag -d: %v - %s", err, stderr)
440440
}

Diff for: models/repo.go

+15-19
Original file line numberDiff line numberDiff line change
@@ -932,22 +932,18 @@ func MigrateRepository(doer, u *User, opts MigrateRepoOptions) (*Repository, err
932932
}
933933
}
934934

935-
// Check if repository is empty.
936-
_, stderr, err := com.ExecCmdDir(repoPath, "git", "log", "-1")
935+
gitRepo, err := git.OpenRepository(repoPath)
937936
if err != nil {
938-
if strings.Contains(stderr, "fatal: bad default revision 'HEAD'") {
939-
repo.IsEmpty = true
940-
} else {
941-
return repo, fmt.Errorf("check empty: %v - %s", err, stderr)
942-
}
937+
return repo, fmt.Errorf("OpenRepository: %v", err)
938+
}
939+
940+
repo.IsEmpty, err = gitRepo.IsEmpty()
941+
if err != nil {
942+
return repo, fmt.Errorf("git.IsEmpty: %v", err)
943943
}
944944

945945
if !repo.IsEmpty {
946946
// Try to get HEAD branch and set it as default branch.
947-
gitRepo, err := git.OpenRepository(repoPath)
948-
if err != nil {
949-
return repo, fmt.Errorf("OpenRepository: %v", err)
950-
}
951947
headBranch, err := gitRepo.GetHEADBranch()
952948
if err != nil {
953949
return repo, fmt.Errorf("GetHEADBranch: %v", err)
@@ -1072,20 +1068,20 @@ func initRepoCommit(tmpPath string, sig *git.Signature) (err error) {
10721068
var stderr string
10731069
if _, stderr, err = process.GetManager().ExecDir(-1,
10741070
tmpPath, fmt.Sprintf("initRepoCommit (git add): %s", tmpPath),
1075-
"git", "add", "--all"); err != nil {
1071+
git.GitExecutable, "add", "--all"); err != nil {
10761072
return fmt.Errorf("git add: %s", stderr)
10771073
}
10781074

10791075
if _, stderr, err = process.GetManager().ExecDir(-1,
10801076
tmpPath, fmt.Sprintf("initRepoCommit (git commit): %s", tmpPath),
1081-
"git", "commit", fmt.Sprintf("--author='%s <%s>'", sig.Name, sig.Email),
1077+
git.GitExecutable, "commit", fmt.Sprintf("--author='%s <%s>'", sig.Name, sig.Email),
10821078
"-m", "Initial commit"); err != nil {
10831079
return fmt.Errorf("git commit: %s", stderr)
10841080
}
10851081

10861082
if _, stderr, err = process.GetManager().ExecDir(-1,
10871083
tmpPath, fmt.Sprintf("initRepoCommit (git push): %s", tmpPath),
1088-
"git", "push", "origin", "master"); err != nil {
1084+
git.GitExecutable, "push", "origin", "master"); err != nil {
10891085
return fmt.Errorf("git push: %s", stderr)
10901086
}
10911087
return nil
@@ -1131,7 +1127,7 @@ func prepareRepoCommit(e Engine, repo *Repository, tmpDir, repoPath string, opts
11311127
// Clone to temporary path and do the init commit.
11321128
_, stderr, err := process.GetManager().Exec(
11331129
fmt.Sprintf("initRepository(git clone): %s", repoPath),
1134-
"git", "clone", repoPath, tmpDir,
1130+
git.GitExecutable, "clone", repoPath, tmpDir,
11351131
)
11361132
if err != nil {
11371133
return fmt.Errorf("git clone: %v - %s", err, stderr)
@@ -1390,7 +1386,7 @@ func CreateRepository(doer, u *User, opts CreateRepoOptions) (_ *Repository, err
13901386

13911387
_, stderr, err := process.GetManager().ExecDir(-1,
13921388
repoPath, fmt.Sprintf("CreateRepository(git update-server-info): %s", repoPath),
1393-
"git", "update-server-info")
1389+
git.GitExecutable, "update-server-info")
13941390
if err != nil {
13951391
return nil, errors.New("CreateRepository(git update-server-info): " + stderr)
13961392
}
@@ -2239,7 +2235,7 @@ func GitGcRepos() error {
22392235
_, stderr, err := process.GetManager().ExecDir(
22402236
time.Duration(setting.Git.Timeout.GC)*time.Second,
22412237
RepoPath(repo.Owner.Name, repo.Name), "Repository garbage collection",
2242-
"git", args...)
2238+
git.GitExecutable, args...)
22432239
if err != nil {
22442240
return fmt.Errorf("%v: %v", err, stderr)
22452241
}
@@ -2429,14 +2425,14 @@ func ForkRepository(doer, u *User, oldRepo *Repository, name, desc string) (_ *R
24292425
repoPath := RepoPath(u.Name, repo.Name)
24302426
_, stderr, err := process.GetManager().ExecTimeout(10*time.Minute,
24312427
fmt.Sprintf("ForkRepository(git clone): %s/%s", u.Name, repo.Name),
2432-
"git", "clone", "--bare", oldRepo.repoPath(sess), repoPath)
2428+
git.GitExecutable, "clone", "--bare", oldRepo.repoPath(sess), repoPath)
24332429
if err != nil {
24342430
return nil, fmt.Errorf("git clone: %v", stderr)
24352431
}
24362432

24372433
_, stderr, err = process.GetManager().ExecDir(-1,
24382434
repoPath, fmt.Sprintf("ForkRepository(git update-server-info): %s", repoPath),
2439-
"git", "update-server-info")
2435+
git.GitExecutable, "update-server-info")
24402436
if err != nil {
24412437
return nil, fmt.Errorf("git update-server-info: %v", stderr)
24422438
}

Diff for: models/repo_mirror.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ func (m *Mirror) runSync() ([]*mirrorSyncResult, bool) {
216216

217217
_, stderr, err := process.GetManager().ExecDir(
218218
timeout, repoPath, fmt.Sprintf("Mirror.runSync: %s", repoPath),
219-
"git", gitArgs...)
219+
git.GitExecutable, gitArgs...)
220220
if err != nil {
221221
// sanitize the output, since it may contain the remote address, which may
222222
// contain a password
@@ -250,7 +250,7 @@ func (m *Mirror) runSync() ([]*mirrorSyncResult, bool) {
250250
if m.Repo.HasWiki() {
251251
if _, stderr, err := process.GetManager().ExecDir(
252252
timeout, wikiPath, fmt.Sprintf("Mirror.runSync: %s", wikiPath),
253-
"git", "remote", "update", "--prune"); err != nil {
253+
git.GitExecutable, "remote", "update", "--prune"); err != nil {
254254
// sanitize the output, since it may contain the remote address, which may
255255
// contain a password
256256
message, err := sanitizeOutput(stderr, wikiPath)

Diff for: models/update.go

+2-4
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ package models
77
import (
88
"container/list"
99
"fmt"
10-
"os/exec"
1110
"strings"
1211
"time"
1312

@@ -193,9 +192,8 @@ func pushUpdate(opts PushUpdateOptions) (repo *Repository, err error) {
193192

194193
repoPath := RepoPath(opts.RepoUserName, opts.RepoName)
195194

196-
gitUpdate := exec.Command("git", "update-server-info")
197-
gitUpdate.Dir = repoPath
198-
if err = gitUpdate.Run(); err != nil {
195+
_, err = git.NewCommand("update-server-info").RunInDir(repoPath)
196+
if err != nil {
199197
return nil, fmt.Errorf("Failed to call 'git update-server-info': %v", err)
200198
}
201199

Diff for: models/git_blame.go renamed to modules/git/blame.go

+3-4
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// Use of this source code is governed by a MIT-style
33
// license that can be found in the LICENSE file.
44

5-
package models
5+
package git
66

77
import (
88
"bufio"
@@ -12,7 +12,6 @@ import (
1212
"os/exec"
1313
"regexp"
1414

15-
"code.gitea.io/gitea/modules/git"
1615
"code.gitea.io/gitea/modules/process"
1716
)
1817

@@ -88,12 +87,12 @@ func (r *BlameReader) Close() error {
8887

8988
// CreateBlameReader creates reader for given repository, commit and file
9089
func CreateBlameReader(repoPath, commitID, file string) (*BlameReader, error) {
91-
_, err := git.OpenRepository(repoPath)
90+
_, err := OpenRepository(repoPath)
9291
if err != nil {
9392
return nil, err
9493
}
9594

96-
return createBlameReader(repoPath, "git", "blame", commitID, "--porcelain", "--", file)
95+
return createBlameReader(repoPath, GitExecutable, "blame", commitID, "--porcelain", "--", file)
9796
}
9897

9998
func createBlameReader(dir string, command ...string) (*BlameReader, error) {

Diff for: models/git_blame_test.go renamed to modules/git/blame_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// Use of this source code is governed by a MIT-style
33
// license that can be found in the LICENSE file.
44

5-
package models
5+
package git
66

77
import (
88
"io/ioutil"

Diff for: modules/git/command.go

+5
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ import (
1212
"os/exec"
1313
"strings"
1414
"time"
15+
16+
"code.gitea.io/gitea/modules/process"
1517
)
1618

1719
var (
@@ -84,6 +86,9 @@ func (c *Command) RunInDirTimeoutEnvFullPipeline(env []string, timeout time.Dura
8486
return err
8587
}
8688

89+
pid := process.GetManager().Add(fmt.Sprintf("%s %s %s [repo_path: %s]", GitExecutable, c.name, strings.Join(c.args, " "), dir), cmd)
90+
defer process.GetManager().Remove(pid)
91+
8792
if err := cmd.Wait(); err != nil {
8893
return err
8994
}

Diff for: modules/git/repo.go

+14
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,20 @@ func OpenRepository(repoPath string) (*Repository, error) {
107107
}, nil
108108
}
109109

110+
// IsEmpty Check if repository is empty.
111+
func (repo *Repository) IsEmpty() (bool, error) {
112+
var errbuf strings.Builder
113+
if err := NewCommand("log", "-1").RunInDirPipeline(repo.Path, nil, &errbuf); err != nil {
114+
if strings.Contains(errbuf.String(), "fatal: bad default revision 'HEAD'") ||
115+
strings.Contains(errbuf.String(), "fatal: your current branch 'master' does not have any commits yet") {
116+
return true, nil
117+
}
118+
return true, fmt.Errorf("check empty: %v - %s", err, errbuf.String())
119+
}
120+
121+
return false, nil
122+
}
123+
110124
// CloneRepoOptions options when clone a repository
111125
type CloneRepoOptions struct {
112126
Timeout time.Duration

Diff for: modules/git/repo_test.go

+10
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
package git
66

77
import (
8+
"path/filepath"
89
"testing"
910
"time"
1011

@@ -24,3 +25,12 @@ func TestGetLatestCommitTime(t *testing.T) {
2425
assert.NoError(t, err)
2526
assert.True(t, lct.Unix() > refTime.Unix(), "%d not greater than %d", lct, refTime)
2627
}
28+
29+
func TestRepoIsEmpty(t *testing.T) {
30+
emptyRepo2Path := filepath.Join(testReposDir, "repo2_empty")
31+
repo, err := OpenRepository(emptyRepo2Path)
32+
assert.NoError(t, err)
33+
isEmpty, err := repo.IsEmpty()
34+
assert.NoError(t, err)
35+
assert.True(t, isEmpty)
36+
}

Diff for: modules/git/tests/repos/repo2_empty/HEAD

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ref: refs/heads/master

Diff for: modules/git/tests/repos/repo2_empty/config

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
[core]
2+
repositoryformatversion = 0
3+
filemode = true
4+
bare = true
5+
ignorecase = true
6+
precomposeunicode = true

Diff for: modules/git/tests/repos/repo2_empty/description

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Unnamed repository; edit this file 'description' to name the repository.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#!/bin/sh
2+
#
3+
# An example hook script to check the commit log message taken by
4+
# applypatch from an e-mail message.
5+
#
6+
# The hook should exit with non-zero status after issuing an
7+
# appropriate message if it wants to stop the commit. The hook is
8+
# allowed to edit the commit message file.
9+
#
10+
# To enable this hook, rename this file to "applypatch-msg".
11+
12+
. git-sh-setup
13+
commitmsg="$(git rev-parse --git-path hooks/commit-msg)"
14+
test -x "$commitmsg" && exec "$commitmsg" ${1+"$@"}
15+
:

0 commit comments

Comments
 (0)