Repository: PrefectHQ/prefect

Issue:
Improve documentation around use of GitHub auth for Projects for SSH, classic PAT, fine-grained PAT 
### First check

- [X] I added a descriptive title to this issue.
- [X] I used GitHub search to find a similar request and didn't find it 😇

### Describe the issue

Users were observed having difficulty providing the correct format for different authentication methods at PACC SF and in other situations

### Describe the proposed change

TBD

### Additional context

@gabcoyne @desertaxle @jamiezieziula @zzstoatzz @jawnsy  have had some involvement here and might be able to add context.


Discussion:
Commit with UI hint for fine grained PAT format here: [#pat github](https://github.com/PrefectHQ/prefect/pull/8929/commits/593ff357484ad2d04caa4eaabfde09cabdaeef19)
The UI hint is confusing. We were entering the token as shown in the GUI, eg: 
```
{jdoe}:{github_pat_xyz...}
```
when this is what actually worked:
```
jdoe:github_pat_xyz...
```

Resolving patch:
diff --git a/src/prefect/projects/steps/pull.py b/src/prefect/projects/steps/pull.py
--- a/src/prefect/projects/steps/pull.py
+++ b/src/prefect/projects/steps/pull.py
@@ -28,7 +28,10 @@ def set_working_directory(directory: str) -> dict:
 
 
 def git_clone_project(
-    repository: str, branch: Optional[str] = None, access_token: Optional[str] = None
+    repository: str,
+    branch: Optional[str] = None,
+    include_submodules: bool = False,
+    access_token: Optional[str] = None,
 ) -> dict:
     """
     Clones a git repository into the current working directory.
@@ -36,6 +39,7 @@ def git_clone_project(
     Args:
         repository (str): the URL of the repository to clone
         branch (str, optional): the branch to clone; if not provided, the default branch will be used
+        include_submodules (bool): whether to include git submodules when cloning the repository
         access_token (str, optional): an access token to use for cloning the repository; if not provided
             the repository will be cloned using the default git credentials
 
@@ -44,6 +48,49 @@ def git_clone_project(
 
     Raises:
         subprocess.CalledProcessError: if the git clone command fails for any reason
+
+    Examples:
+        Clone a public repository:
+        ```yaml
+        pull:
+            - prefect.projects.steps.git_clone_project:
+                repository: https://github.com/PrefectHQ/prefect.git
+        ```
+
+        Clone a branch of a public repository:
+        ```yaml
+        pull:
+            - prefect.projects.steps.git_clone_project:
+                repository: https://github.com/PrefectHQ/prefect.git
+                branch: my-branch
+        ```
+
+        Clone a private repository using an access token:
+        ```yaml
+        pull:
+            - prefect.projects.steps.git_clone_project:
+                repository: https://github.com/org/repo.git
+                access_token: "{{ prefect.blocks.secret.github-access-token }}" # Requires creation of a Secret block
+        ```
+        Note that you will need to [create a Secret block](/concepts/blocks/#using-existing-block-types) to store the
+        value of your git credentials. You can also store a username/password combo or token prefix (e.g. `x-token-auth`)
+        in your secret block. Refer to your git providers documentation for the correct authentication schema.
+
+        Clone a repository with submodules:
+        ```yaml
+        pull:
+            - prefect.projects.steps.git_clone_project:
+                repository: https://github.com/org/repo.git
+                include_submodules: true
+        ```
+
+        Clone a repository with an SSH key (note that the SSH key must be added to the worker
+        before executing flows):
+        ```yaml
+        pull:
+            - prefect.projects.steps.git_clone_project:
+                repository: git@github.com:org/repo.git
+        ```
     """
     url_components = urllib.parse.urlparse(repository)
     if url_components.scheme == "https" and access_token is not None:
@@ -57,6 +104,8 @@ def git_clone_project(
     cmd = ["git", "clone", repository_url]
     if branch:
         cmd += ["-b", branch]
+    if include_submodules:
+        cmd += ["--recurse-submodules"]
 
     # Limit git history
     cmd += ["--depth", "1"]


Test patch:
diff --git a/tests/projects/test_steps.py b/tests/projects/test_steps.py
--- a/tests/projects/test_steps.py
+++ b/tests/projects/test_steps.py
@@ -1,3 +1,4 @@
+from unittest.mock import MagicMock, ANY
 import pytest
 
 import prefect
@@ -75,6 +76,62 @@ async def test_run_step_runs_async_functions(self):
 
 
 class TestGitCloneStep:
+    async def test_git_clone(self, monkeypatch):
+        subprocess_mock = MagicMock()
+        monkeypatch.setattr(
+            "prefect.projects.steps.pull.subprocess",
+            subprocess_mock,
+        )
+        output = await run_step(
+            {
+                "prefect.projects.steps.git_clone_project": {
+                    "repository": "https://github.com/org/repo.git",
+                }
+            }
+        )
+        assert output["directory"] == "repo"
+        subprocess_mock.check_call.assert_called_once_with(
+            [
+                "git",
+                "clone",
+                "https://github.com/org/repo.git",
+                "--depth",
+                "1",
+            ],
+            shell=False,
+            stderr=ANY,
+            stdout=ANY,
+        )
+
+    async def test_git_clone_include_submodules(self, monkeypatch):
+        subprocess_mock = MagicMock()
+        monkeypatch.setattr(
+            "prefect.projects.steps.pull.subprocess",
+            subprocess_mock,
+        )
+        output = await run_step(
+            {
+                "prefect.projects.steps.git_clone_project": {
+                    "repository": "https://github.com/org/has-submodules.git",
+                    "include_submodules": True,
+                }
+            }
+        )
+        assert output["directory"] == "has-submodules"
+        subprocess_mock.check_call.assert_called_once_with(
+            [
+                "git",
+                "clone",
+                "https://github.com/org/has-submodules.git",
+                "--recurse-submodules",
+                "--depth",
+                "1",
+            ],
+            shell=False,
+            stderr=ANY,
+            stdout=ANY,
+        )
+
     async def test_git_clone_errors_obscure_access_token(self):
         with pytest.raises(RuntimeError) as exc:
             await run_step(