#2071 Diff is not showing full content when has super long one line

This commit is contained in:
Unknwon 2015-12-02 01:10:13 -05:00
parent 91ae2ad28b
commit 926e91820a
5 changed files with 76 additions and 58 deletions

View File

@ -5,7 +5,7 @@ Gogs - Go Git Service [![Build Status](https://travis-ci.org/gogits/gogs.svg?bra
![](public/img/gogs-large-resize.png) ![](public/img/gogs-large-resize.png)
##### Current version: 0.7.25 Beta ##### Current version: 0.7.26 Beta
<table> <table>
<tr> <tr>

View File

@ -17,7 +17,7 @@ import (
"github.com/gogits/gogs/modules/setting" "github.com/gogits/gogs/modules/setting"
) )
const APP_VER = "0.7.25.1202 Beta" const APP_VER = "0.7.26.1202 Beta"
func init() { func init() {
runtime.GOMAXPROCS(runtime.NumCPU()) runtime.GOMAXPROCS(runtime.NumCPU())

View File

@ -12,15 +12,14 @@ import (
"os" "os"
"os/exec" "os/exec"
"strings" "strings"
"time"
"github.com/Unknwon/com"
"golang.org/x/net/html/charset" "golang.org/x/net/html/charset"
"golang.org/x/text/transform" "golang.org/x/text/transform"
"github.com/Unknwon/com" "github.com/gogits/git-shell"
"github.com/gogits/gogs/modules/base" "github.com/gogits/gogs/modules/base"
"github.com/gogits/gogs/modules/git"
"github.com/gogits/gogs/modules/log" "github.com/gogits/gogs/modules/log"
"github.com/gogits/gogs/modules/process" "github.com/gogits/gogs/modules/process"
) )
@ -80,36 +79,50 @@ func (diff *Diff) NumFiles() int {
const DIFF_HEAD = "diff --git " const DIFF_HEAD = "diff --git "
func ParsePatch(pid int64, maxlines int, cmd *exec.Cmd, reader io.Reader) (*Diff, error) { func ParsePatch(maxlines int, reader io.Reader) (*Diff, error) {
scanner := bufio.NewScanner(reader)
var ( var (
diff = &Diff{Files: make([]*DiffFile, 0)}
curFile *DiffFile curFile *DiffFile
curSection = &DiffSection{ curSection = &DiffSection{
Lines: make([]*DiffLine, 0, 10), Lines: make([]*DiffLine, 0, 10),
} }
leftLine, rightLine int leftLine, rightLine int
// FIXME: Should use cache in the future. lineCount int
buf bytes.Buffer
) )
diff := &Diff{Files: make([]*DiffFile, 0)} input := bufio.NewReader(reader)
var i int isEOF := false
for scanner.Scan() { for {
line := scanner.Text() if isEOF {
break
}
line, err := input.ReadString('\n')
if err != nil {
if err == io.EOF {
isEOF = true
} else {
return nil, fmt.Errorf("ReadString: %v", err)
}
}
if len(line) > 0 && line[len(line)-1] == '\n' {
// Remove line break.
line = line[:len(line)-1]
}
if strings.HasPrefix(line, "+++ ") || strings.HasPrefix(line, "--- ") { if strings.HasPrefix(line, "+++ ") || strings.HasPrefix(line, "--- ") {
continue continue
} } else if len(line) == 0 {
if line == "" {
continue continue
} }
i = i + 1 lineCount++
// Diff data too large, we only show the first about maxlines lines // Diff data too large, we only show the first about maxlines lines
if i >= maxlines { if lineCount >= maxlines {
log.Warn("Diff data too large") log.Warn("Diff data too large")
diff.Files = nil diff.Files = nil
return diff, nil return diff, nil
@ -189,17 +202,26 @@ func ParsePatch(pid int64, maxlines int, cmd *exec.Cmd, reader io.Reader) (*Diff
diff.Files = append(diff.Files, curFile) diff.Files = append(diff.Files, curFile)
// Check file diff type. // Check file diff type.
for scanner.Scan() { for {
line, err := input.ReadString('\n')
if err != nil {
if err == io.EOF {
isEOF = true
} else {
return nil, fmt.Errorf("ReadString: %v", err)
}
}
switch { switch {
case strings.HasPrefix(scanner.Text(), "new file"): case strings.HasPrefix(line, "new file"):
curFile.Type = DIFF_FILE_ADD curFile.Type = DIFF_FILE_ADD
curFile.IsCreated = true curFile.IsCreated = true
case strings.HasPrefix(scanner.Text(), "deleted"): case strings.HasPrefix(line, "deleted"):
curFile.Type = DIFF_FILE_DEL curFile.Type = DIFF_FILE_DEL
curFile.IsDeleted = true curFile.IsDeleted = true
case strings.HasPrefix(scanner.Text(), "index"): case strings.HasPrefix(line, "index"):
curFile.Type = DIFF_FILE_CHANGE curFile.Type = DIFF_FILE_CHANGE
case strings.HasPrefix(scanner.Text(), "similarity index 100%"): case strings.HasPrefix(line, "similarity index 100%"):
curFile.Type = DIFF_FILE_RENAME curFile.Type = DIFF_FILE_RENAME
curFile.IsRenamed = true curFile.IsRenamed = true
curFile.OldName = curFile.Name curFile.OldName = curFile.Name
@ -212,6 +234,8 @@ func ParsePatch(pid int64, maxlines int, cmd *exec.Cmd, reader io.Reader) (*Diff
} }
} }
// FIXME: detect encoding while parsing.
var buf bytes.Buffer
for _, f := range diff.Files { for _, f := range diff.Files {
buf.Reset() buf.Reset()
for _, sec := range f.Sections { for _, sec := range f.Sections {
@ -238,61 +262,55 @@ func ParsePatch(pid int64, maxlines int, cmd *exec.Cmd, reader io.Reader) (*Diff
return diff, nil return diff, nil
} }
func GetDiffRange(repoPath, beforeCommitId string, afterCommitId string, maxlines int) (*Diff, error) { func GetDiffRange(repoPath, beforeCommitID string, afterCommitID string, maxlines int) (*Diff, error) {
repo, err := git.OpenRepository(repoPath) repo, err := git.OpenRepository(repoPath)
if err != nil { if err != nil {
return nil, err return nil, err
} }
commit, err := repo.GetCommit(afterCommitId) commit, err := repo.GetCommit(afterCommitID)
if err != nil { if err != nil {
return nil, err return nil, err
} }
rd, wr := io.Pipe()
var cmd *exec.Cmd var cmd *exec.Cmd
// if "after" commit given // if "after" commit given
if beforeCommitId == "" { if len(beforeCommitID) == 0 {
// First commit of repository. // First commit of repository.
if commit.ParentCount() == 0 { if commit.ParentCount() == 0 {
cmd = exec.Command("git", "show", afterCommitId) cmd = exec.Command("git", "show", afterCommitID)
} else { } else {
c, _ := commit.Parent(0) c, _ := commit.Parent(0)
cmd = exec.Command("git", "diff", "-M", c.ID.String(), afterCommitId) cmd = exec.Command("git", "diff", "-M", c.ID.String(), afterCommitID)
} }
} else { } else {
cmd = exec.Command("git", "diff", "-M", beforeCommitId, afterCommitId) cmd = exec.Command("git", "diff", "-M", beforeCommitID, afterCommitID)
} }
cmd.Dir = repoPath cmd.Dir = repoPath
cmd.Stdout = wr
cmd.Stdin = os.Stdin
cmd.Stderr = os.Stderr cmd.Stderr = os.Stderr
done := make(chan error) stdout, err := cmd.StdoutPipe()
go func() { if err != nil {
cmd.Start() return nil, fmt.Errorf("StdoutPipe: %v", err)
done <- cmd.Wait() }
wr.Close()
}()
defer rd.Close()
desc := fmt.Sprintf("GetDiffRange(%s)", repoPath) if err = cmd.Start(); err != nil {
pid := process.Add(desc, cmd) return nil, fmt.Errorf("Start: %v", err)
go func() { }
// In case process became zombie.
select {
case <-time.After(5 * time.Minute):
if errKill := process.Kill(pid); errKill != nil {
log.Error(4, "git_diff.ParsePatch(Kill): %v", err)
}
<-done
// return "", ErrExecTimeout.Error(), ErrExecTimeout
case err = <-done:
process.Remove(pid)
}
}()
return ParsePatch(pid, maxlines, cmd, rd) pid := process.Add(fmt.Sprintf("GetDiffRange (%s)", repoPath), cmd)
defer process.Remove(pid)
diff, err := ParsePatch(maxlines, stdout)
if err != nil {
return nil, fmt.Errorf("ParsePatch: %v", err)
}
if err = cmd.Wait(); err != nil {
return nil, fmt.Errorf("Wait: %v", err)
}
return diff, nil
} }
func GetDiffCommit(repoPath, commitId string, maxlines int) (*Diff, error) { func GetDiffCommit(repoPath, commitId string, maxlines int) (*Diff, error) {

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
0.7.25.1202 Beta 0.7.26.1202 Beta