update with new git

This commit is contained in:
slene 2014-04-13 09:35:36 +08:00
parent 9ffa8a4083
commit 52b4ab2aa5
10 changed files with 307 additions and 663 deletions

View File

@ -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()
}

207
models/git_diff.go Normal file
View File

@ -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)
}

View File

@ -28,34 +28,25 @@ func Update(refName, oldCommitId, newCommitId, userName, repoName string, userId
qlog.Fatalf("runUpdate.Open repoId: %v", err) qlog.Fatalf("runUpdate.Open repoId: %v", err)
} }
newOid, err := git.NewOidFromString(newCommitId) newCommit, err := repo.GetCommit(newCommitId)
if err != nil { if err != nil {
qlog.Fatalf("runUpdate.Ref repoId:%v err: %v", newCommitId, err) qlog.Fatalf("runUpdate GetCommit of newCommitId: %v", err)
} return
newCommit, err := repo.LookupCommit(newOid)
if err != nil {
qlog.Fatalf("runUpdate.Ref repoId: %v", err)
} }
var l *list.List var l *list.List
// if a new branch // if a new branch
if isNew { if isNew {
l, err = repo.CommitsBefore(newCommit.Id()) l, err = newCommit.CommitsBefore()
if err != nil { if err != nil {
qlog.Fatalf("Find CommitsBefore erro:", err) qlog.Fatalf("Find CommitsBefore erro:", err)
} }
} else { } else {
oldOid, err := git.NewOidFromString(oldCommitId) l, err = newCommit.CommitsBeforeUntil(oldCommitId)
if err != nil { if err != nil {
qlog.Fatalf("runUpdate.Ref repoId: %v", err) qlog.Fatalf("Find CommitsBeforeUntil erro:", err)
return
} }
oldCommit, err := repo.LookupCommit(oldOid)
if err != nil {
qlog.Fatalf("runUpdate.Ref repoId: %v", err)
}
l = repo.CommitsBetween(newCommit, oldCommit)
} }
if err != nil { if err != nil {
@ -76,7 +67,7 @@ func Update(refName, oldCommitId, newCommitId, userName, repoName string, userId
actEmail = commit.Committer.Email actEmail = commit.Committer.Email
} }
commits = append(commits, commits = append(commits,
&base.PushCommit{commit.Id().String(), &base.PushCommit{commit.Id.String(),
commit.Message(), commit.Message(),
commit.Author.Email, commit.Author.Email,
commit.Author.Name}) 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()}) //commits = append(commits, []string{lastCommit.Id().String(), lastCommit.Message()})
if err = CommitRepoAction(userId, userName, actEmail, 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) qlog.Fatalf("runUpdate.models.CommitRepoAction: %v", err)
} }
} }

View File

@ -131,7 +131,7 @@ func RepoAssignment(redirect bool, args ...bool) martini.Handler {
detect: detect:
if len(branchName) > 0 { if len(branchName) > 0 {
// TODO check tag // TODO check tag
if models.IsBranchExist(user.Name, repoName, branchName) { if gitRepo.IsBranchExist(branchName) {
ctx.Repo.IsBranch = true ctx.Repo.IsBranch = true
ctx.Repo.BranchName = branchName ctx.Repo.BranchName = branchName
@ -141,7 +141,7 @@ func RepoAssignment(redirect bool, args ...bool) martini.Handler {
return return
} }
ctx.Repo.CommitId = ctx.Repo.Commit.Oid.String() ctx.Repo.CommitId = ctx.Repo.Commit.Id.String()
} else if len(branchName) == 40 { } else if len(branchName) == 40 {
ctx.Repo.IsCommit = true ctx.Repo.IsCommit = true
@ -181,7 +181,7 @@ func RepoAssignment(redirect bool, args ...bool) martini.Handler {
} }
ctx.Data["BranchName"] = ctx.Repo.BranchName ctx.Data["BranchName"] = ctx.Repo.BranchName
brs, err := models.GetBranches(user.Name, repoName) brs, err := ctx.Repo.GitRepo.GetBranches()
if err != nil { if err != nil {
log.Error("RepoAssignment(GetBranches): %v", err) log.Error("RepoAssignment(GetBranches): %v", err)
} }

View File

@ -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,
})
}

