improved diff
This commit is contained in:
		
							parent
							
								
									8e0748e0b8
								
							
						
					
					
						commit
						74b3c953de
					
				
					 1 changed files with 138 additions and 6 deletions
				
			
		
							
								
								
									
										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