diff options
Diffstat (limited to 'services')
-rw-r--r-- | services/gitdiff/gitdiff.go | 78 |
1 files changed, 78 insertions, 0 deletions
diff --git a/services/gitdiff/gitdiff.go b/services/gitdiff/gitdiff.go index 4be115f030..65d0dab4ca 100644 --- a/services/gitdiff/gitdiff.go +++ b/services/gitdiff/gitdiff.go @@ -23,6 +23,7 @@ import ( "time" "code.gitea.io/gitea/models" + "code.gitea.io/gitea/modules/analyze" "code.gitea.io/gitea/modules/charset" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/highlight" @@ -30,6 +31,7 @@ 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" @@ -593,6 +595,8 @@ type DiffFile struct { IsIncomplete bool IsIncompleteLineTooLong bool IsProtected bool + IsGenerated bool + IsVendored bool } // GetType returns type of diff file. @@ -1268,7 +1272,81 @@ func GetDiffRangeWithWhitespaceBehavior(gitRepo *git.Repository, beforeCommitID, if err != nil { return nil, fmt.Errorf("ParsePatch: %v", err) } + + var checker *git.CheckAttributeReader + + if git.CheckGitVersionAtLeast("1.7.8") == nil { + indexFilename, deleteTemporaryFile, err := gitRepo.ReadTreeToTemporaryIndex(afterCommitID) + if err == nil { + defer deleteTemporaryFile() + workdir, err := ioutil.TempDir("", "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"}, + Repo: gitRepo, + IndexFile: indexFilename, + WorkTree: workdir, + } + ctx, cancel := context.WithCancel(git.DefaultContext) + if err := checker.Init(ctx); err != nil { + log.Error("Unable to open checker for %s. Error: %v", afterCommitID, err) + } else { + go func() { + err = checker.Run() + if err != nil && err != ctx.Err() { + log.Error("Unable to open checker for %s. Error: %v", afterCommitID, err) + } + cancel() + }() + } + defer func() { + cancel() + }() + } + } + for _, diffFile := range diff.Files { + + gotVendor := false + gotGenerated := false + if checker != nil { + attrs, err := checker.CheckPath(diffFile.Name) + if err == nil { + if vendored, has := attrs["linguist-vendored"]; has { + if vendored == "set" || vendored == "true" { + diffFile.IsVendored = true + gotVendor = true + } else { + gotVendor = vendored == "false" + } + } + if generated, has := attrs["linguist-generated"]; has { + if generated == "set" || generated == "true" { + diffFile.IsGenerated = true + gotGenerated = true + } else { + gotGenerated = generated == "false" + } + } + } else { + log.Error("Unexpected error: %v", err) + } + } + + if !gotVendor { + diffFile.IsVendored = analyze.IsVendor(diffFile.Name) + } + if !gotGenerated { + diffFile.IsGenerated = analyze.IsGenerated(diffFile.Name) + } + tailSection := diffFile.GetTailSection(gitRepo, beforeCommitID, afterCommitID) if tailSection != nil { diffFile.Sections = append(diffFile.Sections, tailSection) |