mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-26 12:27:06 +00:00 
			
		
		
		
	Fix blame view missing lines (#22826)
Creating a new buffered reader for every part of the blame can miss lines, as it will read and buffer bytes that the next buffered reader will not get. Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
This commit is contained in:
		 Brecht Van Lommel
					Brecht Van Lommel
				
			
				
					committed by
					
						 GitHub
						GitHub
					
				
			
			
				
	
			
			
			 GitHub
						GitHub
					
				
			
						parent
						
							4dd7d61ac8
						
					
				
				
					commit
					87261f3fb9
				
			| @@ -20,11 +20,12 @@ type BlamePart struct { | |||||||
|  |  | ||||||
| // BlameReader returns part of file blame one by one | // BlameReader returns part of file blame one by one | ||||||
| type BlameReader struct { | type BlameReader struct { | ||||||
| 	cmd     *Command | 	cmd            *Command | ||||||
| 	output  io.WriteCloser | 	output         io.WriteCloser | ||||||
| 	reader  io.ReadCloser | 	reader         io.ReadCloser | ||||||
| 	done    chan error | 	bufferedReader *bufio.Reader | ||||||
| 	lastSha *string | 	done           chan error | ||||||
|  | 	lastSha        *string | ||||||
| } | } | ||||||
|  |  | ||||||
| var shaLineRegex = regexp.MustCompile("^([a-z0-9]{40})") | var shaLineRegex = regexp.MustCompile("^([a-z0-9]{40})") | ||||||
| @@ -33,8 +34,6 @@ var shaLineRegex = regexp.MustCompile("^([a-z0-9]{40})") | |||||||
| func (r *BlameReader) NextPart() (*BlamePart, error) { | func (r *BlameReader) NextPart() (*BlamePart, error) { | ||||||
| 	var blamePart *BlamePart | 	var blamePart *BlamePart | ||||||
|  |  | ||||||
| 	reader := bufio.NewReader(r.reader) |  | ||||||
|  |  | ||||||
| 	if r.lastSha != nil { | 	if r.lastSha != nil { | ||||||
| 		blamePart = &BlamePart{*r.lastSha, make([]string, 0)} | 		blamePart = &BlamePart{*r.lastSha, make([]string, 0)} | ||||||
| 	} | 	} | ||||||
| @@ -44,7 +43,7 @@ func (r *BlameReader) NextPart() (*BlamePart, error) { | |||||||
| 	var err error | 	var err error | ||||||
|  |  | ||||||
| 	for err != io.EOF { | 	for err != io.EOF { | ||||||
| 		line, isPrefix, err = reader.ReadLine() | 		line, isPrefix, err = r.bufferedReader.ReadLine() | ||||||
| 		if err != nil && err != io.EOF { | 		if err != nil && err != io.EOF { | ||||||
| 			return blamePart, err | 			return blamePart, err | ||||||
| 		} | 		} | ||||||
| @@ -66,7 +65,7 @@ func (r *BlameReader) NextPart() (*BlamePart, error) { | |||||||
| 				r.lastSha = &sha1 | 				r.lastSha = &sha1 | ||||||
| 				// need to munch to end of line... | 				// need to munch to end of line... | ||||||
| 				for isPrefix { | 				for isPrefix { | ||||||
| 					_, isPrefix, err = reader.ReadLine() | 					_, isPrefix, err = r.bufferedReader.ReadLine() | ||||||
| 					if err != nil && err != io.EOF { | 					if err != nil && err != io.EOF { | ||||||
| 						return blamePart, err | 						return blamePart, err | ||||||
| 					} | 					} | ||||||
| @@ -81,7 +80,7 @@ func (r *BlameReader) NextPart() (*BlamePart, error) { | |||||||
|  |  | ||||||
| 		// need to munch to end of line... | 		// need to munch to end of line... | ||||||
| 		for isPrefix { | 		for isPrefix { | ||||||
| 			_, isPrefix, err = reader.ReadLine() | 			_, isPrefix, err = r.bufferedReader.ReadLine() | ||||||
| 			if err != nil && err != io.EOF { | 			if err != nil && err != io.EOF { | ||||||
| 				return blamePart, err | 				return blamePart, err | ||||||
| 			} | 			} | ||||||
| @@ -96,6 +95,7 @@ func (r *BlameReader) NextPart() (*BlamePart, error) { | |||||||
| // Close BlameReader - don't run NextPart after invoking that | // Close BlameReader - don't run NextPart after invoking that | ||||||
| func (r *BlameReader) Close() error { | func (r *BlameReader) Close() error { | ||||||
| 	err := <-r.done | 	err := <-r.done | ||||||
|  | 	r.bufferedReader = nil | ||||||
| 	_ = r.reader.Close() | 	_ = r.reader.Close() | ||||||
| 	_ = r.output.Close() | 	_ = r.output.Close() | ||||||
| 	return err | 	return err | ||||||
| @@ -126,10 +126,13 @@ func CreateBlameReader(ctx context.Context, repoPath, commitID, file string) (*B | |||||||
| 		done <- err | 		done <- err | ||||||
| 	}(cmd, repoPath, stdout, done) | 	}(cmd, repoPath, stdout, done) | ||||||
|  |  | ||||||
|  | 	bufferedReader := bufio.NewReader(reader) | ||||||
|  |  | ||||||
| 	return &BlameReader{ | 	return &BlameReader{ | ||||||
| 		cmd:    cmd, | 		cmd:            cmd, | ||||||
| 		output: stdout, | 		output:         stdout, | ||||||
| 		reader: reader, | 		reader:         reader, | ||||||
| 		done:   done, | 		bufferedReader: bufferedReader, | ||||||
|  | 		done:           done, | ||||||
| 	}, nil | 	}, nil | ||||||
| } | } | ||||||
|   | |||||||
| @@ -28,7 +28,7 @@ func TestReadingBlameOutput(t *testing.T) { | |||||||
| 		}, | 		}, | ||||||
| 		{ | 		{ | ||||||
| 			"f32b0a9dfd09a60f616f29158f772cedd89942d2", | 			"f32b0a9dfd09a60f616f29158f772cedd89942d2", | ||||||
| 			[]string{}, | 			[]string{"", "Do not make any changes to this repo it is used for unit testing"}, | ||||||
| 		}, | 		}, | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user