Skip to content

Commit 33850a8

Browse files
lunnywxiaoguang
andauthored
Fix submodule parsing (#32571)
Fix #32568, parse `.gitmodules` correctly --------- Co-authored-by: wxiaoguang <[email protected]>
1 parent 407b6e6 commit 33850a8

20 files changed

+492
-360
lines changed

modules/git/commit.go

+1-65
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import (
99
"bytes"
1010
"context"
1111
"errors"
12-
"fmt"
1312
"io"
1413
"os/exec"
1514
"strconv"
@@ -29,7 +28,7 @@ type Commit struct {
2928
Signature *CommitSignature
3029

3130
Parents []ObjectID // ID strings
32-
submoduleCache *ObjectCache
31+
submoduleCache *ObjectCache[*SubModule]
3332
}
3433

3534
// CommitSignature represents a git commit signature part.
@@ -357,69 +356,6 @@ func (c *Commit) GetFileContent(filename string, limit int) (string, error) {
357356
return string(bytes), nil
358357
}
359358

360-
// GetSubModules get all the sub modules of current revision git tree
361-
func (c *Commit) GetSubModules() (*ObjectCache, error) {
362-
if c.submoduleCache != nil {
363-
return c.submoduleCache, nil
364-
}
365-
366-
entry, err := c.GetTreeEntryByPath(".gitmodules")
367-
if err != nil {
368-
if _, ok := err.(ErrNotExist); ok {
369-
return nil, nil
370-
}
371-
return nil, err
372-
}
373-
374-
rd, err := entry.Blob().DataAsync()
375-
if err != nil {
376-
return nil, err
377-
}
378-
379-
defer rd.Close()
380-
scanner := bufio.NewScanner(rd)
381-
c.submoduleCache = newObjectCache()
382-
var ismodule bool
383-
var path string
384-
for scanner.Scan() {
385-
if strings.HasPrefix(scanner.Text(), "[submodule") {
386-
ismodule = true
387-
continue
388-
}
389-
if ismodule {
390-
fields := strings.Split(scanner.Text(), "=")
391-
k := strings.TrimSpace(fields[0])
392-
if k == "path" {
393-
path = strings.TrimSpace(fields[1])
394-
} else if k == "url" {
395-
c.submoduleCache.Set(path, &SubModule{path, strings.TrimSpace(fields[1])})
396-
ismodule = false
397-
}
398-
}
399-
}
400-
if err = scanner.Err(); err != nil {
401-
return nil, fmt.Errorf("GetSubModules scan: %w", err)
402-
}
403-
404-
return c.submoduleCache, nil
405-
}
406-
407-
// GetSubModule get the sub module according entryname
408-
func (c *Commit) GetSubModule(entryname string) (*SubModule, error) {
409-
modules, err := c.GetSubModules()
410-
if err != nil {
411-
return nil, err
412-
}
413-
414-
if modules != nil {
415-
module, has := modules.Get(entryname)
416-
if has {
417-
return module.(*SubModule), nil
418-
}
419-
}
420-
return nil, nil
421-
}
422-
423359
// GetBranchName gets the closest branch name (as returned by 'git name-rev --name-only')
424360
func (c *Commit) GetBranchName() (string, error) {
425361
cmd := NewCommand(c.repo.Ctx, "name-rev")

modules/git/commit_info.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,5 @@ package git
77
type CommitInfo struct {
88
Entry *TreeEntry
99
Commit *Commit
10-
SubModuleFile *SubModuleFile
10+
SubModuleFile *CommitSubModuleFile
1111
}

modules/git/commit_info_gogit.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ func (tes Entries) GetCommitsInfo(ctx context.Context, commit *Commit, treePath
7171
commitsInfo[i].Commit = entryCommit
7272
}
7373

74-
// If the entry if a submodule add a submodule file for this
74+
// If the entry is a submodule add a submodule file for this
7575
if entry.IsSubModule() {
7676
subModuleURL := ""
7777
var fullPath string
@@ -85,7 +85,7 @@ func (tes Entries) GetCommitsInfo(ctx context.Context, commit *Commit, treePath
8585
} else if subModule != nil {
8686
subModuleURL = subModule.URL
8787
}
88-
subModuleFile := NewSubModuleFile(commitsInfo[i].Commit, subModuleURL, entry.ID.String())
88+
subModuleFile := NewCommitSubModuleFile(subModuleURL, entry.ID.String())
8989
commitsInfo[i].SubModuleFile = subModuleFile
9090
}
9191
}

modules/git/commit_info_nogogit.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ func (tes Entries) GetCommitsInfo(ctx context.Context, commit *Commit, treePath
7979
} else if subModule != nil {
8080
subModuleURL = subModule.URL
8181
}
82-
subModuleFile := NewSubModuleFile(commitsInfo[i].Commit, subModuleURL, entry.ID.String())
82+
subModuleFile := NewCommitSubModuleFile(subModuleURL, entry.ID.String())
8383
commitsInfo[i].SubModuleFile = subModuleFile
8484
}
8585
}

