forked from gitea/gitea
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"
|
"fmt"
|
||||||
"path"
|
"path"
|
||||||
"strings"
|
"strings"
|
||||||
|
"io"
|
||||||
"github.com/Unknwon/com"
|
"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
|
Type int
|
||||||
Content []string
|
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
|
||||||
}
|
}*/
|
||||||
|
|
Loading…
Reference in New Issue