[submodule_update] Migrate tests from google3
submodule_test.go is copied from
http://google3/turquoise/infra/foundation/go/submodule_update/submodule/submodule_test.go
with necessary changes to support building with Go's build system.
Also fix minor issues in some other files.
Bug: 320755417
Change-Id: Iead7c68f469f0fb6a76bf25b144971d2b0b7a065
Reviewed-on: https://fuchsia-review.googlesource.com/c/infra/infra/+/979912
Reviewed-by: Ina Huh <ihuh@google.com>
Fuchsia-Auto-Submit: Oliver Newman <olivernewman@google.com>
Commit-Queue: Auto-Submit <auto-submit@fuchsia-infra.iam.gserviceaccount.com>
diff --git a/cmd/submodule_update/gitutil/git.go b/cmd/submodule_update/gitutil/git.go
index 7014c9c..09916c8 100644
--- a/cmd/submodule_update/gitutil/git.go
+++ b/cmd/submodule_update/gitutil/git.go
@@ -1,6 +1,7 @@
// Copyright 2023 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+
// Package gitutil is a wrapper layer for handing calls to the git tool.
package gitutil
@@ -38,16 +39,15 @@
// Error outputs GitError struct as a string.
func (ge GitError) Error() string {
- result := fmt.Sprintf("(%s)", ge.Root)
- result += "'git "
- result += strings.Join(ge.Args, " ")
- result += "' failed:\n"
- result += "stdout:\n"
- result += ge.Output + "\n"
- result += "stderr:\n"
- result += ge.ErrorOutput
- result += "\ncommand fail error: " + ge.err.Error()
- return result
+ lines := []string{
+ fmt.Sprintf("(%s) 'git %s' failed:", ge.Root, strings.Join(ge.Args, " ")),
+ "stdout:",
+ ge.Output,
+ "stderr:",
+ ge.ErrorOutput,
+ "command fail error: " + ge.err.Error(),
+ }
+ return strings.Join(lines, "\n")
}
// Git structure for environmental options passed to git tool.
@@ -207,9 +207,7 @@
// SubmoduleAdd adds submodule to current branch.
func (g *Git) SubmoduleAdd(remote string, path string) error {
// Use -f to add submodules even if in .gitignore.
- args := []string{"submodule", "add", "-f"}
- args = append(args, remote, path)
- return g.run(args...)
+ return g.run("submodule", "add", "-f", remote, path)
}
// SubmoduleStatus returns current current status of submodules in a superproject.
@@ -244,6 +242,54 @@
args = append(args, "--jobs=50")
args = append(args, paths...)
return g.run(args...)
+
+}
+
+// Clone clones the given repository to the given local path. If reference is
+// not empty it uses the given path as a reference/shared repo.
+func (g *Git) Clone(repo, path string, opts ...CloneOpt) error {
+ args := []string{"clone"}
+ for _, opt := range opts {
+ switch typedOpt := opt.(type) {
+ case BareOpt:
+ if typedOpt {
+ args = append(args, "--bare")
+ }
+ case ReferenceOpt:
+ reference := string(typedOpt)
+ if reference != "" {
+ args = append(args, []string{"--reference-if-able", reference}...)
+ }
+ case SharedOpt:
+ if typedOpt {
+ args = append(args, []string{"--shared", "--local"}...)
+ }
+ case NoCheckoutOpt:
+ if typedOpt {
+ args = append(args, "--no-checkout")
+ }
+ case DepthOpt:
+ if typedOpt > 0 {
+ args = append(args, []string{"--depth", strconv.Itoa(int(typedOpt))}...)
+ }
+ case OmitBlobsOpt:
+ if typedOpt {
+ args = append(args, "--filter=blob:none")
+ }
+ case OffloadPackfilesOpt:
+ if typedOpt {
+ args = append([]string{"-c", "fetch.uriprotocols=https"}, args...)
+ }
+ case RecurseSubmodulesOpt:
+ // TODO(iankaz): Add setting submodule.fetchJobs in git config to jiri init
+ if typedOpt {
+ args = append(args, []string{"--recurse-submodules", "--jobs=16"}...)
+ }
+ }
+ }
+ args = append(args, repo)
+ args = append(args, path)
+ return g.run(args...)
}
// CommitWithMessage commits all files in staging with the given
diff --git a/cmd/submodule_update/submodule/submodule.go b/cmd/submodule_update/submodule/submodule.go
index 35967e4..0887a72 100644
--- a/cmd/submodule_update/submodule/submodule.go
+++ b/cmd/submodule_update/submodule/submodule.go
@@ -1,6 +1,7 @@
// Copyright 2023 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+
// Package submodule handles analyzing and updating git submodule states.
package submodule
diff --git a/cmd/submodule_update/submodule/submodule_test.go b/cmd/submodule_update/submodule/submodule_test.go
new file mode 100644
index 0000000..6acc022
--- /dev/null
+++ b/cmd/submodule_update/submodule/submodule_test.go
@@ -0,0 +1,507 @@
+// Copyright 2024 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package submodule
+
+import (
+ "fmt"
+ "os"
+ "os/exec"
+ "path"
+ "path/filepath"
+ "regexp"
+ "strconv"
+ "strings"
+ "testing"
+
+ "github.com/google/go-cmp/cmp"
+ "go.fuchsia.dev/infra/cmd/submodule_update/gitutil"
+)
+
+// createTestdataTemp copies the testdata to a temp folder compatible with git.
+func createTestdataTemp(t *testing.T) (string, error) {
+ t.Helper()
+ uniqTempDir := t.TempDir()
+ fromPath := "../testdata"
+ if err := exec.Command("cp", "-R", fromPath, uniqTempDir).Run(); err != nil {
+ t.Fatalf("Error copying from %s to %s (%q)", fromPath, uniqTempDir, err)
+ return "", err
+ }
+ return uniqTempDir, nil
+}
+
+// createSuperproject clones the testdata superproject to a temp directory.
+func createSuperproject(t *testing.T, recurseSubmodules bool) (g *gitutil.Git, err error) {
+ t.Helper()
+ superprojectRemoteTemp, err := createTestdataTemp(t)
+ if err != nil {
+ t.Fatalf("Failed to create superproject remote temp dir: %s", err)
+ return nil, err
+ }
+
+ superprojectRoot := t.TempDir()
+ scm := gitutil.New(gitutil.RootDirOpt(superprojectRoot))
+ repo := filepath.Join(superprojectRemoteTemp, "testdata", "remote", "super")
+ if err := scm.Clone(repo, superprojectRoot, gitutil.RecurseSubmodulesOpt(recurseSubmodules)); err != nil {
+ t.Fatalf("Failed to clone superproject: %s", err)
+ return nil, err
+ }
+
+ gitConfig := map[string]string{
+ // Allow cloning local repos, since this is required for tests that use
+ // this mock data.
+ "protocol.file.allow": "always",
+ }
+ t.Setenv("GIT_CONFIG_COUNT", strconv.Itoa(len(gitConfig)))
+ i := 0
+ for k, v := range gitConfig {
+ t.Setenv(fmt.Sprintf("GIT_CONFIG_KEY_%d", i), k)
+ t.Setenv(fmt.Sprintf("GIT_CONFIG_VALUE_%d", i), v)
+ i++
+ }
+
+ return scm, nil
+}
+
+func createSubmodules(t *testing.T, submodules map[string]string) Submodules {
+ t.Helper()
+ var subModules = Submodules{}
+ for subPath, rev := range submodules {
+ subM := Submodule{
+ Path: subPath,
+ Revision: rev,
+ // For testing, fake the remote
+ Remote: filepath.Join("remote", subPath),
+ }
+ subModules[subM.Key()] = subM
+ }
+ return subModules
+}
+
+func getSubmodules(t *testing.T, g *gitutil.Git, cached bool) Submodules {
+ t.Helper()
+ gitSubmodules, err := gitSubmodules(g, cached)
+ if err != nil {
+ t.Fatalf("Git submodules creation failed: %s", err)
+ }
+ return gitSubmodules
+}
+
+func TestSubmoduleDiff(t *testing.T) {
+ initialSub := createSubmodules(t, map[string]string{"sub1": "12345a", "sub2": "12345b"})
+ // Change remote for "sub1" to "sub1_new_remote"
+ remoteChangeSub := createSubmodules(t, map[string]string{"sub1": "12345a", "sub2": "12345b"})
+ remoteSub1 := remoteChangeSub[Key("sub1")]
+ remoteSub1.Remote = path.Join("new", "remote", "sub1")
+ remoteChangeSub[Key("sub1")] = remoteSub1
+
+ emptyDiff := Diff{}
+ type diffTest struct {
+ sub1 Submodules
+ sub2 Submodules
+ want Diff
+ }
+ testCases := []diffTest{
+ // No diff
+ {
+ initialSub,
+ initialSub,
+ emptyDiff,
+ },
+ // Add sub3
+ {
+ initialSub,
+ createSubmodules(t, map[string]string{"sub1": "12345a", "sub2": "12345b", "sub3": "12345c"}),
+ Diff{
+ NewSubmodules: []DiffSubmodule{{
+ Path: "sub3",
+ Revision: "12345c",
+ Remote: path.Join("remote", "sub3"),
+ }},
+ },
+ },
+ // Delete sub1
+ {
+ initialSub,
+ createSubmodules(t, map[string]string{"sub2": "12345b"}),
+ Diff{
+ DeletedSubmodules: []DiffSubmodule{{
+ Path: "sub1",
+ Revision: "12345a",
+ Remote: path.Join("remote", "sub1")}},
+ },
+ },
+ // Update sub1 (new revision)
+ {
+ initialSub,
+ createSubmodules(t, map[string]string{"sub1": "12346a", "sub2": "12345b"}),
+ Diff{
+ UpdatedSubmodules: []DiffSubmodule{{
+ Path: "sub1",
+ Revision: "12346a",
+ OldRevision: "12345a",
+ }},
+ },
+ },
+ // Move sub1 (change path) - Processed as a delete (old path) and a new submodule (new path)
+ {
+ initialSub,
+ createSubmodules(t, map[string]string{"sub3": "12345a", "sub2": "12345b"}),
+ Diff{
+ NewSubmodules: []DiffSubmodule{{
+ Path: "sub3",
+ Revision: "12345a",
+ Remote: path.Join("remote", "sub3")}},
+ DeletedSubmodules: []DiffSubmodule{{
+ Path: "sub1",
+ Revision: "12345a",
+ Remote: path.Join("remote", "sub1")}},
+ },
+ },
+ // Move sub1 (change remote) - Processed as a delete (old remote) and a new submodule (new remote)
+ {
+ initialSub,
+ remoteChangeSub,
+ Diff{
+ NewSubmodules: []DiffSubmodule{{
+ Path: "sub1",
+ Revision: "12345a",
+ Remote: path.Join("new", "remote", "sub1")}},
+ DeletedSubmodules: []DiffSubmodule{{
+ Path: "sub1",
+ Revision: "12345a",
+ Remote: path.Join("remote", "sub1")}},
+ },
+ },
+ }
+
+ for _, tc := range testCases {
+ got, err := getDiff(tc.sub1, tc.sub2)
+ if err != nil {
+ t.Fatalf("GetDiff failed with: %s", err)
+ }
+
+ if diff := cmp.Diff(tc.want, got); diff != "" {
+ t.Errorf("GetDiff failed (-want +got):\n%s", diff)
+ }
+ }
+}
+
+func TestUpdateCommitMessage(t *testing.T) {
+ type msgTest struct {
+ message string
+ want string
+ }
+ testCases := []msgTest{
+ // No [roll]
+ {
+ message: "Hello\nworld",
+ want: "Hello\nworld",
+ },
+ // [roll] not at start
+ {
+ message: "Hello\nworld [roll] ",
+ want: "Hello\nworld [roll] ",
+ },
+ // [roll] at start
+ {
+ message: "[roll] Hello\nworld",
+ want: "[superproject] Hello\nworld",
+ },
+ }
+ for _, tc := range testCases {
+ got := updateCommitMessage(tc.message)
+ if diff := cmp.Diff(tc.want, got); diff != "" {
+ t.Errorf("updateCommitMessage failed (-want +got):\n%s", diff)
+ }
+ }
+}
+
+var gitSHA1Re = regexp.MustCompile(`^[0-9a-f]{40}$`)
+
+func TestSubmoduleStatusParsing(t *testing.T) {
+ gitSuperproject, err := createSuperproject(t, false)
+ if err != nil {
+ t.Fatalf("Git superproject creation failed: %s", err)
+ }
+
+ gitSubmodules := getSubmodules(t, gitSuperproject, true)
+
+ expected := []Submodule{
+ {
+ Name: "sub1",
+ Revision: "rev1",
+ Path: "sub1",
+ Remote: "../sub1/",
+ },
+ {
+ Name: "sub2",
+ Revision: "rev2",
+ Path: "sub2",
+ Remote: "../sub2/",
+ },
+ }
+ for _, subM := range expected {
+ if submodule, ok := gitSubmodules[Key(subM.Path)]; ok {
+ if subM.Remote != submodule.Remote {
+ t.Errorf("Remote (%s) didn't match expected %s", submodule.Remote, subM.Remote)
+ }
+ if !gitSHA1Re.MatchString(submodule.Revision) {
+ t.Errorf("Revision (%s) didn't match SHA1 regex", submodule.Revision)
+ }
+ } else {
+ t.Errorf("Expected submodule %s missing", subM.Path)
+ }
+ }
+}
+
+func TestJiriProjectParsing(t *testing.T) {
+ jiriProjectsPath := filepath.Join("..", "testdata", "jiri_projects_public.json")
+
+ jiriSubmodules, err := jiriProjectsToSubmodule(jiriProjectsPath)
+ if err != nil {
+ t.Fatalf("Jiri project parsing failed: %s", err)
+ }
+ expectedPaths := []string{"sub1", "sub2"}
+ for _, path := range expectedPaths {
+ if submodule, ok := jiriSubmodules[Key(path)]; ok {
+ if !gitSHA1Re.MatchString(submodule.Revision) {
+ t.Errorf("Revision (%s) didn't match SHA1 regex", submodule.Revision)
+ }
+ if submodule.Remote == "" {
+ t.Errorf("Expected remote for submodule %s not present", submodule.Path)
+ }
+ } else {
+ t.Errorf("Expected submodule %s missing", path)
+ }
+ }
+}
+
+func TestUpdateSubmodules(t *testing.T) {
+ subPath := "sub1"
+ wantRev := "4c473777b21946176bc7d157d195a29c108da6c6"
+ gitSuperproject, err := createSuperproject(t, false)
+ if err != nil {
+ t.Fatalf("Failed to create superproject: %s", err)
+ }
+ diff := []DiffSubmodule{{
+ Path: subPath,
+ Revision: wantRev,
+ }}
+ if err := updateSubmodules(gitSuperproject, diff, gitSuperproject.RootDir()); err != nil {
+ cmd := exec.Command("tree", gitSuperproject.RootDir())
+ cmd.Stdout = os.Stdout
+ if e := cmd.Run(); e != nil {
+ t.Fatal(e)
+ }
+ t.Fatalf("Failed to update submodules: %s", err)
+ }
+ gitSubmodules := getSubmodules(t, gitSuperproject, false)
+ gotRev := gitSubmodules[Key(subPath)].Revision
+ if gotRev != wantRev {
+ t.Errorf("Expected %s for submodule revision, got %s", wantRev, gotRev)
+ }
+}
+
+func TestUpdateSubmodulesEmpty(t *testing.T) {
+ gitSuperproject, err := createSuperproject(t, false)
+ if err != nil {
+ t.Fatalf("Failed to create superproject: %s", err)
+ }
+ want := getSubmodules(t, gitSuperproject, false)
+ diff := Diff{}
+ if err := updateSubmodules(gitSuperproject, diff.UpdatedSubmodules, "tmp/superproject"); err != nil {
+ t.Fatalf("Failed to update submodules: %s", err)
+ }
+ got := getSubmodules(t, gitSuperproject, false)
+ if diff := cmp.Diff(want, got); diff != "" {
+ t.Errorf("Submodule status changed (-want +got):\n%s", diff)
+ }
+}
+
+func TestDeleteSubmodules(t *testing.T) {
+ subPath := "sub1"
+ gitSuperproject, err := createSuperproject(t, false)
+ if err != nil {
+ t.Fatalf("Failed to create superproject: %s", err)
+ }
+ diff := []DiffSubmodule{{
+ Path: subPath,
+ }}
+ if err := deleteSubmodules(gitSuperproject, diff); err != nil {
+ t.Fatalf("Failed to delete submodules: %s", err)
+ }
+ gitSubmodules := getSubmodules(t, gitSuperproject, false)
+ if _, ok := gitSubmodules[Key(subPath)]; ok {
+ t.Errorf("Submodule %s still present, expected it to be removed", subPath)
+ }
+}
+
+func TestDeleteSubmodulesEmpty(t *testing.T) {
+ gitSuperproject, err := createSuperproject(t, false)
+ if err != nil {
+ t.Fatalf("Failed to create superproject: %s", err)
+ }
+ want := getSubmodules(t, gitSuperproject, false)
+ diff := Diff{}
+ if err := deleteSubmodules(gitSuperproject, diff.DeletedSubmodules); err != nil {
+ t.Fatalf("Failed to delete submodules: %s", err)
+ }
+ got := getSubmodules(t, gitSuperproject, false)
+ if diff := cmp.Diff(want, got); diff != "" {
+ t.Errorf("Submodule status changed (-want +got):\n%s", diff)
+ }
+}
+
+func TestAddSubmodules(t *testing.T) {
+ subPath := "sub3"
+ gitSuperproject, err := createSuperproject(t, false)
+ if err != nil {
+ t.Fatalf("Failed to create superproject: %s", err)
+ }
+ testdataTemp, err := createTestdataTemp(t)
+ if err != nil {
+ t.Fatalf("Failed to create temp testdata dir: %s", err)
+ }
+ remotePath := filepath.Join(testdataTemp, "testdata", "remote", "sub3")
+ diff := []DiffSubmodule{{
+ Path: subPath,
+ Remote: remotePath,
+ Revision: "b6c817cd8a01b209f3b4f89cb55816f4173bbf4e",
+ }}
+ if err := addSubmodules(gitSuperproject, diff); err != nil {
+ t.Fatalf("Failed to add submodules: %s", err)
+ }
+ gitSubmodules := getSubmodules(t, gitSuperproject, false)
+ if _, ok := gitSubmodules[Key(subPath)]; !ok {
+ t.Errorf("Submodule %s not present, expected it to be added", subPath)
+ }
+}
+
+func TestAddSubmodulesEmpty(t *testing.T) {
+ gitSuperproject, err := createSuperproject(t, false)
+ if err != nil {
+ t.Fatalf("Failed to create superproject: %s", err)
+ }
+ want := getSubmodules(t, gitSuperproject, false)
+ diff := Diff{}
+ if err := addSubmodules(gitSuperproject, diff.NewSubmodules); err != nil {
+ t.Fatalf("Failed to add submodules: %s", err)
+ }
+ got := getSubmodules(t, gitSuperproject, false)
+ if diff := cmp.Diff(want, got); diff != "" {
+ t.Errorf("Submodule status changed (-want +got):\n%s", diff)
+ }
+}
+
+func TestCopyFile(t *testing.T) {
+ srcPath := "../testdata/ensure/cipd.ensure"
+ tempDir := t.TempDir()
+ dstPath := filepath.Join(tempDir, "copytest")
+
+ // Test new file creation
+ if err := copyFile(srcPath, dstPath); err != nil {
+ t.Fatalf("Failed to copy file: %s", err)
+ }
+ srcData, err := os.ReadFile(srcPath)
+ if err != nil {
+ t.Fatalf("Failed to read source file: %s", err)
+ }
+ dstData, err := os.ReadFile(dstPath)
+ if err != nil {
+ t.Fatalf("Failed to read destination file: %s", err)
+ }
+ if diff := cmp.Diff(string(srcData), string(dstData)); diff != "" {
+ t.Errorf("CopyFile to new file failed (-want +got):\n%s", diff)
+ }
+
+ // Test truncate/overwrite existing file
+ srcPath = "../testdata/ensure/cipd_internal.ensure"
+ if err = copyFile(srcPath, dstPath); err != nil {
+ t.Fatalf("Failed to copy file: %s", err)
+ }
+ srcData, err = os.ReadFile(srcPath)
+ if err != nil {
+ t.Fatalf("Failed to read source file: %s", err)
+ }
+ dstData, err = os.ReadFile(dstPath)
+ if err != nil {
+ t.Fatalf("Failed to read destination file: %s", err)
+ }
+ if diff := cmp.Diff(string(srcData), string(dstData)); diff != "" {
+ t.Errorf("CopyFile overwrite file failed (-want +got):\n%s", diff)
+ }
+}
+
+func TestCopyCIPDEnsure(t *testing.T) {
+ ensurePath := "../testdata/ensure/"
+ cipdPaths := map[string]string{
+ "ensure": filepath.Join(ensurePath, "cipd.ensure"),
+ "internalEnsure": filepath.Join(ensurePath, "cipd_internal.ensure"),
+ "internalVersion": filepath.Join(ensurePath, "cipd_internal.version"),
+ "version": filepath.Join(ensurePath, "cipd.version"),
+ }
+ gitSuperproject, err := createSuperproject(t, false)
+ if err != nil {
+ t.Fatalf("Failed to create superproject: %s", err)
+ }
+ cipdPath := filepath.Join(gitSuperproject.RootDir(), "tools", "superproject")
+ err = copyCIPDEnsureToSuperproject(cipdPaths, cipdPath)
+ if err != nil {
+ t.Fatalf("Failed to copy ensure files: %s", err)
+ }
+ ensureFileList := []string{filepath.Join(cipdPath, path.Base(cipdPaths["ensure"])), filepath.Join(cipdPath, path.Base(cipdPaths["internalEnsure"]))}
+ versionFileList := []string{filepath.Join(cipdPath, path.Base(cipdPaths["version"])), filepath.Join(cipdPath, path.Base(cipdPaths["internalVersion"]))}
+ for _, dstPath := range ensureFileList {
+ dstDataBytes, err := os.ReadFile(dstPath)
+ if err != nil {
+ t.Fatalf("Failed to read destination file: %s", err)
+ }
+ dstData := string(dstDataBytes)
+ if !strings.HasSuffix(dstData, "Ensure updated\n") {
+ t.Fatalf("Ensure file not updated.")
+ }
+ }
+ for _, dstPath := range versionFileList {
+ dstDataBytes, err := os.ReadFile(dstPath)
+ if err != nil {
+ t.Fatalf("Failed to read destination file: %s", err)
+ }
+ dstData := string(dstDataBytes)
+ if !strings.HasSuffix(dstData, "Version updated\n") {
+ t.Fatalf("Version file not updated.")
+ }
+ }
+
+}
+
+// TODO(olivernewman): Re-enable these tests (or find another way to provide test-coverage)
+// This would require generating a jiri projects input file to match the remotes to the superproject temp directory
+// because remotes are considered in determining new/deleted/updated submodules.
+
+/*
+func TestUpdateSuperprojectRunsNoRecurse(t *testing.T) {
+ gitSuperproject, err := createSuperproject(t, false)
+ if err != nil {
+ t.Fatalf("Failed to create superproject: %s", err)
+ }
+ jiriProjectsPath := "../testdata/jiri_projects_public.json"
+ outputPath := t.TempDir()
+ outputJSONPath := filepath.Join(outputPath, "json_output.json")
+ message := "Commit Message"
+ UpdateSuperproject(gitSuperproject, message, jiriProjectsPath, outputJSONPath)
+}
+
+func TestUpdateSuperprojectRunsWithRecurse(t *testing.T) {
+ gitSuperproject, err := createSuperproject(t, true)
+ if err != nil {
+ t.Fatalf("Failed to create superproject: %s", err)
+ }
+ jiriProjectsPath := "../testdata/jiri_projects_public.json"
+ outputPath := t.TempDir()
+ outputJSONPath := filepath.Join(outputPath, "json_output.json")
+ message := "Commit Message"
+ UpdateSuperproject(gitSuperproject, message, jiriProjectsPath, outputJSONPath)
+}
+*/
diff --git a/cmd/submodule_update/testdata/jiri_projects_public.json b/cmd/submodule_update/testdata/jiri_projects_public.json
index 3ff776a..167a0be 100644
--- a/cmd/submodule_update/testdata/jiri_projects_public.json
+++ b/cmd/submodule_update/testdata/jiri_projects_public.json
@@ -5,7 +5,8 @@
"relativePath": "sub1",
"remote": "sub1_remote",
"revision": "4c473777b21946176bc7d157d195a29c108da6c6",
- "manifest": "/usr/local/google/home/iankaz/fuchsia/.jiri_root/update_history/latest"
+ "manifest": "/usr/local/google/home/me/fuchsia/.jiri_root/update_history/latest",
+ "gitsubmoduleof": "fuchsia"
},
{
"name": "sub2",
@@ -13,25 +14,26 @@
"relativePath": "sub2",
"remote": "sub2_remote",
"revision": "cfb431368e1510b1a3f7cfdd70f8ce14aeb3d6e3",
- "manifest": "/usr/local/google/home/iankaz/fuchsia/.jiri_root/update_history/latest"
+ "manifest": "/usr/local/google/home/me/fuchsia/.jiri_root/update_history/latest",
+ "gitsubmoduleof": "fuchsia"
},
{
"name": "fuchsia",
- "path": "/usr/local/google/home/iankaz/fuchsia",
+ "path": "/usr/local/google/home/me/fuchsia",
"relativePath": ".",
"remote": "https://fuchsia.googlesource.com/fuchsia",
"revision": "052baf0f73298e11a37a1fb54bcdc4b170f65103",
- "manifest": "/usr/local/google/home/iankaz/fuchsia/.jiri_root/update_history/latest"
+ "manifest": "/usr/local/google/home/me/fuchsia/.jiri_root/update_history/latest"
},
{
"name": "integration",
- "path": "/usr/local/google/home/iankaz/fuchsia/integration",
+ "path": "/usr/local/google/home/me/fuchsia/integration",
"relativePath": "integration",
"remote": "https://fuchsia.googlesource.com/integration",
"revision": "cc90a7a07c55f303536759074c71d32ca66c43e0",
"branches": [
"main"
],
- "manifest": "/usr/local/google/home/iankaz/fuchsia/.jiri_root/update_history/latest"
+ "manifest": "/usr/local/google/home/me/fuchsia/.jiri_root/update_history/latest"
}
]