aboutsummaryrefslogtreecommitdiffstats
path: root/services/gitdiff
diff options
context:
space:
mode:
authorzeripath <art27@cantab.net>2021-11-17 20:37:00 +0000
committerGitHub <noreply@github.com>2021-11-17 20:37:00 +0000
commit3c4724d70e4ac7bfc06b97f6fad8936f97479b6b (patch)
tree754286def789b823e020d3ccfafae148d0017b62 /services/gitdiff
parent81a4fc752833101dd7d6b4f612bccc4b29c98dff (diff)
downloadgitea-3c4724d70e4ac7bfc06b97f6fad8936f97479b6b.tar.gz
gitea-3c4724d70e4ac7bfc06b97f6fad8936f97479b6b.zip
Add .gitattribute assisted language detection to blame, diff and render (#17590)
Use check attribute code to check the assigned language of a file and send that in to chroma as a hint for the language of the file. Signed-off-by: Andrew Thornton <art27@cantab.net>
Diffstat (limited to 'services/gitdiff')
-rw-r--r--services/gitdiff/gitdiff.go45
-rw-r--r--services/gitdiff/gitdiff_test.go2
2 files changed, 25 insertions, 22 deletions
diff --git a/services/gitdiff/gitdiff.go b/services/gitdiff/gitdiff.go
index 614f8104ec..33e66e89ec 100644
--- a/services/gitdiff/gitdiff.go
+++ b/services/gitdiff/gitdiff.go
@@ -31,7 +31,6 @@ import (
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/process"
"code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/util"
"github.com/sergi/go-diff/diffmatchpatch"
stdcharset "golang.org/x/net/html/charset"
@@ -178,6 +177,7 @@ func getLineContent(content string) string {
// DiffSection represents a section of a DiffFile.
type DiffSection struct {
+ file *DiffFile
FileName string
Name string
Lines []*DiffLine
@@ -546,6 +546,11 @@ func (diffSection *DiffSection) GetComputedInlineDiffFor(diffLine *DiffLine) tem
diff2 string
)
+ language := ""
+ if diffSection.file != nil {
+ language = diffSection.file.Language
+ }
+
// try to find equivalent diff line. ignore, otherwise
switch diffLine.Type {
case DiffLineSection:
@@ -553,25 +558,25 @@ func (diffSection *DiffSection) GetComputedInlineDiffFor(diffLine *DiffLine) tem
case DiffLineAdd:
compareDiffLine = diffSection.GetLine(DiffLineDel, diffLine.RightIdx)
if compareDiffLine == nil {
- return template.HTML(highlight.Code(diffSection.FileName, diffLine.Content[1:]))
+ return template.HTML(highlight.Code(diffSection.FileName, language, diffLine.Content[1:]))
}
diff1 = compareDiffLine.Content
diff2 = diffLine.Content
case DiffLineDel:
compareDiffLine = diffSection.GetLine(DiffLineAdd, diffLine.LeftIdx)
if compareDiffLine == nil {
- return template.HTML(highlight.Code(diffSection.FileName, diffLine.Content[1:]))
+ return template.HTML(highlight.Code(diffSection.FileName, language, diffLine.Content[1:]))
}
diff1 = diffLine.Content
diff2 = compareDiffLine.Content
default:
if strings.IndexByte(" +-", diffLine.Content[0]) > -1 {
- return template.HTML(highlight.Code(diffSection.FileName, diffLine.Content[1:]))
+ return template.HTML(highlight.Code(diffSection.FileName, language, diffLine.Content[1:]))
}
- return template.HTML(highlight.Code(diffSection.FileName, diffLine.Content))
+ return template.HTML(highlight.Code(diffSection.FileName, language, diffLine.Content))
}
- diffRecord := diffMatchPatch.DiffMain(highlight.Code(diffSection.FileName, diff1[1:]), highlight.Code(diffSection.FileName, diff2[1:]), true)
+ diffRecord := diffMatchPatch.DiffMain(highlight.Code(diffSection.FileName, language, diff1[1:]), highlight.Code(diffSection.FileName, language, diff2[1:]), true)
diffRecord = diffMatchPatch.DiffCleanupEfficiency(diffRecord)
return diffToHTML(diffSection.FileName, diffRecord, diffLine.Type)
@@ -597,6 +602,7 @@ type DiffFile struct {
IsProtected bool
IsGenerated bool
IsVendored bool
+ Language string
}
// GetType returns type of diff file.
@@ -1008,7 +1014,7 @@ func parseHunks(curFile *DiffFile, maxLines, maxLineCharacters int, input *bufio
line := sb.String()
// Create a new section to represent this hunk
- curSection = &DiffSection{}
+ curSection = &DiffSection{file: curFile}
lastLeftIdx = -1
curFile.Sections = append(curFile.Sections, curSection)
@@ -1048,7 +1054,7 @@ func parseHunks(curFile *DiffFile, maxLines, maxLineCharacters int, input *bufio
rightLine++
if curSection == nil {
// Create a new section to represent this hunk
- curSection = &DiffSection{}
+ curSection = &DiffSection{file: curFile}
curFile.Sections = append(curFile.Sections, curSection)
lastLeftIdx = -1
}
@@ -1074,7 +1080,7 @@ func parseHunks(curFile *DiffFile, maxLines, maxLineCharacters int, input *bufio
}
if curSection == nil {
// Create a new section to represent this hunk
- curSection = &DiffSection{}
+ curSection = &DiffSection{file: curFile}
curFile.Sections = append(curFile.Sections, curSection)
lastLeftIdx = -1
}
@@ -1094,7 +1100,7 @@ func parseHunks(curFile *DiffFile, maxLines, maxLineCharacters int, input *bufio
lastLeftIdx = -1
if curSection == nil {
// Create a new section to represent this hunk
- curSection = &DiffSection{}
+ curSection = &DiffSection{file: curFile}
curFile.Sections = append(curFile.Sections, curSection)
}
curSection.Lines = append(curSection.Lines, diffLine)
@@ -1302,23 +1308,15 @@ func GetDiffRangeWithWhitespaceBehavior(gitRepo *git.Repository, beforeCommitID,
var checker *git.CheckAttributeReader
if git.CheckGitVersionAtLeast("1.7.8") == nil {
- indexFilename, deleteTemporaryFile, err := gitRepo.ReadTreeToTemporaryIndex(afterCommitID)
+ indexFilename, worktree, deleteTemporaryFile, err := gitRepo.ReadTreeToTemporaryIndex(afterCommitID)
if err == nil {
defer deleteTemporaryFile()
- workdir, err := os.MkdirTemp("", "empty-work-dir")
- if err != nil {
- log.Error("Unable to create temporary directory: %v", err)
- return nil, err
- }
- defer func() {
- _ = util.RemoveAll(workdir)
- }()
checker = &git.CheckAttributeReader{
- Attributes: []string{"linguist-vendored", "linguist-generated"},
+ Attributes: []string{"linguist-vendored", "linguist-generated", "linguist-language", "gitlab-language"},
Repo: gitRepo,
IndexFile: indexFilename,
- WorkTree: workdir,
+ WorkTree: worktree,
}
ctx, cancel := context.WithCancel(git.DefaultContext)
if err := checker.Init(ctx); err != nil {
@@ -1361,6 +1359,11 @@ func GetDiffRangeWithWhitespaceBehavior(gitRepo *git.Repository, beforeCommitID,
gotGenerated = generated == "false"
}
}
+ if language, has := attrs["linguist-language"]; has && language != "unspecified" && language != "" {
+ diffFile.Language = language
+ } else if language, has := attrs["gitlab-language"]; has && language != "unspecified" && language != "" {
+ diffFile.Language = language
+ }
} else {
log.Error("Unexpected error: %v", err)
}
diff --git a/services/gitdiff/gitdiff_test.go b/services/gitdiff/gitdiff_test.go
index aefd396ebb..c6c6f3b0e3 100644
--- a/services/gitdiff/gitdiff_test.go
+++ b/services/gitdiff/gitdiff_test.go
@@ -533,7 +533,7 @@ func TestGetDiffRangeWithWhitespaceBehavior(t *testing.T) {
func TestDiffToHTML_14231(t *testing.T) {
setting.Cfg = ini.Empty()
- diffRecord := diffMatchPatch.DiffMain(highlight.Code("main.v", " run()\n"), highlight.Code("main.v", " run(db)\n"), true)
+ diffRecord := diffMatchPatch.DiffMain(highlight.Code("main.v", "", " run()\n"), highlight.Code("main.v", "", " run(db)\n"), true)
diffRecord = diffMatchPatch.DiffCleanupEfficiency(diffRecord)
expected := ` <span class="n">run</span><span class="added-code"><span class="o">(</span><span class="n">db</span></span><span class="o">)</span>`