add submodule diff links (#33097)

This adds links to submodules in diffs, similar to the existing link
when viewing a repo at a specific commit. It does this by expanding diff
parsing to recognize changes to submodules, and find the specific refs
that are added, deleted or changed.

Related #25888

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
This commit is contained in:
Rowan Bohde 2025-01-07 19:38:30 -06:00 committed by GitHub
parent ec84687df9
commit a8e7caedfa
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
23 changed files with 688 additions and 339 deletions

View file

@ -360,7 +360,6 @@ type DiffFile struct {
IsLFSFile bool
IsRenamed bool
IsAmbiguous bool
IsSubmodule bool
Sections []*DiffSection
IsIncomplete bool
IsIncompleteLineTooLong bool
@ -372,6 +371,9 @@ type DiffFile struct {
Language string
Mode string
OldMode string
IsSubmodule bool // if IsSubmodule==true, then there must be a SubmoduleDiffInfo
SubmoduleDiffInfo *SubmoduleDiffInfo
}
// GetType returns type of diff file.
@ -609,9 +611,8 @@ parsingLoop:
if strings.HasPrefix(line, "new mode ") {
curFile.Mode = prepareValue(line, "new mode ")
}
if strings.HasSuffix(line, " 160000\n") {
curFile.IsSubmodule = true
curFile.IsSubmodule, curFile.SubmoduleDiffInfo = true, &SubmoduleDiffInfo{}
}
case strings.HasPrefix(line, "rename from "):
curFile.IsRenamed = true
@ -646,17 +647,17 @@ parsingLoop:
curFile.Mode = prepareValue(line, "new file mode ")
}
if strings.HasSuffix(line, " 160000\n") {
curFile.IsSubmodule = true
curFile.IsSubmodule, curFile.SubmoduleDiffInfo = true, &SubmoduleDiffInfo{}
}
case strings.HasPrefix(line, "deleted"):
curFile.Type = DiffFileDel
curFile.IsDeleted = true
if strings.HasSuffix(line, " 160000\n") {
curFile.IsSubmodule = true
curFile.IsSubmodule, curFile.SubmoduleDiffInfo = true, &SubmoduleDiffInfo{}
}
case strings.HasPrefix(line, "index"):
if strings.HasSuffix(line, " 160000\n") {
curFile.IsSubmodule = true
curFile.IsSubmodule, curFile.SubmoduleDiffInfo = true, &SubmoduleDiffInfo{}
}
case strings.HasPrefix(line, "similarity index 100%"):
curFile.Type = DiffFileRename
@ -915,6 +916,13 @@ func parseHunks(ctx context.Context, curFile *DiffFile, maxLines, maxLineCharact
}
}
curSection.Lines = append(curSection.Lines, diffLine)
// Parse submodule additions
if curFile.SubmoduleDiffInfo != nil {
if ref, found := bytes.CutPrefix(lineBytes, []byte("+Subproject commit ")); found {
curFile.SubmoduleDiffInfo.NewRefID = string(bytes.TrimSpace(ref))
}
}
case '-':
curFileLinesCount++
curFile.Deletion++
@ -936,6 +944,13 @@ func parseHunks(ctx context.Context, curFile *DiffFile, maxLines, maxLineCharact
lastLeftIdx = len(curSection.Lines)
}
curSection.Lines = append(curSection.Lines, diffLine)
// Parse submodule deletion
if curFile.SubmoduleDiffInfo != nil {
if ref, found := bytes.CutPrefix(lineBytes, []byte("-Subproject commit ")); found {
curFile.SubmoduleDiffInfo.PreviousRefID = string(bytes.TrimSpace(ref))
}
}
case ' ':
curFileLinesCount++
if maxLines > -1 && curFileLinesCount >= maxLines {
@ -1195,6 +1210,11 @@ func GetDiff(ctx context.Context, gitRepo *git.Repository, opts *DiffOptions, fi
}
}
// Populate Submodule URLs
if diffFile.SubmoduleDiffInfo != nil {
diffFile.SubmoduleDiffInfo.PopulateURL(diffFile, beforeCommit, commit)
}
if !isVendored.Has() {
isVendored = optional.Some(analyze.IsVendor(diffFile.Name))
}