|
@@ -9,8 +9,10 @@ import (
|
|
"fmt"
|
|
"fmt"
|
|
"path"
|
|
"path"
|
|
"strings"
|
|
"strings"
|
|
-
|
|
|
|
- "github.com/Unknwon/com"
|
|
|
|
|
|
+ "io"
|
|
|
|
+ "bufio"
|
|
|
|
+ "os"
|
|
|
|
+ "os/exec"
|
|
|
|
|
|
"github.com/gogits/git"
|
|
"github.com/gogits/git"
|
|
)
|
|
)
|
|
@@ -226,20 +228,150 @@ func GetCommits(userName, reposName, branchname string) (*list.List, error) {
|
|
return r.AllCommits()
|
|
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 {
|
|
type DiffFile struct {
|
|
Name string
|
|
Name string
|
|
Addition, Deletion int
|
|
Addition, Deletion int
|
|
- Type string
|
|
|
|
- Content []string
|
|
|
|
|
|
+ Type int
|
|
|
|
+ Sections []*DiffSection
|
|
}
|
|
}
|
|
|
|
|
|
type Diff struct {
|
|
type Diff struct {
|
|
- NumFiles int // Number of file has been changed.
|
|
|
|
TotalAddition, TotalDeletion int
|
|
TotalAddition, TotalDeletion int
|
|
Files []*DiffFile
|
|
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) {
|
|
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)
|
|
stdout, _, err := com.ExecCmdDir(repoPath, "git", "show", commitid)
|
|
if err != nil {
|
|
if err != nil {
|
|
return nil, err
|
|
return nil, err
|
|
@@ -271,4 +403,4 @@ func GetDiff(repoPath, commitid string) (*Diff, error) {
|
|
diff.Files = append(diff.Files, file)
|
|
diff.Files = append(diff.Files, file)
|
|
}
|
|
}
|
|
return diff, nil
|
|
return diff, nil
|
|
-}
|
|
|
|
|
|
+}*/
|