diff --git a/.github/workflows/e2e.yaml b/.github/workflows/e2e.yaml
index ef4bc8bfc9dd795e8b6ca0a0a936f5c0c210f410..d6c232184f4a6c31dfd639e7c344abf82a924c94 100644
--- a/.github/workflows/e2e.yaml
+++ b/.github/workflows/e2e.yaml
@@ -188,7 +188,8 @@ jobs:
         run: |
           /tmp/flux create source git flux-system \
           --url=https://github.com/fluxcd/flux2-kustomize-helm-example \
-          --branch=main
+          --branch=main \
+          --recurse-submodules
           /tmp/flux create kustomization flux-system \
           --source=flux-system \
           --path=./clusters/staging
diff --git a/cmd/flux/create_source_git.go b/cmd/flux/create_source_git.go
index 8f00636c3279ac66d8f1cf5c7ea5608b703db136..eaee699a14ef6eeab24be5ca019a880528a98da7 100644
--- a/cmd/flux/create_source_git.go
+++ b/cmd/flux/create_source_git.go
@@ -56,6 +56,7 @@ type sourceGitFlags struct {
 	gitImplementation flags.GitImplementation
 	caFile            string
 	privateKeyFile    string
+	recurseSubmodules bool
 }
 
 var createSourceGitCmd = &cobra.Command{
@@ -124,6 +125,7 @@ func init() {
 	createSourceGitCmd.Flags().Var(&sourceGitArgs.gitImplementation, "git-implementation", sourceGitArgs.gitImplementation.Description())
 	createSourceGitCmd.Flags().StringVar(&sourceGitArgs.caFile, "ca-file", "", "path to TLS CA file used for validating self-signed certificates")
 	createSourceGitCmd.Flags().StringVar(&sourceGitArgs.privateKeyFile, "private-key-file", "", "path to a passwordless private key file used for authenticating to the Git SSH server")
+	createSourceGitCmd.Flags().BoolVar(&sourceGitArgs.recurseSubmodules, "recurse-submodules", false, "when enabled, after the clone is created, initializes all Git submodules within")
 
 	createSourceCmd.AddCommand(createSourceGitCmd)
 }
@@ -158,6 +160,10 @@ func createSourceGitCmdRun(cmd *cobra.Command, args []string) error {
 		return fmt.Errorf("specifing a CA file is not supported for Git over SSH")
 	}
 
+	if sourceGitArgs.recurseSubmodules && sourceGitArgs.gitImplementation == sourcev1.LibGit2Implementation {
+		return fmt.Errorf("recurse submodules requires --git-implementation=%s", sourcev1.GoGitImplementation)
+	}
+
 	tmpDir, err := ioutil.TempDir("", name)
 	if err != nil {
 		return err
@@ -180,7 +186,8 @@ func createSourceGitCmdRun(cmd *cobra.Command, args []string) error {
 			Interval: metav1.Duration{
 				Duration: createArgs.interval,
 			},
-			Reference: &sourcev1.GitRepositoryRef{},
+			RecurseSubmodules: sourceGitArgs.recurseSubmodules,
+			Reference:         &sourcev1.GitRepositoryRef{},
 		},
 	}
 
diff --git a/docs/cmd/flux_create_source_git.md b/docs/cmd/flux_create_source_git.md
index 14cddd5abbf6c3df92bbcad46717c769824a0288..faab2f92fa9daec8bd28fe198de2e7f31c94f0c5 100644
--- a/docs/cmd/flux_create_source_git.md
+++ b/docs/cmd/flux_create_source_git.md
@@ -70,6 +70,7 @@ flux create source git [name] [flags]
   -h, --help                                   help for git
   -p, --password string                        basic authentication password
       --private-key-file string                path to a passwordless private key file used for authenticating to the Git SSH server
+      --recurse-submodules                     when enabled, after the clone is created, initializes all Git submodules within
       --secret-ref string                      the name of an existing secret containing SSH or basic credentials
       --ssh-ecdsa-curve ecdsaCurve             SSH ECDSA public key curve (p256, p384, p521) (default p384)
       --ssh-key-algorithm publicKeyAlgorithm   SSH public key algorithm (rsa, ecdsa, ed25519) (default rsa)