@@ -76,13 +76,15 @@ const (
76
76
77
77
// DiffLine represents a line difference in a DiffSection.
78
78
type DiffLine struct {
79
- LeftIdx int
80
- RightIdx int
81
- Match int
82
- Type DiffLineType
83
- Content string
84
- Comments []* issues_model.Comment
85
- SectionInfo * DiffLineSectionInfo
79
+ LeftIdx int
80
+ RightIdx int
81
+ Match int
82
+ Type DiffLineType
83
+ Content string
84
+ Comments []* issues_model.Comment
85
+ SectionInfo * DiffLineSectionInfo
86
+ HighlightContent string
87
+ HasHighlightContent bool
86
88
}
87
89
88
90
// DiffLineSectionInfo represents diff line section meta data
@@ -306,13 +308,23 @@ func (diffSection *DiffSection) GetComputedInlineDiffFor(diffLine *DiffLine, loc
306
308
case DiffLineSection :
307
309
return getLineContent (diffLine .Content [1 :], locale )
308
310
case DiffLineAdd :
311
+ if diffLine .HasHighlightContent {
312
+ status , content := charset .EscapeControlHTML (diffLine .HighlightContent , locale )
313
+ return DiffInline {EscapeStatus : status , Content : template .HTML (content )}
314
+ }
315
+
309
316
compareDiffLine = diffSection .GetLine (DiffLineDel , diffLine .RightIdx )
310
317
if compareDiffLine == nil {
311
318
return DiffInlineWithHighlightCode (diffSection .FileName , language , diffLine .Content [1 :], locale )
312
319
}
313
320
diff1 = compareDiffLine .Content
314
321
diff2 = diffLine .Content
315
322
case DiffLineDel :
323
+ if diffLine .HasHighlightContent {
324
+ status , content := charset .EscapeControlHTML (diffLine .HighlightContent , locale )
325
+ return DiffInline {EscapeStatus : status , Content : template .HTML (content )}
326
+ }
327
+
316
328
compareDiffLine = diffSection .GetLine (DiffLineAdd , diffLine .LeftIdx )
317
329
if compareDiffLine == nil {
318
330
return DiffInlineWithHighlightCode (diffSection .FileName , language , diffLine .Content [1 :], locale )
@@ -321,6 +333,11 @@ func (diffSection *DiffSection) GetComputedInlineDiffFor(diffLine *DiffLine, loc
321
333
diff2 = compareDiffLine .Content
322
334
default :
323
335
if strings .IndexByte (" +-" , diffLine .Content [0 ]) > - 1 {
336
+ if diffLine .HasHighlightContent {
337
+ status , content := charset .EscapeControlHTML (diffLine .HighlightContent , locale )
338
+ return DiffInline {EscapeStatus : status , Content : template .HTML (content )}
339
+ }
340
+
324
341
return DiffInlineWithHighlightCode (diffSection .FileName , language , diffLine .Content [1 :], locale )
325
342
}
326
343
return DiffInlineWithHighlightCode (diffSection .FileName , language , diffLine .Content , locale )
@@ -1064,13 +1081,46 @@ type DiffOptions struct {
1064
1081
// Passing the empty string as beforeCommitID returns a diff from the parent commit.
1065
1082
// The whitespaceBehavior is either an empty string or a git flag
1066
1083
func GetDiff (gitRepo * git.Repository , opts * DiffOptions , files ... string ) (* Diff , error ) {
1084
+
1085
+ loadCommitFileContent := func (commit * git.Commit , path , lang string ) ([]string , string ) {
1086
+ entry , err := commit .GetTreeEntryByPath (path )
1087
+ if err != nil {
1088
+ log .Error ("GetTreeEntryByPath: %v" , err )
1089
+ return nil , ""
1090
+ }
1091
+
1092
+ f , err := entry .Blob ().DataAsync ()
1093
+ if err != nil {
1094
+ log .Error ("Blob.DataAsync: %v" , err )
1095
+ return nil , ""
1096
+ }
1097
+
1098
+ // TODO: maybe should limit file size?
1099
+ content , err := io .ReadAll (f )
1100
+ _ = f .Close ()
1101
+ if err != nil {
1102
+ log .Error ("io.ReadAll: %v" , err )
1103
+ return nil , ""
1104
+ }
1105
+
1106
+ highlightedContent , lang , err := highlight .File (path , lang , content )
1107
+ if err != nil {
1108
+ log .Error ("highlight.File: %v" , err )
1109
+ return nil , ""
1110
+ }
1111
+
1112
+ return highlightedContent , lang
1113
+ }
1114
+
1067
1115
repoPath := gitRepo .Path
1068
1116
1069
1117
commit , err := gitRepo .GetCommit (opts .AfterCommitID )
1070
1118
if err != nil {
1071
1119
return nil , err
1072
1120
}
1073
1121
1122
+ var beforeCommit * git.Commit
1123
+
1074
1124
cmdDiff := git .NewCommand (gitRepo .Ctx )
1075
1125
if (len (opts .BeforeCommitID ) == 0 || opts .BeforeCommitID == git .EmptySHA ) && commit .ParentCount () == 0 {
1076
1126
cmdDiff .AddArguments ("diff" , "--src-prefix=\\ a/" , "--dst-prefix=\\ b/" , "-M" ).
@@ -1082,6 +1132,12 @@ func GetDiff(gitRepo *git.Repository, opts *DiffOptions, files ...string) (*Diff
1082
1132
if len (actualBeforeCommitID ) == 0 {
1083
1133
parentCommit , _ := commit .Parent (0 )
1084
1134
actualBeforeCommitID = parentCommit .ID .String ()
1135
+ beforeCommit = parentCommit
1136
+ } else {
1137
+ beforeCommit , err = gitRepo .GetCommit (actualBeforeCommitID )
1138
+ if err != nil {
1139
+ return nil , err
1140
+ }
1085
1141
}
1086
1142
1087
1143
cmdDiff .AddArguments ("diff" , "--src-prefix=\\ a/" , "--dst-prefix=\\ b/" , "-M" ).
@@ -1172,6 +1228,35 @@ func GetDiff(gitRepo *git.Repository, opts *DiffOptions, files ...string) (*Diff
1172
1228
if tailSection != nil {
1173
1229
diffFile .Sections = append (diffFile .Sections , tailSection )
1174
1230
}
1231
+
1232
+ // render full file for edited file
1233
+ if diffFile .Type != DiffFileChange || beforeCommit == nil {
1234
+ continue
1235
+ }
1236
+
1237
+ var newContent []string
1238
+ oldContent , _ := loadCommitFileContent (beforeCommit , diffFile .OldName , diffFile .Language )
1239
+ newContent , diffFile .Language = loadCommitFileContent (commit , diffFile .Name , diffFile .Language )
1240
+
1241
+ for _ , diffSection := range diffFile .Sections {
1242
+ for _ , diffLine := range diffSection .Lines {
1243
+ switch diffLine .Type {
1244
+ case DiffLineAdd :
1245
+ fallthrough
1246
+ case DiffLinePlain :
1247
+ if diffLine .RightIdx > 0 && diffLine .RightIdx <= len (newContent ) {
1248
+ diffLine .HighlightContent = newContent [diffLine .RightIdx - 1 ]
1249
+ diffLine .HasHighlightContent = true
1250
+ }
1251
+
1252
+ case DiffLineDel :
1253
+ if diffLine .LeftIdx > 0 && diffLine .LeftIdx <= len (oldContent ) {
1254
+ diffLine .HighlightContent = oldContent [diffLine .LeftIdx - 1 ]
1255
+ diffLine .HasHighlightContent = true
1256
+ }
1257
+ }
1258
+ }
1259
+ }
1175
1260
}
1176
1261
1177
1262
separator := "..."
0 commit comments