modules/git/commit_submodule.go

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// Copyright 2024 The Gitea Authors. All rights reserved.
2+
// SPDX-License-Identifier: MIT
3+
4+
package git
5+
6+
// GetSubModules get all the submodules of current revision git tree
7+
func (c *Commit) GetSubModules() (*ObjectCache[*SubModule], error) {
8+
if c.submoduleCache != nil {
9+
return c.submoduleCache, nil
10+
}
11+
12+
entry, err := c.GetTreeEntryByPath(".gitmodules")
13+
if err != nil {
14+
if _, ok := err.(ErrNotExist); ok {
15+
return nil, nil
16+
}
17+
return nil, err
18+
}
19+
20+
rd, err := entry.Blob().DataAsync()
21+
if err != nil {
22+
return nil, err
23+
}
24+
defer rd.Close()
25+
26+
// at the moment we do not strictly limit the size of the .gitmodules file because some users would have huge .gitmodules files (>1MB)
27+
c.submoduleCache, err = configParseSubModules(rd)
28+
if err != nil {
29+
return nil, err
30+
}
31+
return c.submoduleCache, nil
32+
}
33+
34+
// GetSubModule get the submodule according entry name
35+
func (c *Commit) GetSubModule(entryName string) (*SubModule, error) {
36+
modules, err := c.GetSubModules()
37+
if err != nil {
38+
return nil, err
39+
}
40+
41+
if modules != nil {
42+
if module, has := modules.Get(entryName); has {
43+
return module, nil
44+
}
45+
}
46+
return nil, nil
47+
}

modules/git/submodule.go modules/git/commit_submodule_file.go

+8-16
Original file line numberDiff line numberDiff line change
@@ -15,24 +15,15 @@ import (
1515

1616
var scpSyntax = regexp.MustCompile(`^([a-zA-Z0-9_]+@)?([a-zA-Z0-9._-]+):(.*)$`)
1717

18-
// SubModule submodule is a reference on git repository
19-
type SubModule struct {
20-
Name string
21-
URL string
22-
}
23-
24-
// SubModuleFile represents a file with submodule type.
25-
type SubModuleFile struct {
26-
*Commit
27-
18+
// CommitSubModuleFile represents a file with submodule type.
19+
type CommitSubModuleFile struct {
2820
refURL string
2921
refID string
3022
}
3123

32-
// NewSubModuleFile create a new submodule file
33-
func NewSubModuleFile(c *Commit, refURL, refID string) *SubModuleFile {
34-
return &SubModuleFile{
35-
Commit: c,
24+
// NewCommitSubModuleFile create a new submodule file
25+
func NewCommitSubModuleFile(refURL, refID string) *CommitSubModuleFile {
26+
return &CommitSubModuleFile{
3627
refURL: refURL,
3728
refID: refID,
3829
}
@@ -109,11 +100,12 @@ func getRefURL(refURL, urlPrefix, repoFullName, sshDomain string) string {
109100
}
110101

111102
// RefURL guesses and returns reference URL.
112-
func (sf *SubModuleFile) RefURL(urlPrefix, repoFullName, sshDomain string) string {
103+
// FIXME: template passes AppURL as urlPrefix, it needs to figure out the correct approach (no hard-coded AppURL anymore)
104+
func (sf *CommitSubModuleFile) RefURL(urlPrefix, repoFullName, sshDomain string) string {
113105
return getRefURL(sf.refURL, urlPrefix, repoFullName, sshDomain)
114106
}
115107

116108
// RefID returns reference ID.
117-
func (sf *SubModuleFile) RefID() string {
109+
func (sf *CommitSubModuleFile) RefID() string {
118110
return sf.refID
119111
}

modules/git/submodule_test.go modules/git/commit_submodule_file_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import (
99
"github.com/stretchr/testify/assert"
1010
)
1111

12-
func TestGetRefURL(t *testing.T) {
12+
func TestCommitSubModuleFileGetRefURL(t *testing.T) {
1313
kases := []struct {
1414
refURL string
1515
prefixURL string

modules/git/commit_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ author KN4CK3R <[email protected]> 1711702962 +0100
135135
committer KN4CK3R <[email protected]> 1711702962 +0100
136136
encoding ISO-8859-1
137137
gpgsig -----BEGIN PGP SIGNATURE-----
138-
138+
<SPACE>
139139
iQGzBAABCgAdFiEE9HRrbqvYxPT8PXbefPSEkrowAa8FAmYGg7IACgkQfPSEkrow
140140
Aa9olwv+P0HhtCM6CRvlUmPaqswRsDPNR4i66xyXGiSxdI9V5oJL7HLiQIM7KrFR
141141
gizKa2COiGtugv8fE+TKqXKaJx6uJUJEjaBd8E9Af9PrAzjWj+A84lU6/PgPS8hq
@@ -150,7 +150,7 @@ gpgsig -----BEGIN PGP SIGNATURE-----
150150
-----END PGP SIGNATURE-----
151151
152152
ISO-8859-1`
153-
153+
commitString = strings.ReplaceAll(commitString, "<SPACE>", " ")
154154
sha := &Sha1Hash{0xfe, 0xaf, 0x4b, 0xa6, 0xbc, 0x63, 0x5f, 0xec, 0x44, 0x2f, 0x46, 0xdd, 0xd4, 0x51, 0x24, 0x16, 0xec, 0x43, 0xc2, 0xc2}
155155
gitRepo, err := openRepositoryWithDefaultContext(filepath.Join(testReposDir, "repo1_bare"))
156156
assert.NoError(t, err)

0 commit comments

Comments
 (0)