summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLunny Xiao <xiaolunwen@gmail.com>2014-03-26 17:57:13 +0800
committerLunny Xiao <xiaolunwen@gmail.com>2014-03-26 17:57:13 +0800
commit74b3c953def27d91761cb487c1984dcebd346d29 (patch)
treedcc3458fd77f105065986d5822efbb905e4202c1
parent8e0748e0b8910f6b759493d73c7107631c3aa457 (diff)
downloadgitea-74b3c953def27d91761cb487c1984dcebd346d29.tar.gz
gitea-74b3c953def27d91761cb487c1984dcebd346d29.zip
improved diff
-rw-r--r--models/git.go144
1 files changed, 138 insertions, 6 deletions
diff --git a/models/git.go b/models/git.go
index b0b0dd2f84..5b2a4060b4 100644
--- a/models/git.go
+++ b/models/git.go
@@ -9,8 +9,10 @@ import (
"fmt"
"path"
"strings"
-
- "github.com/Unknwon/com"
+ "io"
+ "bufio"
+ "os"
+ "os/exec"
"github.com/gogits/git"
)
@@ -226,20 +228,150 @@ func GetCommits(userName, reposName, branchname string) (*list.List, error) {
return r.AllCommits()
}
+const (
+ PlainLine = iota + 1
+ AddLine
+ DelLine
+ SectionLine
+)
+
+const (
+ AddFile = iota + 1
+ ChangeFile
+ DelFile
+)
+
+type DiffLine struct {
+ LeftIdx int
+ RightIdx int
+ Type int
+ Content string
+}
+
+type DiffSection struct {
+ Name string
+ Lines []*DiffLine
+}
+
type DiffFile struct {
Name string
Addition, Deletion int
- Type string
- Content []string
+ Type int
+ Sections []*DiffSection
}
type Diff struct {
- NumFiles int // Number of file has been changed.
TotalAddition, TotalDeletion int
Files []*DiffFile
}
+func (diff *Diff) NumFiles() int {
+ return len(diff.Files)
+}
+
+const diffHead = "diff --git "
+
+func ParsePatch(reader io.Reader) (*Diff, error) {
+ scanner := bufio.NewScanner(reader)
+ var totalAdd, totalDel int
+ var curFile *DiffFile
+ var curSection * DiffSection
+ //var leftLine, rightLine int
+ diff := &Diff{Files:make([]*DiffFile, 0)}
+ var i int
+ for scanner.Scan() {
+ line := scanner.Text()
+ fmt.Println(i, line)
+ i = i + 1
+ if line == "" {
+ continue
+ }
+ if line[0] == ' ' {
+ diffLine := &DiffLine{Type: PlainLine, Content:line}
+ curSection.Lines = append(curSection.Lines, diffLine)
+ continue
+ } else if line[0] == '@' {
+ ss := strings.Split(line, "@@")
+ diffLine := &DiffLine{Type: SectionLine, Content:"@@ "+ss[len(ss)-2]}
+ curSection.Lines = append(curSection.Lines, diffLine)
+
+
+
+ diffLine = &DiffLine{Type: PlainLine, Content:ss[len(ss)-1]}
+ curSection.Lines = append(curSection.Lines, diffLine)
+ continue
+ } else if line[0] == '+' {
+ diffLine := &DiffLine{Type: AddLine, Content:line}
+ curSection.Lines = append(curSection.Lines, diffLine)
+ continue
+ } else if line[0] == '-' {
+ diffLine := &DiffLine{Type: DelLine, Content:line}
+ curSection.Lines = append(curSection.Lines, diffLine)
+ continue
+ }
+
+ if strings.HasPrefix(line, diffHead) {
+ if curFile != nil {
+ curFile.Addition, totalAdd = totalAdd, 0
+ curFile.Deletion, totalDel = totalDel, 0
+ curFile = nil
+ }
+ fs := strings.Split(line[len(diffHead):], " ")
+ a := fs[0]
+
+ curFile = &DiffFile{
+ Name:a[strings.Index(a, "/")+1:],
+ Type: ChangeFile,
+ Sections:make([]*DiffSection, 0),
+ }
+ diff.Files = append(diff.Files, curFile)
+ scanner.Scan()
+ scanner.Scan()
+ if scanner.Text() == "--- /dev/null" {
+ curFile.Type = AddFile
+ }
+ scanner.Scan()
+ }
+ }
+
+ 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
+ }
+
+ if commit.ParentCount() == 0 {
+ return nil, err
+ }
+
+ rd, wr := io.Pipe()
+ go func() {
+ cmd := exec.Command("git", "diff", commitid, commit.Parent(0).Oid.String())
+ cmd.Dir = repoPath
+ cmd.Stdout = wr
+ cmd.Stdin = os.Stdin
+ cmd.Stderr = os.Stderr
+ cmd.Run()
+ //if err != nil {
+ // return nil, err
+ //}
+ wr.Close()
+ }()
+
+ defer rd.Close()
+
+ return ParsePatch(rd)
+}
+
+/*func GetDiff(repoPath, commitid string) (*Diff, error) {
stdout, _, err := com.ExecCmdDir(repoPath, "git", "show", commitid)
if err != nil {
return nil, err
@@ -271,4 +403,4 @@ func GetDiff(repoPath, commitid string) (*Diff, error) {
diff.Files = append(diff.Files, file)
}
return diff, nil
-}
+}*/