|
|
|
@ -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 |
|
|
|
|
} |
|
|
|
|
}*/ |
|
|
|
|