-
-
Notifications
You must be signed in to change notification settings - Fork 5.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Inherit submodules from template repository content (#16237)
Fix #10316 --------- Signed-off-by: Steffen Schröter <steffen@vexar.de> Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
- Loading branch information
1 parent
92a2900
commit 57eb9d0
Showing
17 changed files
with
290 additions
and
136 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
// Copyright 2024 The Gitea Authors. All rights reserved. | ||
// SPDX-License-Identifier: MIT | ||
|
||
package git | ||
|
||
import ( | ||
"bytes" | ||
"fmt" | ||
"strconv" | ||
"strings" | ||
|
||
"code.gitea.io/gitea/modules/optional" | ||
) | ||
|
||
var sepSpace = []byte{' '} | ||
|
||
type LsTreeEntry struct { | ||
ID ObjectID | ||
EntryMode EntryMode | ||
Name string | ||
Size optional.Option[int64] | ||
} | ||
|
||
func parseLsTreeLine(line []byte) (*LsTreeEntry, error) { | ||
// expect line to be of the form: | ||
// <mode> <type> <sha> <space-padded-size>\t<filename> | ||
// <mode> <type> <sha>\t<filename> | ||
|
||
var err error | ||
posTab := bytes.IndexByte(line, '\t') | ||
if posTab == -1 { | ||
return nil, fmt.Errorf("invalid ls-tree output (no tab): %q", line) | ||
} | ||
|
||
entry := new(LsTreeEntry) | ||
|
||
entryAttrs := line[:posTab] | ||
entryName := line[posTab+1:] | ||
|
||
entryMode, entryAttrs, _ := bytes.Cut(entryAttrs, sepSpace) | ||
_ /* entryType */, entryAttrs, _ = bytes.Cut(entryAttrs, sepSpace) // the type is not used, the mode is enough to determine the type | ||
entryObjectID, entryAttrs, _ := bytes.Cut(entryAttrs, sepSpace) | ||
if len(entryAttrs) > 0 { | ||
entrySize := entryAttrs // the last field is the space-padded-size | ||
size, _ := strconv.ParseInt(strings.TrimSpace(string(entrySize)), 10, 64) | ||
entry.Size = optional.Some(size) | ||
} | ||
|
||
switch string(entryMode) { | ||
case "100644": | ||
entry.EntryMode = EntryModeBlob | ||
case "100755": | ||
entry.EntryMode = EntryModeExec | ||
case "120000": | ||
entry.EntryMode = EntryModeSymlink | ||
case "160000": | ||
entry.EntryMode = EntryModeCommit | ||
case "040000", "040755": // git uses 040000 for tree object, but some users may get 040755 for unknown reasons | ||
entry.EntryMode = EntryModeTree | ||
default: | ||
return nil, fmt.Errorf("unknown type: %v", string(entryMode)) | ||
} | ||
|
||
entry.ID, err = NewIDFromString(string(entryObjectID)) | ||
if err != nil { | ||
return nil, fmt.Errorf("invalid ls-tree output (invalid object id): %q, err: %w", line, err) | ||
} | ||
|
||
if len(entryName) > 0 && entryName[0] == '"' { | ||
entry.Name, err = strconv.Unquote(string(entryName)) | ||
if err != nil { | ||
return nil, fmt.Errorf("invalid ls-tree output (invalid name): %q, err: %w", line, err) | ||
} | ||
} else { | ||
entry.Name = string(entryName) | ||
} | ||
return entry, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
// Copyright 2024 The Gitea Authors. All rights reserved. | ||
// SPDX-License-Identifier: MIT | ||
|
||
package git | ||
|
||
import ( | ||
"bufio" | ||
"context" | ||
"fmt" | ||
"os" | ||
|
||
"code.gitea.io/gitea/modules/log" | ||
) | ||
|
||
type TemplateSubmoduleCommit struct { | ||
Path string | ||
Commit string | ||
} | ||
|
||
// GetTemplateSubmoduleCommits returns a list of submodules paths and their commits from a repository | ||
// This function is only for generating new repos based on existing template, the template couldn't be too large. | ||
func GetTemplateSubmoduleCommits(ctx context.Context, repoPath string) (submoduleCommits []TemplateSubmoduleCommit, _ error) { | ||
stdoutReader, stdoutWriter, err := os.Pipe() | ||
if err != nil { | ||
return nil, err | ||
} | ||
opts := &RunOpts{ | ||
Dir: repoPath, | ||
Stdout: stdoutWriter, | ||
PipelineFunc: func(ctx context.Context, cancel context.CancelFunc) error { | ||
_ = stdoutWriter.Close() | ||
defer stdoutReader.Close() | ||
|
||
scanner := bufio.NewScanner(stdoutReader) | ||
for scanner.Scan() { | ||
entry, err := parseLsTreeLine(scanner.Bytes()) | ||
if err != nil { | ||
cancel() | ||
return err | ||
} | ||
if entry.EntryMode == EntryModeCommit { | ||
submoduleCommits = append(submoduleCommits, TemplateSubmoduleCommit{Path: entry.Name, Commit: entry.ID.String()}) | ||
} | ||
} | ||
return scanner.Err() | ||
}, | ||
} | ||
err = NewCommand(ctx, "ls-tree", "-r", "--", "HEAD").Run(opts) | ||
if err != nil { | ||
return nil, fmt.Errorf("GetTemplateSubmoduleCommits: error running git ls-tree: %v", err) | ||
} | ||
return submoduleCommits, nil | ||
} | ||
|
||
// AddTemplateSubmoduleIndexes Adds the given submodules to the git index. | ||
// It is only for generating new repos based on existing template, requires the .gitmodules file to be already present in the work dir. | ||
func AddTemplateSubmoduleIndexes(ctx context.Context, repoPath string, submodules []TemplateSubmoduleCommit) error { | ||
for _, submodule := range submodules { | ||
cmd := NewCommand(ctx, "update-index", "--add", "--cacheinfo", "160000").AddDynamicArguments(submodule.Commit, submodule.Path) | ||
if stdout, _, err := cmd.RunStdString(&RunOpts{Dir: repoPath}); err != nil { | ||
log.Error("Unable to add %s as submodule to repo %s: stdout %s\nError: %v", submodule.Path, repoPath, stdout, err) | ||
return err | ||
} | ||
} | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
// Copyright 2024 The Gitea Authors. All rights reserved. | ||
// SPDX-License-Identifier: MIT | ||
|
||
package git | ||
|
||
import ( | ||
"context" | ||
"os" | ||
"path/filepath" | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
func TestGetTemplateSubmoduleCommits(t *testing.T) { | ||
testRepoPath := filepath.Join(testReposDir, "repo4_submodules") | ||
submodules, err := GetTemplateSubmoduleCommits(DefaultContext, testRepoPath) | ||
require.NoError(t, err) | ||
|
||
assert.Len(t, submodules, 2) | ||
|
||
assert.EqualValues(t, "<°)))><", submodules[0].Path) | ||
assert.EqualValues(t, "d2932de67963f23d43e1c7ecf20173e92ee6c43c", submodules[0].Commit) | ||
|
||
assert.EqualValues(t, "libtest", submodules[1].Path) | ||
assert.EqualValues(t, "1234567890123456789012345678901234567890", submodules[1].Commit) | ||
} | ||
|
||
func TestAddTemplateSubmoduleIndexes(t *testing.T) { | ||
ctx := context.Background() | ||
tmpDir := t.TempDir() | ||
var err error | ||
_, _, err = NewCommand(ctx, "init").RunStdString(&RunOpts{Dir: tmpDir}) | ||
require.NoError(t, err) | ||
_ = os.Mkdir(filepath.Join(tmpDir, "new-dir"), 0o755) | ||
err = AddTemplateSubmoduleIndexes(ctx, tmpDir, []TemplateSubmoduleCommit{{Path: "new-dir", Commit: "1234567890123456789012345678901234567890"}}) | ||
require.NoError(t, err) | ||
_, _, err = NewCommand(ctx, "add", "--all").RunStdString(&RunOpts{Dir: tmpDir}) | ||
require.NoError(t, err) | ||
_, _, err = NewCommand(ctx, "-c", "user.name=a", "-c", "user.email=b", "commit", "-m=test").RunStdString(&RunOpts{Dir: tmpDir}) | ||
require.NoError(t, err) | ||
submodules, err := GetTemplateSubmoduleCommits(DefaultContext, tmpDir) | ||
require.NoError(t, err) | ||
assert.Len(t, submodules, 1) | ||
assert.EqualValues(t, "new-dir", submodules[0].Path) | ||
assert.EqualValues(t, "1234567890123456789012345678901234567890", submodules[0].Commit) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
ref: refs/heads/master |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
[core] | ||
repositoryformatversion = 0 | ||
filemode = true | ||
bare = true |
Binary file added
BIN
+110 Bytes
modules/git/tests/repos/repo4_submodules/objects/97/c3d30df0e6492348292600920a6482feaebb74
Binary file not shown.
Binary file added
BIN
+112 Bytes
modules/git/tests/repos/repo4_submodules/objects/c7/e064ed49b44523cba8a5dfbc37d2ce1bb41d34
Binary file not shown.
2 changes: 2 additions & 0 deletions
2
modules/git/tests/repos/repo4_submodules/objects/e1/e59caba97193d48862d6809912043871f37437
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
x��[ | ||
�0E��*�_��$M�5tifBk Iŕ�7�k~��9ܘ��ܠ���.j�� �O���"z�`�#I�irF����$%����|4)��?t��=��:K��#[$D����^�����Ӓy�HU/�f?G |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
e1e59caba97193d48862d6809912043871f37437 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.