aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--worktree.go28
-rw-r--r--worktree_test.go44
2 files changed, 70 insertions, 2 deletions
diff --git a/worktree.go b/worktree.go
index 62ad03b..c79e715 100644
--- a/worktree.go
+++ b/worktree.go
@@ -716,7 +716,33 @@ func (w *Worktree) readGitmodulesFile() (*config.Modules, error) {
}
m := config.NewModules()
- return m, m.Unmarshal(input)
+ if err := m.Unmarshal(input); err != nil {
+ return m, err
+ }
+
+ w.resolveRelativeSubmodulePaths(m)
+
+ return m, nil
+}
+
+
+// resolveRelativeSubmodulePaths is to replace any relative submodule URL (../foobar.git) in .gitmodules
+// to the accessible repository URL
+func (w *Worktree) resolveRelativeSubmodulePaths(m *config.Modules) {
+ origin, err := w.r.Remotes()
+ // remote is not associated with this worktree. we don't need to process any futher more
+ if err != nil {
+ return
+ }
+
+ parentURL := filepath.Dir(origin[0].c.URLs[0])
+
+ for i := range m.Submodules {
+ if strings.HasPrefix(m.Submodules[i].URL, "../") {
+ child := strings.Replace(m.Submodules[i].URL, "../", "", 1)
+ m.Submodules[i].URL = fmt.Sprintf("%s/%s", parentURL, child)
+ }
+ }
}
// Clean the worktree by removing untracked files.
diff --git a/worktree_test.go b/worktree_test.go
index 59c80af..93a4a9a 100644
--- a/worktree_test.go
+++ b/worktree_test.go
@@ -4,6 +4,7 @@ import (
"bytes"
"context"
"errors"
+ "io"
"io/ioutil"
"os"
"path/filepath"
@@ -12,7 +13,7 @@ import (
"testing"
"time"
- fixtures "github.com/go-git/go-git-fixtures/v4"
+ "github.com/go-git/go-git-fixtures/v4"
"github.com/go-git/go-git/v5/config"
"github.com/go-git/go-git/v5/plumbing"
"github.com/go-git/go-git/v5/plumbing/filemode"
@@ -519,6 +520,47 @@ func (s *WorktreeSuite) TestCheckoutSubmoduleInitialized(c *C) {
c.Assert(status.IsClean(), Equals, true)
}
+
+func (s *WorktreeSuite) TestCheckoutRelativePathSubmoduleInitialized(c *C) {
+ url := "https://github.com/git-fixtures/submodule.git"
+ r := s.NewRepository(fixtures.ByURL(url).One())
+
+ // modify the .gitmodules from original one
+ file, err := r.wt.OpenFile(".gitmodules", os.O_WRONLY|os.O_TRUNC, 0666)
+ c.Assert(err, IsNil)
+
+ n, err := io.WriteString(file, `[submodule "basic"]
+ path = basic
+ url = ../basic.git
+[submodule "itself"]
+ path = itself
+ url = ../submodule.git`)
+ c.Assert(err, IsNil)
+ c.Assert(n, Not(Equals), 0)
+
+ w, err := r.Worktree()
+ c.Assert(err, IsNil)
+
+ w.Add(".gitmodules")
+ w.Commit("test", &CommitOptions{})
+
+ // test submodule path
+ modules, err := w.readGitmodulesFile()
+
+ c.Assert(modules.Submodules["basic"].URL, Equals, "git@github.com:git-fixtures/basic.git")
+ c.Assert(modules.Submodules["itself"].URL, Equals, "git@github.com:git-fixtures/submodule.git")
+
+ sub, err := w.Submodules()
+ c.Assert(err, IsNil)
+
+ err = sub.Update(&SubmoduleUpdateOptions{Init: true, RecurseSubmodules:DefaultSubmoduleRecursionDepth})
+ c.Assert(err, IsNil)
+
+ status, err := w.Status()
+ c.Assert(err, IsNil)
+ c.Assert(status.IsClean(), Equals, true)
+}
+
func (s *WorktreeSuite) TestCheckoutIndexMem(c *C) {
fs := memfs.New()
w := &Worktree{