improved diff
This commit is contained in:
parent
8e0748e0b8
commit
74b3c953de
144
models/git.go
144
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
|
||||
}
|
||||
}*/
|
||||
|
|
Loading…
Reference in a new issue