Просмотр исходного кода

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

Unknwon лет назад: 8
Родитель
Сommit
926e91820a
5 измененных файлов с 77 добавлено и 59 удалено
  1. 1 1
      README.md
  2. 1 1
      gogs.go
  3. 72 54
      models/git_diff.go
  4. 2 2
      modules/bindata/bindata.go
  5. 1 1
      templates/.VERSION

+ 1 - 1
README.md

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

+ 1 - 1
gogs.go

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

+ 72 - 54
models/git_diff.go

@@ -12,15 +12,14 @@ import (
 	"os"
 	"os/exec"
 	"strings"
-	"time"
 
+	"github.com/Unknwon/com"
 	"golang.org/x/net/html/charset"
 	"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/git"
 	"github.com/gogits/gogs/modules/log"
 	"github.com/gogits/gogs/modules/process"
 )
@@ -80,36 +79,50 @@ func (diff *Diff) NumFiles() int {
 
 const DIFF_HEAD = "diff --git "
 
-func ParsePatch(pid int64, maxlines int, cmd *exec.Cmd, reader io.Reader) (*Diff, error) {
-	scanner := bufio.NewScanner(reader)
+func ParsePatch(maxlines int, reader io.Reader) (*Diff, error) {
 	var (
+		diff = &Diff{Files: make([]*DiffFile, 0)}
+
 		curFile    *DiffFile
 		curSection = &DiffSection{
 			Lines: make([]*DiffLine, 0, 10),
 		}
 
 		leftLine, rightLine int
-		// FIXME: Should use cache in the future.
-		buf bytes.Buffer
+		lineCount           int
 	)
 
-	diff := &Diff{Files: make([]*DiffFile, 0)}
-	var i int
-	for scanner.Scan() {
-		line := scanner.Text()
+	input := bufio.NewReader(reader)
+	isEOF := false
+	for {
+		if isEOF {
+			break
+		}
 
-		if strings.HasPrefix(line, "+++ ") || strings.HasPrefix(line, "--- ") {
-			continue
+		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 line == "" {
+		if strings.HasPrefix(line, "+++ ") || strings.HasPrefix(line, "--- ") {
+			continue
+		} else if len(line) == 0 {
 			continue
 		}
 
-		i = i + 1
+		lineCount++
 
 		// Diff data too large, we only show the first about maxlines lines
-		if i >= maxlines {
+		if lineCount >= maxlines {
 			log.Warn("Diff data too large")
 			diff.Files = 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)
 
 			// 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 {
-				case strings.HasPrefix(scanner.Text(), "new file"):
+				case strings.HasPrefix(line, "new file"):
 					curFile.Type = DIFF_FILE_ADD
 					curFile.IsCreated = true
-				case strings.HasPrefix(scanner.Text(), "deleted"):
+				case strings.HasPrefix(line, "deleted"):
 					curFile.Type = DIFF_FILE_DEL
 					curFile.IsDeleted = true
-				case strings.HasPrefix(scanner.Text(), "index"):
+				case strings.HasPrefix(line, "index"):
 					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.IsRenamed = true
 					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 {
 		buf.Reset()
 		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
 }
 
-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)
 	if err != nil {
 		return nil, err
 	}
 
-	commit, err := repo.GetCommit(afterCommitId)
+	commit, err := repo.GetCommit(afterCommitID)
 	if err != nil {
 		return nil, err
 	}
 
-	rd, wr := io.Pipe()
 	var cmd *exec.Cmd
 	// if "after" commit given
-	if beforeCommitId == "" {
+	if len(beforeCommitID) == 0 {
 		// First commit of repository.
 		if commit.ParentCount() == 0 {
-			cmd = exec.Command("git", "show", afterCommitId)
+			cmd = exec.Command("git", "show", afterCommitID)
 		} else {
 			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 {
-		cmd = exec.Command("git", "diff", "-M", beforeCommitId, afterCommitId)
+		cmd = exec.Command("git", "diff", "-M", beforeCommitID, afterCommitID)
 	}
 	cmd.Dir = repoPath
-	cmd.Stdout = wr
-	cmd.Stdin = os.Stdin
 	cmd.Stderr = os.Stderr
 
-	done := make(chan error)
-	go func() {
-		cmd.Start()
-		done <- cmd.Wait()
-		wr.Close()
-	}()
-	defer rd.Close()
-
-	desc := fmt.Sprintf("GetDiffRange(%s)", repoPath)
-	pid := process.Add(desc, cmd)
-	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)
-		}
-	}()
+	stdout, err := cmd.StdoutPipe()
+	if err != nil {
+		return nil, fmt.Errorf("StdoutPipe: %v", err)
+	}
+
+	if err = cmd.Start(); err != nil {
+		return nil, fmt.Errorf("Start: %v", err)
+	}
 
-	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) {

Разница между файлами не показана из-за своего большого размера
+ 2 - 2
modules/bindata/bindata.go


+ 1 - 1
templates/.VERSION

@@ -1 +1 @@
-0.7.25.1202 Beta
+0.7.26.1202 Beta