diff --git a/models/git.go b/models/git.go deleted file mode 100644 index e32b5ba96..000000000 --- a/models/git.go +++ /dev/null @@ -1,503 +0,0 @@ -// Copyright 2014 The Gogs 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" - "bytes" - "container/list" - "errors" - "fmt" - "io" - "os" - "os/exec" - "path" - "strings" - - "github.com/Unknwon/com" - - "github.com/gogits/git" - - "github.com/gogits/gogs/modules/base" - "github.com/gogits/gogs/modules/log" -) - -// RepoFile represents a file object in git repository. -type RepoFile struct { - *git.TreeEntry - Path string - Size int64 - Repo *git.Repository - Commit *git.Commit -} - -// LookupBlob returns the content of an object. -func (file *RepoFile) LookupBlob() (*git.Blob, error) { - if file.Repo == nil { - return nil, ErrRepoFileNotLoaded - } - - return file.Repo.LookupBlob(file.Id) -} - -// GetBranches returns all branches of given repository. -func GetBranches(userName, repoName string) ([]string, error) { - repo, err := git.OpenRepository(RepoPath(userName, repoName)) - if err != nil { - return nil, err - } - - refs, err := repo.AllReferences() - if err != nil { - return nil, err - } - - brs := make([]string, len(refs)) - for i, ref := range refs { - brs[i] = ref.BranchName() - } - return brs, nil -} - -// GetTags returns all tags of given repository. -func GetTags(userName, repoName string) ([]string, error) { - repo, err := git.OpenRepository(RepoPath(userName, repoName)) - if err != nil { - return nil, err - } - - refs, err := repo.AllTags() - if err != nil { - return nil, err - } - - tags := make([]string, len(refs)) - for i, ref := range refs { - tags[i] = ref.Name - } - return tags, nil -} - -func IsBranchExist(userName, repoName, branchName string) bool { - repo, err := git.OpenRepository(RepoPath(userName, repoName)) - if err != nil { - return false - } - return repo.IsBranchExist(branchName) -} - -func GetTargetFile(userName, repoName, branchName, commitId, rpath string) (*RepoFile, error) { - repo, err := git.OpenRepository(RepoPath(userName, repoName)) - if err != nil { - return nil, err - } - - commit, err := repo.GetCommitOfBranch(branchName) - if err != nil { - commit, err = repo.GetCommit(commitId) - if err != nil { - return nil, err - } - } - - parts := strings.Split(path.Clean(rpath), "/") - - var entry *git.TreeEntry - tree := commit.Tree - for i, part := range parts { - if i == len(parts)-1 { - entry = tree.EntryByName(part) - if entry == nil { - return nil, ErrRepoFileNotExist - } - } else { - tree, err = repo.SubTree(tree, part) - if err != nil { - return nil, err - } - } - } - - size, err := repo.ObjectSize(entry.Id) - if err != nil { - return nil, err - } - - repoFile := &RepoFile{ - entry, - rpath, - size, - repo, - commit, - } - - return repoFile, nil -} - -// GetReposFiles returns a list of file object in given directory of repository. -// func GetReposFilesOfBranch(userName, repoName, branchName, rpath string) ([]*RepoFile, error) { -// return getReposFiles(userName, repoName, commitId, rpath) -// } - -// GetReposFiles returns a list of file object in given directory of repository. -func GetReposFiles(userName, repoName, commitId, rpath string) ([]*RepoFile, error) { - return getReposFiles(userName, repoName, commitId, rpath) -} - -func getReposFiles(userName, repoName, commitId string, rpath string) ([]*RepoFile, error) { - repopath := RepoPath(userName, repoName) - repo, err := git.OpenRepository(repopath) - if err != nil { - return nil, err - } - - commit, err := repo.GetCommit(commitId) - if err != nil { - return nil, err - } - - var repodirs []*RepoFile - var repofiles []*RepoFile - commit.Tree.Walk(func(dirname string, entry *git.TreeEntry) int { - if dirname == rpath { - // TODO: size get method shoule be improved - size, err := repo.ObjectSize(entry.Id) - if err != nil { - return 0 - } - - stdout, _, err := com.ExecCmdDir(repopath, "git", "log", "-1", "--pretty=format:%H", commitId, "--", path.Join(dirname, entry.Name)) - if err != nil { - return 0 - } - filecm, err := repo.GetCommit(string(stdout)) - if err != nil { - return 0 - } - - rp := &RepoFile{ - entry, - path.Join(dirname, entry.Name), - size, - repo, - filecm, - } - - if entry.IsFile() { - repofiles = append(repofiles, rp) - } else if entry.IsDir() { - repodirs = append(repodirs, rp) - } - } - return 0 - }) - - return append(repodirs, repofiles...), nil -} - -func GetCommit(userName, repoName, commitId string) (*git.Commit, error) { - repo, err := git.OpenRepository(RepoPath(userName, repoName)) - if err != nil { - return nil, err - } - - return repo.GetCommit(commitId) -} - -// GetCommitsByBranch returns all commits of given branch of repository. -func GetCommitsByBranch(userName, repoName, branchName string) (*list.List, error) { - repo, err := git.OpenRepository(RepoPath(userName, repoName)) - if err != nil { - return nil, err - } - r, err := repo.LookupReference(fmt.Sprintf("refs/heads/%s", branchName)) - if err != nil { - return nil, err - } - return r.AllCommits() -} - -// GetCommitsByCommitId returns all commits of given commitId of repository. -func GetCommitsByCommitId(userName, repoName, commitId string) (*list.List, error) { - repo, err := git.OpenRepository(RepoPath(userName, repoName)) - if err != nil { - return nil, err - } - oid, err := git.NewOidFromString(commitId) - if err != nil { - return nil, err - } - return repo.CommitsBefore(oid) -} - -// Diff line types. -const ( - DIFF_LINE_PLAIN = iota + 1 - DIFF_LINE_ADD - DIFF_LINE_DEL - DIFF_LINE_SECTION -) - -const ( - DIFF_FILE_ADD = iota + 1 - DIFF_FILE_CHANGE - DIFF_FILE_DEL -) - -type DiffLine struct { - LeftIdx int - RightIdx int - Type int - Content string -} - -func (d DiffLine) GetType() int { - return d.Type -} - -type DiffSection struct { - Name string - Lines []*DiffLine -} - -type DiffFile struct { - Name string - Addition, Deletion int - Type int - Sections []*DiffSection -} - -type Diff struct { - TotalAddition, TotalDeletion int - Files []*DiffFile -} - -func (diff *Diff) NumFiles() int { - return len(diff.Files) -} - -const DIFF_HEAD = "diff --git " - -func ParsePatch(reader io.Reader) (*Diff, error) { - scanner := bufio.NewScanner(reader) - var ( - curFile *DiffFile - curSection = &DiffSection{ - Lines: make([]*DiffLine, 0, 10), - } - - leftLine, rightLine int - ) - - diff := &Diff{Files: make([]*DiffFile, 0)} - var i int - for scanner.Scan() { - line := scanner.Text() - // fmt.Println(i, line) - if strings.HasPrefix(line, "+++ ") || strings.HasPrefix(line, "--- ") { - continue - } - - i = i + 1 - - // Diff data too large. - if i == 5000 { - log.Warn("Diff data too large") - return &Diff{}, nil - } - - if line == "" { - continue - } - if line[0] == ' ' { - diffLine := &DiffLine{Type: DIFF_LINE_PLAIN, Content: line, LeftIdx: leftLine, RightIdx: rightLine} - leftLine++ - rightLine++ - curSection.Lines = append(curSection.Lines, diffLine) - continue - } else if line[0] == '@' { - curSection = &DiffSection{} - curFile.Sections = append(curFile.Sections, curSection) - ss := strings.Split(line, "@@") - diffLine := &DiffLine{Type: DIFF_LINE_SECTION, Content: line} - curSection.Lines = append(curSection.Lines, diffLine) - - // Parse line number. - ranges := strings.Split(ss[len(ss)-2][1:], " ") - leftLine, _ = base.StrTo(strings.Split(ranges[0], ",")[0][1:]).Int() - rightLine, _ = base.StrTo(strings.Split(ranges[1], ",")[0]).Int() - continue - } else if line[0] == '+' { - curFile.Addition++ - diff.TotalAddition++ - diffLine := &DiffLine{Type: DIFF_LINE_ADD, Content: line, RightIdx: rightLine} - rightLine++ - curSection.Lines = append(curSection.Lines, diffLine) - continue - } else if line[0] == '-' { - curFile.Deletion++ - diff.TotalDeletion++ - diffLine := &DiffLine{Type: DIFF_LINE_DEL, Content: line, LeftIdx: leftLine} - if leftLine > 0 { - leftLine++ - } - curSection.Lines = append(curSection.Lines, diffLine) - continue - } - - // Get new file. - if strings.HasPrefix(line, DIFF_HEAD) { - fs := strings.Split(line[len(DIFF_HEAD):], " ") - a := fs[0] - - curFile = &DiffFile{ - Name: a[strings.Index(a, "/")+1:], - Type: DIFF_FILE_CHANGE, - Sections: make([]*DiffSection, 0, 10), - } - diff.Files = append(diff.Files, curFile) - - // Check file diff type. - for scanner.Scan() { - switch { - case strings.HasPrefix(scanner.Text(), "new file"): - curFile.Type = DIFF_FILE_ADD - case strings.HasPrefix(scanner.Text(), "deleted"): - curFile.Type = DIFF_FILE_DEL - case strings.HasPrefix(scanner.Text(), "index"): - curFile.Type = DIFF_FILE_CHANGE - } - if curFile.Type > 0 { - break - } - } - } - } - - return diff, nil -} - -func GetDiff(repoPath, commitid string) (*Diff, error) { - repo, err := git.OpenRepository(repoPath) - if err != nil { - return nil, err - } - - commit, err := repo.GetCommit(commitid) - if err != nil { - return nil, err - } - - // First commit of repository. - if commit.ParentCount() == 0 { - rd, wr := io.Pipe() - go func() { - cmd := exec.Command("git", "show", commitid) - cmd.Dir = repoPath - cmd.Stdout = wr - cmd.Stdin = os.Stdin - cmd.Stderr = os.Stderr - cmd.Run() - wr.Close() - }() - defer rd.Close() - return ParsePatch(rd) - } - - rd, wr := io.Pipe() - go func() { - cmd := exec.Command("git", "diff", commit.Parent(0).Oid.String(), commitid) - cmd.Dir = repoPath - cmd.Stdout = wr - cmd.Stdin = os.Stdin - cmd.Stderr = os.Stderr - cmd.Run() - wr.Close() - }() - defer rd.Close() - return ParsePatch(rd) -} - -const prettyLogFormat = `--pretty=format:%H%n%an <%ae> %at%n%s` - -func parsePrettyFormatLog(logByts []byte) (*list.List, error) { - l := list.New() - buf := bytes.NewBuffer(logByts) - if buf.Len() == 0 { - return l, nil - } - - idx := 0 - var commit *git.Commit - - for { - line, err := buf.ReadString('\n') - if err != nil && err != io.EOF { - return nil, err - } - line = strings.TrimSpace(line) - // fmt.Println(line) - - var parseErr error - switch idx { - case 0: // SHA1. - commit = &git.Commit{} - commit.Oid, parseErr = git.NewOidFromString(line) - case 1: // Signature. - commit.Author, parseErr = git.NewSignatureFromCommitline([]byte(line + " ")) - case 2: // Commit message. - commit.CommitMessage = line - l.PushBack(commit) - idx = -1 - } - - if parseErr != nil { - return nil, parseErr - } - - idx++ - - if err == io.EOF { - break - } - } - - return l, nil -} - -// SearchCommits searches commits in given branch and keyword of repository. -func SearchCommits(repoPath, branch, keyword string) (*list.List, error) { - stdout, stderr, err := com.ExecCmdDirBytes(repoPath, "git", "log", branch, "-100", - "-i", "--grep="+keyword, prettyLogFormat) - if err != nil { - return nil, err - } else if len(stderr) > 0 { - return nil, errors.New(string(stderr)) - } - return parsePrettyFormatLog(stdout) -} - -// GetCommitsByRange returns certain number of commits with given page of repository. -func GetCommitsByRange(repoPath, branch string, page int) (*list.List, error) { - stdout, stderr, err := com.ExecCmdDirBytes(repoPath, "git", "log", branch, - "--skip="+base.ToStr((page-1)*50), "--max-count=50", prettyLogFormat) - if err != nil { - return nil, err - } else if len(stderr) > 0 { - return nil, errors.New(string(stderr)) - } - return parsePrettyFormatLog(stdout) -} - -// GetCommitsCount returns the commits count of given branch of repository. -func GetCommitsCount(repoPath, branch string) (int, error) { - stdout, stderr, err := com.ExecCmdDir(repoPath, "git", "rev-list", "--count", branch) - if err != nil { - return 0, err - } else if len(stderr) > 0 { - return 0, errors.New(stderr) - } - return base.StrTo(strings.TrimSpace(stdout)).Int() -} diff --git a/models/git_diff.go b/models/git_diff.go new file mode 100644 index 000000000..de9d1de7b --- /dev/null +++ b/models/git_diff.go @@ -0,0 +1,207 @@ +// Copyright 2014 The Gogs 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" + "io" + "os" + "os/exec" + "strings" + + "github.com/gogits/git" + + "github.com/gogits/gogs/modules/base" + "github.com/gogits/gogs/modules/log" +) + +// Diff line types. +const ( + DIFF_LINE_PLAIN = iota + 1 + DIFF_LINE_ADD + DIFF_LINE_DEL + DIFF_LINE_SECTION +) + +const ( + DIFF_FILE_ADD = iota + 1 + DIFF_FILE_CHANGE + DIFF_FILE_DEL +) + +type DiffLine struct { + LeftIdx int + RightIdx int + Type int + Content string +} + +func (d DiffLine) GetType() int { + return d.Type +} + +type DiffSection struct { + Name string + Lines []*DiffLine +} + +type DiffFile struct { + Name string + Addition, Deletion int + Type int + Sections []*DiffSection +} + +type Diff struct { + TotalAddition, TotalDeletion int + Files []*DiffFile +} + +func (diff *Diff) NumFiles() int { + return len(diff.Files) +} + +const DIFF_HEAD = "diff --git " + +func ParsePatch(reader io.Reader) (*Diff, error) { + scanner := bufio.NewScanner(reader) + var ( + curFile *DiffFile + curSection = &DiffSection{ + Lines: make([]*DiffLine, 0, 10), + } + + leftLine, rightLine int + ) + + diff := &Diff{Files: make([]*DiffFile, 0)} + var i int + for scanner.Scan() { + line := scanner.Text() + // fmt.Println(i, line) + if strings.HasPrefix(line, "+++ ") || strings.HasPrefix(line, "--- ") { + continue + } + + i = i + 1 + + // Diff data too large. + if i == 5000 { + log.Warn("Diff data too large") + return &Diff{}, nil + } + + if line == "" { + continue + } + if line[0] == ' ' { + diffLine := &DiffLine{Type: DIFF_LINE_PLAIN, Content: line, LeftIdx: leftLine, RightIdx: rightLine} + leftLine++ + rightLine++ + curSection.Lines = append(curSection.Lines, diffLine) + continue + } else if line[0] == '@' { + curSection = &DiffSection{} + curFile.Sections = append(curFile.Sections, curSection) + ss := strings.Split(line, "@@") + diffLine := &DiffLine{Type: DIFF_LINE_SECTION, Content: line} + curSection.Lines = append(curSection.Lines, diffLine) + + // Parse line number. + ranges := strings.Split(ss[len(ss)-2][1:], " ") + leftLine, _ = base.StrTo(strings.Split(ranges[0], ",")[0][1:]).Int() + rightLine, _ = base.StrTo(strings.Split(ranges[1], ",")[0]).Int() + continue + } else if line[0] == '+' { + curFile.Addition++ + diff.TotalAddition++ + diffLine := &DiffLine{Type: DIFF_LINE_ADD, Content: line, RightIdx: rightLine} + rightLine++ + curSection.Lines = append(curSection.Lines, diffLine) + continue + } else if line[0] == '-' { + curFile.Deletion++ + diff.TotalDeletion++ + diffLine := &DiffLine{Type: DIFF_LINE_DEL, Content: line, LeftIdx: leftLine} + if leftLine > 0 { + leftLine++ + } + curSection.Lines = append(curSection.Lines, diffLine) + continue + } + + // Get new file. + if strings.HasPrefix(line, DIFF_HEAD) { + fs := strings.Split(line[len(DIFF_HEAD):], " ") + a := fs[0] + + curFile = &DiffFile{ + Name: a[strings.Index(a, "/")+1:], + Type: DIFF_FILE_CHANGE, + Sections: make([]*DiffSection, 0, 10), + } + diff.Files = append(diff.Files, curFile) + + // Check file diff type. + for scanner.Scan() { + switch { + case strings.HasPrefix(scanner.Text(), "new file"): + curFile.Type = DIFF_FILE_ADD + case strings.HasPrefix(scanner.Text(), "deleted"): + curFile.Type = DIFF_FILE_DEL + case strings.HasPrefix(scanner.Text(), "index"): + curFile.Type = DIFF_FILE_CHANGE + } + if curFile.Type > 0 { + break + } + } + } + } + + return diff, nil +} + +func GetDiff(repoPath, commitid string) (*Diff, error) { + repo, err := git.OpenRepository(repoPath) + if err != nil { + return nil, err + } + + commit, err := repo.GetCommit(commitid) + if err != nil { + return nil, err + } + + // First commit of repository. + if commit.ParentCount() == 0 { + rd, wr := io.Pipe() + go func() { + cmd := exec.Command("git", "show", commitid) + cmd.Dir = repoPath + cmd.Stdout = wr + cmd.Stdin = os.Stdin + cmd.Stderr = os.Stderr + cmd.Run() + wr.Close() + }() + defer rd.Close() + return ParsePatch(rd) + } + + rd, wr := io.Pipe() + go func() { + c, _ := commit.Parent(0) + cmd := exec.Command("git", "diff", c.Id.String(), commitid) + cmd.Dir = repoPath + cmd.Stdout = wr + cmd.Stdin = os.Stdin + cmd.Stderr = os.Stderr + cmd.Run() + wr.Close() + }() + defer rd.Close() + return ParsePatch(rd) +} diff --git a/models/update.go b/models/update.go index 2ceac271a..53591fa42 100644 --- a/models/update.go +++ b/models/update.go @@ -28,34 +28,25 @@ func Update(refName, oldCommitId, newCommitId, userName, repoName string, userId qlog.Fatalf("runUpdate.Open repoId: %v", err) } - newOid, err := git.NewOidFromString(newCommitId) + newCommit, err := repo.GetCommit(newCommitId) if err != nil { - qlog.Fatalf("runUpdate.Ref repoId:%v err: %v", newCommitId, err) - } - - newCommit, err := repo.LookupCommit(newOid) - if err != nil { - qlog.Fatalf("runUpdate.Ref repoId: %v", err) + qlog.Fatalf("runUpdate GetCommit of newCommitId: %v", err) + return } var l *list.List // if a new branch if isNew { - l, err = repo.CommitsBefore(newCommit.Id()) + l, err = newCommit.CommitsBefore() if err != nil { qlog.Fatalf("Find CommitsBefore erro:", err) } } else { - oldOid, err := git.NewOidFromString(oldCommitId) - if err != nil { - qlog.Fatalf("runUpdate.Ref repoId: %v", err) - } - - oldCommit, err := repo.LookupCommit(oldOid) + l, err = newCommit.CommitsBeforeUntil(oldCommitId) if err != nil { - qlog.Fatalf("runUpdate.Ref repoId: %v", err) + qlog.Fatalf("Find CommitsBeforeUntil erro:", err) + return } - l = repo.CommitsBetween(newCommit, oldCommit) } if err != nil { @@ -76,7 +67,7 @@ func Update(refName, oldCommitId, newCommitId, userName, repoName string, userId actEmail = commit.Committer.Email } commits = append(commits, - &base.PushCommit{commit.Id().String(), + &base.PushCommit{commit.Id.String(), commit.Message(), commit.Author.Email, commit.Author.Name}) @@ -87,7 +78,7 @@ func Update(refName, oldCommitId, newCommitId, userName, repoName string, userId //commits = append(commits, []string{lastCommit.Id().String(), lastCommit.Message()}) if err = CommitRepoAction(userId, userName, actEmail, - repos.Id, repoName, git.BranchName(refName), &base.PushCommits{l.Len(), commits}); err != nil { + repos.Id, repoName, git.RefEndName(refName), &base.PushCommits{l.Len(), commits}); err != nil { qlog.Fatalf("runUpdate.models.CommitRepoAction: %v", err) } } diff --git a/modules/middleware/repo.go b/modules/middleware/repo.go index 2a6d300e4..f0a46b6da 100644 --- a/modules/middleware/repo.go +++ b/modules/middleware/repo.go @@ -131,7 +131,7 @@ func RepoAssignment(redirect bool, args ...bool) martini.Handler { detect: if len(branchName) > 0 { // TODO check tag - if models.IsBranchExist(user.Name, repoName, branchName) { + if gitRepo.IsBranchExist(branchName) { ctx.Repo.IsBranch = true ctx.Repo.BranchName = branchName @@ -141,7 +141,7 @@ func RepoAssignment(redirect bool, args ...bool) martini.Handler { return } - ctx.Repo.CommitId = ctx.Repo.Commit.Oid.String() + ctx.Repo.CommitId = ctx.Repo.Commit.Id.String() } else if len(branchName) == 40 { ctx.Repo.IsCommit = true @@ -181,7 +181,7 @@ func RepoAssignment(redirect bool, args ...bool) martini.Handler { } ctx.Data["BranchName"] = ctx.Repo.BranchName - brs, err := models.GetBranches(user.Name, repoName) + brs, err := ctx.Repo.GitRepo.GetBranches() if err != nil { log.Error("RepoAssignment(GetBranches): %v", err) } diff --git a/routers/api/v1/repositories.go b/routers/api/v1/repositories.go deleted file mode 100644 index 4d05c1a77..000000000 --- a/routers/api/v1/repositories.go +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright 2014 The Gogs 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 v1 - -import ( - "github.com/gogits/gogs/models" - "github.com/gogits/gogs/modules/middleware" -) - -func SearchCommits(ctx *middleware.Context) { - userName := ctx.Query("username") - repoName := ctx.Query("reponame") - branch := ctx.Query("branch") - keyword := ctx.Query("q") - if len(keyword) == 0 { - ctx.Render.JSON(404, nil) - return - } - - commits, err := models.SearchCommits(models.RepoPath(userName, repoName), branch, keyword) - if err != nil { - ctx.Render.JSON(200, map[string]interface{}{"ok": false}) - return - } - - ctx.Render.JSON(200, map[string]interface{}{ - "ok": true, - "commits": commits, - }) -} diff --git a/routers/repo/branch.go b/routers/repo/branch.go index ffd118ae1..92265d2e5 100644 --- a/routers/repo/branch.go +++ b/routers/repo/branch.go @@ -7,12 +7,11 @@ package repo import ( "github.com/go-martini/martini" - "github.com/gogits/gogs/models" "github.com/gogits/gogs/modules/middleware" ) func Branches(ctx *middleware.Context, params martini.Params) { - brs, err := models.GetBranches(ctx.Repo.Owner.Name, ctx.Repo.Repository.Name) + brs, err := ctx.Repo.GitRepo.GetBranches() if err != nil { ctx.Handle(404, "repo.Branches", err) return diff --git a/routers/repo/commit.go b/routers/repo/commit.go index dbfd9af29..6e20a7b7f 100644 --- a/routers/repo/commit.go +++ b/routers/repo/commit.go @@ -5,7 +5,6 @@ package repo import ( - "container/list" "path" "github.com/go-martini/martini" @@ -16,11 +15,10 @@ import ( ) func Commits(ctx *middleware.Context, params martini.Params) { - userName := params["username"] - repoName := params["reponame"] - branchName := params["branchname"] + userName := ctx.Repo.Owner.Name + repoName := ctx.Repo.Repository.Name - brs, err := models.GetBranches(userName, repoName) + brs, err := ctx.Repo.GitRepo.GetBranches() if err != nil { ctx.Handle(500, "repo.Commits", err) return @@ -29,8 +27,7 @@ func Commits(ctx *middleware.Context, params martini.Params) { return } - repoPath := models.RepoPath(userName, repoName) - commitsCount, err := models.GetCommitsCount(repoPath, branchName) + commitsCount, err := ctx.Repo.Commit.CommitsCount() if err != nil { ctx.Handle(500, "repo.Commits(GetCommitsCount)", err) return @@ -51,7 +48,7 @@ func Commits(ctx *middleware.Context, params martini.Params) { } //both `git log branchName` and `git log commitId` work - commits, err := models.GetCommitsByRange(repoPath, branchName, page) + commits, err := ctx.Repo.Commit.CommitsByRange(page) if err != nil { ctx.Handle(500, "repo.Commits(get commits)", err) return @@ -70,7 +67,6 @@ func Commits(ctx *middleware.Context, params martini.Params) { func Diff(ctx *middleware.Context, params martini.Params) { userName := ctx.Repo.Owner.Name repoName := ctx.Repo.Repository.Name - branchName := ctx.Repo.BranchName commitId := ctx.Repo.CommitId commit := ctx.Repo.Commit @@ -82,19 +78,15 @@ func Diff(ctx *middleware.Context, params martini.Params) { } isImageFile := func(name string) bool { - repoFile, err := models.GetTargetFile(userName, repoName, - branchName, commitId, name) - + blob, err := ctx.Repo.Commit.GetBlobByPath(name) if err != nil { return false } - blob, err := repoFile.LookupBlob() + data, err := blob.Data() if err != nil { return false } - - data := blob.Contents() _, isImage := base.IsImageFile(data) return isImage } @@ -119,9 +111,8 @@ func SearchCommits(ctx *middleware.Context, params martini.Params) { userName := params["username"] repoName := params["reponame"] - branchName := params["branchname"] - brs, err := models.GetBranches(userName, repoName) + brs, err := ctx.Repo.GitRepo.GetBranches() if err != nil { ctx.Handle(500, "repo.SearchCommits(GetBranches)", err) return @@ -130,11 +121,8 @@ func SearchCommits(ctx *middleware.Context, params martini.Params) { return } - var commits *list.List - if !models.IsBranchExist(userName, repoName, branchName) { - ctx.Handle(404, "repo.SearchCommits(IsBranchExist)", err) - return - } else if commits, err = models.SearchCommits(models.RepoPath(userName, repoName), branchName, keyword); err != nil { + commits, err := ctx.Repo.Commit.SearchCommits(keyword) + if err != nil { ctx.Handle(500, "repo.SearchCommits(SearchCommits)", err) return } diff --git a/routers/repo/release.go b/routers/repo/release.go index 279fc169f..3d549bf77 100644 --- a/routers/repo/release.go +++ b/routers/repo/release.go @@ -5,7 +5,6 @@ package repo import ( - "github.com/gogits/gogs/models" "github.com/gogits/gogs/modules/middleware" ) @@ -13,7 +12,7 @@ func Releases(ctx *middleware.Context) { ctx.Data["Title"] = "Releases" ctx.Data["IsRepoToolbarReleases"] = true ctx.Data["IsRepoReleaseNew"] = false - tags, err := models.GetTags(ctx.Repo.Owner.Name, ctx.Repo.Repository.Name) + tags, err := ctx.Repo.GitRepo.GetTags() if err != nil { ctx.Handle(404, "repo.Releases(GetTags)", err) return diff --git a/routers/repo/repo.go b/routers/repo/repo.go index f19ae02ee..3b20731c6 100644 --- a/routers/repo/repo.go +++ b/routers/repo/repo.go @@ -8,6 +8,7 @@ import ( "encoding/base64" "errors" "fmt" + "github.com/gogits/git" "path" "path/filepath" "strings" @@ -107,7 +108,6 @@ func MigratePost(ctx *middleware.Context, form auth.MigrateRepoForm) { func Single(ctx *middleware.Context, params martini.Params) { branchName := ctx.Repo.BranchName - commitId := ctx.Repo.CommitId userName := ctx.Repo.Owner.Name repoName := ctx.Repo.Repository.Name @@ -125,46 +125,42 @@ func Single(ctx *middleware.Context, params martini.Params) { ctx.Data["IsRepoToolbarSource"] = true - // Branches. - brs, err := models.GetBranches(userName, repoName) - if err != nil { - ctx.Handle(404, "repo.Single(GetBranches)", err) - return - } - - ctx.Data["Branches"] = brs - isViewBranch := ctx.Repo.IsBranch ctx.Data["IsViewBranch"] = isViewBranch - repoFile, err := models.GetTargetFile(userName, repoName, - branchName, commitId, treename) + treePath := treename + if len(treePath) != 0 { + treePath = treePath + "/" + } + + entry, err := ctx.Repo.Commit.GetTreeEntryByPath(treename) - if err != nil && err != models.ErrRepoFileNotExist { - ctx.Handle(404, "repo.Single(GetTargetFile)", err) + if err != nil && err != git.ErrNotExist { + ctx.Handle(404, "repo.Single(GetTreeEntryByPath)", err) return } - if len(treename) != 0 && repoFile == nil { + if len(treename) != 0 && entry == nil { ctx.Handle(404, "repo.Single", nil) return } - if repoFile != nil && repoFile.IsFile() { - if blob, err := repoFile.LookupBlob(); err != nil { - ctx.Handle(404, "repo.Single(repoFile.LookupBlob)", err) + if entry != nil && entry.IsFile() { + blob := entry.Blob() + + if data, err := blob.Data(); err != nil { + ctx.Handle(404, "repo.Single(blob.Data)", err) } else { - ctx.Data["FileSize"] = repoFile.Size + ctx.Data["FileSize"] = blob.Size() ctx.Data["IsFile"] = true - ctx.Data["FileName"] = repoFile.Name - ext := path.Ext(repoFile.Name) + ctx.Data["FileName"] = blob.Name + ext := path.Ext(blob.Name) if len(ext) > 0 { ext = ext[1:] } ctx.Data["FileExt"] = ext ctx.Data["FileLink"] = rawLink + "/" + treename - data := blob.Contents() _, isTextFile := base.IsTextFile(data) _, isImageFile := base.IsImageFile(data) ctx.Data["FileIsText"] = isTextFile @@ -172,7 +168,7 @@ func Single(ctx *middleware.Context, params martini.Params) { if isImageFile { ctx.Data["IsImageFile"] = true } else { - readmeExist := base.IsMarkdownFile(repoFile.Name) || base.IsReadmeFile(repoFile.Name) + readmeExist := base.IsMarkdownFile(blob.Name) || base.IsReadmeFile(blob.Name) ctx.Data["ReadmeExist"] = readmeExist if readmeExist { ctx.Data["FileContent"] = string(base.RenderMarkdown(data, "")) @@ -186,21 +182,35 @@ func Single(ctx *middleware.Context, params martini.Params) { } else { // Directory and file list. - files, err := models.GetReposFiles(userName, repoName, ctx.Repo.CommitId, treename) + tree, err := ctx.Repo.Commit.SubTree(treename) if err != nil { - ctx.Handle(404, "repo.Single(GetReposFiles)", err) + ctx.Handle(404, "repo.Single(SubTree)", err) return } + entries := tree.ListEntries() + entries.Sort() + + files := make([][]interface{}, 0, len(entries)) + + for _, te := range entries { + c, err := ctx.Repo.Commit.GetCommitOfRelPath(filepath.Join(treePath, te.Name)) + if err != nil { + ctx.Handle(404, "repo.Single(SubTree)", err) + return + } + + files = append(files, []interface{}{te, c}) + } ctx.Data["Files"] = files - var readmeFile *models.RepoFile + var readmeFile *git.Blob - for _, f := range files { + for _, f := range entries { if !f.IsFile() || !base.IsReadmeFile(f.Name) { continue } else { - readmeFile = f + readmeFile = f.Blob() break } } @@ -208,13 +218,12 @@ func Single(ctx *middleware.Context, params martini.Params) { if readmeFile != nil { ctx.Data["ReadmeInSingle"] = true ctx.Data["ReadmeExist"] = true - if blob, err := readmeFile.LookupBlob(); err != nil { + if data, err := readmeFile.Data(); err != nil { ctx.Handle(404, "repo.Single(readmeFile.LookupBlob)", err) return } else { ctx.Data["FileSize"] = readmeFile.Size ctx.Data["FileLink"] = rawLink + "/" + treename - data := blob.Contents() _, isTextFile := base.IsTextFile(data) ctx.Data["FileIsText"] = isTextFile ctx.Data["FileName"] = readmeFile.Name @@ -246,6 +255,7 @@ func Single(ctx *middleware.Context, params martini.Params) { ctx.Data["LastCommit"] = ctx.Repo.Commit ctx.Data["Paths"] = Paths ctx.Data["Treenames"] = treenames + ctx.Data["TreePath"] = treePath ctx.Data["BranchLink"] = branchLink ctx.HTML(200, "repo/single") } @@ -254,31 +264,18 @@ func SingleDownload(ctx *middleware.Context, params martini.Params) { // Get tree path treename := params["_1"] - branchName := params["branchname"] - userName := params["username"] - repoName := params["reponame"] - - var commitId string - if !models.IsBranchExist(userName, repoName, branchName) { - commitId = branchName - branchName = "" - } - - repoFile, err := models.GetTargetFile(userName, repoName, - branchName, commitId, treename) - + blob, err := ctx.Repo.Commit.GetBlobByPath(treename) if err != nil { - ctx.Handle(404, "repo.SingleDownload(GetTargetFile)", err) + ctx.Handle(404, "repo.SingleDownload(GetBlobByPath)", err) return } - blob, err := repoFile.LookupBlob() + data, err := blob.Data() if err != nil { - ctx.Handle(404, "repo.SingleDownload(LookupBlob)", err) + ctx.Handle(404, "repo.SingleDownload(Data)", err) return } - data := blob.Contents() contentType, isTextFile := base.IsTextFile(data) _, isImageFile := base.IsImageFile(data) ctx.Res.Header().Set("Content-Type", contentType) @@ -361,7 +358,8 @@ func SettingPost(ctx *middleware.Context) { } br := ctx.Query("branch") - if models.IsBranchExist(ctx.User.Name, ctx.Repo.Repository.Name, br) { + + if git.IsBranchExist(models.RepoPath(ctx.User.Name, ctx.Repo.Repository.Name), br) { ctx.Repo.Repository.DefaultBranch = br } ctx.Repo.Repository.Description = ctx.Query("desc") diff --git a/templates/repo/single_list.tmpl b/templates/repo/single_list.tmpl index b0c31d1e4..b12687bd7 100644 --- a/templates/repo/single_list.tmpl +++ b/templates/repo/single_list.tmpl @@ -1,6 +1,6 @@