Repository: gohugoio/hugo (language: go)

Issue:
Module mounts with identical sources are not recursively copied to targets
<!-- Please answer these questions before submitting your issue. Thanks! -->

### What version of Hugo are you using (`hugo version`)?

<pre>
hugo v0.92.0-B3549403+extended linux/amd64 BuildDate=2022-01-12T08:23:18Z VendorInfo=gohugoio
</pre>

### Does this issue reproduce with the latest release?

Yes.

**What happened:**
Added three (3) module mounts - two (2) have the same source, but different targets. In config.toml for example: 

```toml
[[module.mounts]]
source = "content"
target = "content"

[[module.mounts]]
source = "extra-content"
target = "content/resources-a"

[[module.mounts]]
source = "extra-content"
target = "content/resources-b"
```

Note the `extra-content` dir contains subdirs, and the resulting `public` output:

![Screenshot from 2022-01-26 16-02-15](https://user-images.githubusercontent.com/8106669/151188120-63ded5e0-39b1-434b-bbaa-9dfbc404b127.png)

**What I expected to happened:**
`public/resources-b` would also contain `extra-content/subdir`.

---

To reproduce with 0.92.0:
```shell
git clone git@github.com:robbymilo/hugo-bug.git
cd hugo-bug && git chceckout module-mounts
hugo
ls -Ral public/resources*
```

You will see the difference between 
`public/resources-a` and 
`public/resources-b`. 

`public/resources-a` contains the subdirs for `extra-content`, while `public/resources-b` does not.


Discussion / hints:
Confirmed. MRE:

```bash
git clone --single-branch -b hugo-github-issue-9426 https://github.com/jmooring/hugo-testing hugo-github-issue-9426
cd hugo-github-issue-9426
hugo && tree public
```

Fix patch:
diff --git a/hugofs/walk.go b/hugofs/walk.go
index 44d58f06085..c02d366713f 100644
--- a/hugofs/walk.go
+++ b/hugofs/walk.go
@@ -270,7 +270,7 @@ func (w *Walkway) walk(path string, info FileMetaInfo, dirEntries []FileMetaInfo
 		meta.Path = normalizeFilename(pathMeta)
 		meta.PathWalk = pathn
 
-		if fim.IsDir() && w.isSeen(meta.Filename) {
+		if fim.IsDir() && meta.IsSymlink && w.isSeen(meta.Filename) {
 			// Prevent infinite recursion
 			// Possible cyclic reference
 			meta.SkipDir = true


Test patch:
diff --git a/hugofs/walk_test.go b/hugofs/walk_test.go
index 4825ba36e6d..2d9ec784d57 100644
--- a/hugofs/walk_test.go
+++ b/hugofs/walk_test.go
@@ -81,14 +81,12 @@ func TestWalkRootMappingFs(t *testing.T) {
 	}
 
 	c.Run("Basic", func(c *qt.C) {
-
 		bfs := prepare(c)
 
 		names, err := collectFilenames(bfs, "", "")
 
 		c.Assert(err, qt.IsNil)
 		c.Assert(names, qt.DeepEquals, []string{"a/test.txt", "b/test.txt", "c/test.txt"})
-
 	})
 
 	c.Run("Para", func(c *qt.C) {
@@ -112,12 +110,10 @@ func TestWalkRootMappingFs(t *testing.T) {
 					return errors.New("fail")
 				}
 				return nil
-
 			})
 		}
 
 		c.Assert(r.Wait(), qt.IsNil)
-
 	})
 }
 
@@ -169,7 +165,7 @@ func TestWalkSymbolicLink(t *testing.T) {
 		names, err := collectFilenames(fs, workDir, workDir)
 		c.Assert(err, qt.IsNil)
 
-		c.Assert(names, qt.DeepEquals, []string{"blog/real/sub/a.txt", "docs/b.txt"})
+		c.Assert(names, qt.DeepEquals, []string{"blog/real/sub/a.txt", "blog/symlinked/sub/a.txt", "docs/b.txt"})
 	})
 
 	t.Run("BasePath Fs", func(t *testing.T) {
diff --git a/hugolib/filesystems/basefs_test.go b/hugolib/filesystems/basefs_test.go
index a119d4c1790..7fbb5395422 100644
--- a/hugolib/filesystems/basefs_test.go
+++ b/hugolib/filesystems/basefs_test.go
@@ -33,7 +33,6 @@ import (
 	"github.com/gohugoio/hugo/hugofs"
 	"github.com/gohugoio/hugo/hugolib/paths"
 	"github.com/gohugoio/hugo/modules"
-	
 )
 
 func initConfig(fs afero.Fs, cfg config.Provider) error {
@@ -152,7 +151,7 @@ theme = ["atheme"]
 	checkFileCount(bfs.Data.Fs, "", c, 11)       // 7 + 4 themes
 	checkFileCount(bfs.Archetypes.Fs, "", c, 10) // 8 + 2 themes
 	checkFileCount(bfs.Assets.Fs, "", c, 9)
-	checkFileCount(bfs.Work, "", c, 82)
+	checkFileCount(bfs.Work, "", c, 90)
 
 	c.Assert(bfs.IsData(filepath.Join(workingDir, "mydata", "file1.txt")), qt.Equals, true)
 	c.Assert(bfs.IsI18n(filepath.Join(workingDir, "myi18n", "file1.txt")), qt.Equals, true)
diff --git a/hugolib/hugo_modules_test.go b/hugolib/hugo_modules_test.go
index 46423043750..eb6b7433b5e 100644
--- a/hugolib/hugo_modules_test.go
+++ b/hugolib/hugo_modules_test.go
@@ -1134,3 +1134,39 @@ P1: {{ $p1.Title }}|{{ $p1.RelPermalink }}|Filename: {{ $p1.File.Filename }}
 
 	b.AssertFileContent("public/index.html", "P1: Abs|/p1/", "Filename: "+contentFilename)
 }
+
+// Issue 9426
+func TestMountSameSource(t *testing.T) {
+	config := `baseURL = 'https://example.org/'
+languageCode = 'en-us'
+title = 'Hugo GitHub Issue #9426'
+
+disableKinds = ['RSS','sitemap','taxonomy','term']
+
+[[module.mounts]]
+source = "content"
+target = "content"
+
+[[module.mounts]]
+source = "extra-content"
+target = "content/resources-a"
+
+[[module.mounts]]
+source = "extra-content"
+target = "content/resources-b"
+`
+	b := newTestSitesBuilder(t).WithConfigFile("toml", config)
+
+	b.WithContent("p1.md", "")
+
+	b.WithSourceFile(
+		"extra-content/_index.md", "",
+		"extra-content/subdir/_index.md", "",
+		"extra-content/subdir/about.md", "",
+	)
+
+	b.Build(BuildCfg{})
+
+	b.AssertFileContent("public/resources-a/subdir/about/index.html", "Single")
+	b.AssertFileContent("public/resources-b/subdir/about/index.html", "Single")
+}