mirror of
				https://gitee.com/gitea/gitea
				synced 2025-11-04 16:40:24 +08:00 
			
		
		
		
	#2071 Diff is not showing full content when has super long one line
This commit is contained in:
		@@ -5,7 +5,7 @@ Gogs - Go Git Service [
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
##### Current version: 0.7.25 Beta
 | 
					##### Current version: 0.7.26 Beta
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<table>
 | 
					<table>
 | 
				
			||||||
    <tr>
 | 
					    <tr>
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								gogs.go
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								gogs.go
									
									
									
									
									
								
							@@ -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())
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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)
 | 
					 | 
				
			||||||
	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)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}()
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return ParsePatch(pid, maxlines, cmd, rd)
 | 
						if err = cmd.Start(); err != nil {
 | 
				
			||||||
 | 
							return nil, fmt.Errorf("Start: %v", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						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
											
										
									
								
							@@ -1 +1 @@
 | 
				
			|||||||
0.7.25.1202 Beta
 | 
					0.7.26.1202 Beta
 | 
				
			||||||
		Reference in New Issue
	
	Block a user