View File

@ -7,12 +7,11 @@ package repo
import ( import (
"github.com/go-martini/martini" "github.com/go-martini/martini"
"github.com/gogits/gogs/models"
"github.com/gogits/gogs/modules/middleware" "github.com/gogits/gogs/modules/middleware"
) )
func Branches(ctx *middleware.Context, params martini.Params) { 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 { if err != nil {
ctx.Handle(404, "repo.Branches", err) ctx.Handle(404, "repo.Branches", err)
return return

View File

@ -5,7 +5,6 @@
package repo package repo
import ( import (
"container/list"
"path" "path"
"github.com/go-martini/martini" "github.com/go-martini/martini"
@ -16,11 +15,10 @@ import (
) )
func Commits(ctx *middleware.Context, params martini.Params) { func Commits(ctx *middleware.Context, params martini.Params) {
userName := params["username"] userName := ctx.Repo.Owner.Name
repoName := params["reponame"] repoName := ctx.Repo.Repository.Name
branchName := params["branchname"]
brs, err := models.GetBranches(userName, repoName) brs, err := ctx.Repo.GitRepo.GetBranches()
if err != nil { if err != nil {
ctx.Handle(500, "repo.Commits", err) ctx.Handle(500, "repo.Commits", err)
return return
@ -29,8 +27,7 @@ func Commits(ctx *middleware.Context, params martini.Params) {
return return
} }
repoPath := models.RepoPath(userName, repoName) commitsCount, err := ctx.Repo.Commit.CommitsCount()
commitsCount, err := models.GetCommitsCount(repoPath, branchName)
if err != nil { if err != nil {
ctx.Handle(500, "repo.Commits(GetCommitsCount)", err) ctx.Handle(500, "repo.Commits(GetCommitsCount)", err)
return return
@ -51,7 +48,7 @@ func Commits(ctx *middleware.Context, params martini.Params) {
} }
//both `git log branchName` and `git log commitId` work //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 { if err != nil {
ctx.Handle(500, "repo.Commits(get commits)", err) ctx.Handle(500, "repo.Commits(get commits)", err)
return return
@ -70,7 +67,6 @@ func Commits(ctx *middleware.Context, params martini.Params) {
func Diff(ctx *middleware.Context, params martini.Params) { func Diff(ctx *middleware.Context, params martini.Params) {
userName := ctx.Repo.Owner.Name userName := ctx.Repo.Owner.Name
repoName := ctx.Repo.Repository.Name repoName := ctx.Repo.Repository.Name
branchName := ctx.Repo.BranchName
commitId := ctx.Repo.CommitId commitId := ctx.Repo.CommitId
commit := ctx.Repo.Commit commit := ctx.Repo.Commit
@ -82,19 +78,15 @@ func Diff(ctx *middleware.Context, params martini.Params) {
} }
isImageFile := func(name string) bool { isImageFile := func(name string) bool {
repoFile, err := models.GetTargetFile(userName, repoName, blob, err := ctx.Repo.Commit.GetBlobByPath(name)
branchName, commitId, name)
if err != nil { if err != nil {
return false return false
} }
blob, err := repoFile.LookupBlob() data, err := blob.Data()
if err != nil { if err != nil {
return false return false
} }
data := blob.Contents()
_, isImage := base.IsImageFile(data) _, isImage := base.IsImageFile(data)
return isImage return isImage
} }
@ -119,9 +111,8 @@ func SearchCommits(ctx *middleware.Context, params martini.Params) {
userName := params["username"] userName := params["username"]
repoName := params["reponame"] repoName := params["reponame"]
branchName := params["branchname"]
brs, err := models.GetBranches(userName, repoName) brs, err := ctx.Repo.GitRepo.GetBranches()
if err != nil { if err != nil {
ctx.Handle(500, "repo.SearchCommits(GetBranches)", err) ctx.Handle(500, "repo.SearchCommits(GetBranches)", err)
return return
@ -130,11 +121,8 @@ func SearchCommits(ctx *middleware.Context, params martini.Params) {
return return
} }
var commits *list.List commits, err := ctx.Repo.Commit.SearchCommits(keyword)
if !models.IsBranchExist(userName, repoName, branchName) { if err != nil {
ctx.Handle(404, "repo.SearchCommits(IsBranchExist)", err)
return
} else if commits, err = models.SearchCommits(models.RepoPath(userName, repoName), branchName, keyword); err != nil {
ctx.Handle(500, "repo.SearchCommits(SearchCommits)", err) ctx.Handle(500, "repo.SearchCommits(SearchCommits)", err)
return return
} }

View File

@ -5,7 +5,6 @@
package repo package repo
import ( import (
"github.com/gogits/gogs/models"
"github.com/gogits/gogs/modules/middleware" "github.com/gogits/gogs/modules/middleware"
) )
@ -13,7 +12,7 @@ func Releases(ctx *middleware.Context) {
ctx.Data["Title"] = "Releases" ctx.Data["Title"] = "Releases"
ctx.Data["IsRepoToolbarReleases"] = true ctx.Data["IsRepoToolbarReleases"] = true
ctx.Data["IsRepoReleaseNew"] = false 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 { if err != nil {
ctx.Handle(404, "repo.Releases(GetTags)", err) ctx.Handle(404, "repo.Releases(GetTags)", err)
return return

View File

@ -8,6 +8,7 @@ import (
"encoding/base64" "encoding/base64"
"errors" "errors"
"fmt" "fmt"
"github.com/gogits/git"
"path" "path"
"path/filepath" "path/filepath"
"strings" "strings"
@ -107,7 +108,6 @@ func MigratePost(ctx *middleware.Context, form auth.MigrateRepoForm) {
func Single(ctx *middleware.Context, params martini.Params) { func Single(ctx *middleware.Context, params martini.Params) {
branchName := ctx.Repo.BranchName branchName := ctx.Repo.BranchName
commitId := ctx.Repo.CommitId
userName := ctx.Repo.Owner.Name userName := ctx.Repo.Owner.Name
repoName := ctx.Repo.Repository.Name repoName := ctx.Repo.Repository.Name
@ -125,46 +125,42 @@ func Single(ctx *middleware.Context, params martini.Params) {
ctx.Data["IsRepoToolbarSource"] = true 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 isViewBranch := ctx.Repo.IsBranch
ctx.Data["IsViewBranch"] = isViewBranch ctx.Data["IsViewBranch"] = isViewBranch
repoFile, err := models.GetTargetFile(userName, repoName, treePath := treename
branchName, commitId, treename) if len(treePath) != 0 {
treePath = treePath + "/"
}
if err != nil && err != models.ErrRepoFileNotExist { entry, err := ctx.Repo.Commit.GetTreeEntryByPath(treename)
ctx.Handle(404, "repo.Single(GetTargetFile)", err)
if err != nil && err != git.ErrNotExist {
ctx.Handle(404, "repo.Single(GetTreeEntryByPath)", err)
return return
} }
if len(treename) != 0 && repoFile == nil { if len(treename) != 0 && entry == nil {
ctx.Handle(404, "repo.Single", nil) ctx.Handle(404, "repo.Single", nil)
return return
} }
if repoFile != nil && repoFile.IsFile() { if entry != nil && entry.IsFile() {
if blob, err := repoFile.LookupBlob(); err != nil { blob := entry.Blob()
ctx.Handle(404, "repo.Single(repoFile.LookupBlob)", err)
if data, err := blob.Data(); err != nil {
ctx.Handle(404, "repo.Single(blob.Data)", err)
} else { } else {
ctx.Data["FileSize"] = repoFile.Size ctx.Data["FileSize"] = blob.Size()
ctx.Data["IsFile"] = true ctx.Data["IsFile"] = true
ctx.Data["FileName"] = repoFile.Name ctx.Data["FileName"] = blob.Name
ext := path.Ext(repoFile.Name) ext := path.Ext(blob.Name)
if len(ext) > 0 { if len(ext) > 0 {
ext = ext[1:] ext = ext[1:]
} }
ctx.Data["FileExt"] = ext ctx.Data["FileExt"] = ext
ctx.Data["FileLink"] = rawLink + "/" + treename ctx.Data["FileLink"] = rawLink + "/" + treename
data := blob.Contents()
_, isTextFile := base.IsTextFile(data) _, isTextFile := base.IsTextFile(data)
_, isImageFile := base.IsImageFile(data) _, isImageFile := base.IsImageFile(data)
ctx.Data["FileIsText"] = isTextFile ctx.Data["FileIsText"] = isTextFile
@ -172,7 +168,7 @@ func Single(ctx *middleware.Context, params martini.Params) {
if isImageFile { if isImageFile {
ctx.Data["IsImageFile"] = true ctx.Data["IsImageFile"] = true
} else { } else {
readmeExist := base.IsMarkdownFile(repoFile.Name) || base.IsReadmeFile(repoFile.Name) readmeExist := base.IsMarkdownFile(blob.Name) || base.IsReadmeFile(blob.Name)
ctx.Data["ReadmeExist"] = readmeExist ctx.Data["ReadmeExist"] = readmeExist
if readmeExist { if readmeExist {
ctx.Data["FileContent"] = string(base.RenderMarkdown(data, "")) ctx.Data["FileContent"] = string(base.RenderMarkdown(data, ""))
@ -186,21 +182,35 @@ func Single(ctx *middleware.Context, params martini.Params) {
} else { } else {
// Directory and file list. // Directory and file list.
files, err := models.GetReposFiles(userName, repoName, ctx.Repo.CommitId, treename) tree, err := ctx.Repo.Commit.SubTree(treename)
if err != nil { if err != nil {
ctx.Handle(404, "repo.Single(GetReposFiles)", err) ctx.Handle(404, "repo.Single(SubTree)", err)
return 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 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) { if !f.IsFile() || !base.IsReadmeFile(f.Name) {
continue continue
} else { } else {
readmeFile = f readmeFile = f.Blob()
break break
} }
} }
@ -208,13 +218,12 @@ func Single(ctx *middleware.Context, params martini.Params) {
if readmeFile != nil { if readmeFile != nil {
ctx.Data["ReadmeInSingle"] = true ctx.Data["ReadmeInSingle"] = true
ctx.Data["ReadmeExist"] = 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) ctx.Handle(404, "repo.Single(readmeFile.LookupBlob)", err)
return return
} else { } else {
ctx.Data["FileSize"] = readmeFile.Size ctx.Data["FileSize"] = readmeFile.Size
ctx.Data["FileLink"] = rawLink + "/" + treename ctx.Data["FileLink"] = rawLink + "/" + treename
data := blob.Contents()
_, isTextFile := base.IsTextFile(data) _, isTextFile := base.IsTextFile(data)
ctx.Data["FileIsText"] = isTextFile ctx.Data["FileIsText"] = isTextFile
ctx.Data["FileName"] = readmeFile.Name 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["LastCommit"] = ctx.Repo.Commit
ctx.Data["Paths"] = Paths ctx.Data["Paths"] = Paths
ctx.Data["Treenames"] = treenames ctx.Data["Treenames"] = treenames
ctx.Data["TreePath"] = treePath
ctx.Data["BranchLink"] = branchLink ctx.Data["BranchLink"] = branchLink
ctx.HTML(200, "repo/single") ctx.HTML(200, "repo/single")
} }
@ -254,31 +264,18 @@ func SingleDownload(ctx *middleware.Context, params martini.Params) {
// Get tree path // Get tree path
treename := params["_1"] treename := params["_1"]
branchName := params["branchname"] blob, err := ctx.Repo.Commit.GetBlobByPath(treename)
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)
if err != nil { if err != nil {
ctx.Handle(404, "repo.SingleDownload(GetTargetFile)", err) ctx.Handle(404, "repo.SingleDownload(GetBlobByPath)", err)
return return
} }
blob, err := repoFile.LookupBlob() data, err := blob.Data()
if err != nil { if err != nil {
ctx.Handle(404, "repo.SingleDownload(LookupBlob)", err) ctx.Handle(404, "repo.SingleDownload(Data)", err)
return return
} }
data := blob.Contents()
contentType, isTextFile := base.IsTextFile(data) contentType, isTextFile := base.IsTextFile(data)
_, isImageFile := base.IsImageFile(data) _, isImageFile := base.IsImageFile(data)
ctx.Res.Header().Set("Content-Type", contentType) ctx.Res.Header().Set("Content-Type", contentType)
@ -361,7 +358,8 @@ func SettingPost(ctx *middleware.Context) {
} }
br := ctx.Query("branch") 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.DefaultBranch = br
} }
ctx.Repo.Repository.Description = ctx.Query("desc") ctx.Repo.Repository.Description = ctx.Query("desc")

View File

@ -1,6 +1,6 @@
<div class="panel panel-default info-box"> <div class="panel panel-default info-box">
<div class="panel-heading info-head"> <div class="panel-heading info-head">
<a href="/{{.Username}}/{{.Reponame}}/commit/{{.LastCommit.Oid.String}}">{{.LastCommit.Message}}</a> <a href="/{{.Username}}/{{.Reponame}}/commit/{{.LastCommit.Id}}">{{.LastCommit.Message}}</a>
</div> </div>
<div class="panel-body info-content"> <div class="panel-body info-content">
<a href="/user/{{.LastCommit.Author.Name}}">{{.LastCommit.Author.Name}}</a> <span class="text-muted">{{TimeSince .LastCommit.Author.When}}</span> <a href="/user/{{.LastCommit.Author.Name}}">{{.LastCommit.Author.Name}}</a> <span class="text-muted">{{TimeSince .LastCommit.Author.When}}</span>
@ -15,40 +15,37 @@
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{{if .HasParentPath}} {{if .HasParentPath}}
<tr class="has-parent"> <tr class="has-parent">
<td class="icon"><a href="{{.BranchLink}}{{.ParentPath}}"><i class="fa fa-reply"></i></a></td> <td class="icon"><a href="{{.BranchLink}}{{.ParentPath}}"><i class="fa fa-reply"></i></a></td>
<td class="name"><a href="{{.BranchLink}}{{.ParentPath}}">..</a></td> <td class="name"><a href="{{.BranchLink}}{{.ParentPath}}">..</a></td>
<td class="text"></td> <td class="text"></td>
<td class="date"></td> <td class="date"></td>
</tr> </tr>
{{end}} {{end}}
{{range .Files}} {{range $item := .Files}}
<tr {{$entry := index $item 0}}
{{if .IsDir}}class="is-dir"{{end}}> {{$commit := index $item 1}}
<td class="icon"> <tr {{if $entry.IsDir}}class="is-dir"{{end}}>
<i class="fa {{if .IsDir}}fa-folder{{else}}fa-file-text-o{{end}}"></i> <td class="icon">
</td> <i class="fa {{if $entry.IsDir}}fa-folder{{else}}fa-file-text-o{{end}}"></i>
<td class="name"> </td>
<span class="wrap"> <td class="name">
{{if .IsDir}} <span class="wrap">
<a href="{{$.BranchLink}}/{{.Path}}">{{.Name}}</a> <a href="{{$.BranchLink}}/{{$.TreePath}}{{$entry.Name}}">{{$entry.Name}}</a>
{{else}} </span>
<a href="{{$.BranchLink}}/{{.Path}}">{{.Name}}</a> </td>
{{end}} <td class="text">
</span> <span class="wrap"><a href="/{{$.Username}}/{{$.Reponame}}/commit/{{$commit.Id}}">{{$commit.Message}}</a></span>
</td> </td>
<td class="text"> <td class="date">
<span class="wrap"><a href="/{{$.Username}}/{{$.Reponame}}/commit/{{.Commit.Oid}}">{{.Commit.Message}}</a></span> <span class="wrap">{{TimeSince $commit.Committer.When}}</span>
</td> </td>
<td class="date"> </tr>
<span class="wrap">{{TimeSince .Commit.Committer.When}}</span> {{end}}
</td>
</tr>
{{end}}
</tbody> </tbody>
</table> </table>
</div> </div>
{{if .ReadmeExist}} {{if .ReadmeExist}}
{{template "repo/single_file" .}} {{template "repo/single_file" .}}
{{end}} {{end}}