diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 68c7118..15996ee 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -72,6 +72,16 @@ jobs:
         shell: bash
         run: __test__/verify-side-by-side.sh
 
+      # Filter
+      - name: Fetch filter
+        uses: ./
+        with:
+          filter: 'blob:none'
+          path: fetch-filter
+
+      - name: Verify fetch filter
+        run: __test__/verify-fetch-filter.sh
+
       # Sparse checkout
       - name: Sparse checkout
         uses: ./
diff --git a/README.md b/README.md
index 7e76cde..92bc784 100644
--- a/README.md
+++ b/README.md
@@ -75,8 +75,12 @@ When Git 2.18 or higher is not in your PATH, falls back to the REST API to downl
     # Default: true
     clean: ''
 
+    # Partially clone against a given filter. Overrides sparse-checkout if set.
+    # Default: null
+    filter: ''
+
     # Do a sparse checkout on given patterns. Each pattern should be separated with
-    # new lines
+    # new lines.
     # Default: null
     sparse-checkout: ''
 
diff --git a/__test__/git-auth-helper.test.ts b/__test__/git-auth-helper.test.ts
index a0cff63..411faed 100644
--- a/__test__/git-auth-helper.test.ts
+++ b/__test__/git-auth-helper.test.ts
@@ -802,6 +802,7 @@ async function setup(testName: string): Promise<void> {
     authToken: 'some auth token',
     clean: true,
     commit: '',
+    filter: undefined,
     sparseCheckout: [],
     sparseCheckoutConeMode: true,
     fetchDepth: 1,
diff --git a/__test__/input-helper.test.ts b/__test__/input-helper.test.ts
index 21932ca..9514cb4 100644
--- a/__test__/input-helper.test.ts
+++ b/__test__/input-helper.test.ts
@@ -79,6 +79,7 @@ describe('input-helper tests', () => {
     expect(settings.clean).toBe(true)
     expect(settings.commit).toBeTruthy()
     expect(settings.commit).toBe('1234567890123456789012345678901234567890')
+    expect(settings.filter).toBe(undefined)
     expect(settings.sparseCheckout).toBe(undefined)
     expect(settings.sparseCheckoutConeMode).toBe(true)
     expect(settings.fetchDepth).toBe(1)
diff --git a/__test__/verify-fetch-filter.sh b/__test__/verify-fetch-filter.sh
new file mode 100755
index 0000000..4fc9d9e
--- /dev/null
+++ b/__test__/verify-fetch-filter.sh
@@ -0,0 +1,16 @@
+#!/bin/bash
+
+# Verify .git folder
+if [ ! -d "./fetch-filter/.git" ]; then
+  echo "Expected ./fetch-filter/.git folder to exist"
+  exit 1
+fi
+
+# Verify .git/config contains partialclonefilter
+
+CLONE_FILTER=$(git -C fetch-filter config --local --get remote.origin.partialclonefilter)
+
+if [ "$CLONE_FILTER" != "blob:none" ]; then
+  echo "Expected ./fetch-filter/.git/config to have 'remote.origin.partialclonefilter' set to 'blob:none'"
+  exit 1
+fi
diff --git a/action.yml b/action.yml
index 43d408d..5aa90a7 100644
--- a/action.yml
+++ b/action.yml
@@ -53,10 +53,15 @@ inputs:
   clean:
     description: 'Whether to execute `git clean -ffdx && git reset --hard HEAD` before fetching'
     default: true
+  filter:
+    description: >
+      Partially clone against a given filter.
+      Overrides sparse-checkout if set.
+    default: null
   sparse-checkout:
     description: >
       Do a sparse checkout on given patterns.
-      Each pattern should be separated with new lines
+      Each pattern should be separated with new lines.
     default: null
   sparse-checkout-cone-mode:
     description: >
diff --git a/dist/index.js b/dist/index.js
index 67752ae..ddf2b3d 100644
--- a/dist/index.js
+++ b/dist/index.js
@@ -1244,8 +1244,12 @@ function getSource(settings) {
             // Fetch
             core.startGroup('Fetching the repository');
             const fetchOptions = {};
-            if (settings.sparseCheckout)
+            if (settings.filter) {
+                fetchOptions.filter = settings.filter;
+            }
+            else if (settings.sparseCheckout) {
                 fetchOptions.filter = 'blob:none';
+            }
             if (settings.fetchDepth <= 0) {
                 // Fetch all branches and tags
                 let refSpec = refHelper.getRefSpecForAllHistory(settings.ref, settings.commit);
@@ -1723,6 +1727,12 @@ function getInputs() {
         // Clean
         result.clean = (core.getInput('clean') || 'true').toUpperCase() === 'TRUE';
         core.debug(`clean = ${result.clean}`);
+        // Filter
+        const filter = core.getInput('filter');
+        if (filter) {
+            result.filter = filter;
+        }
+        core.debug(`filter = ${result.filter}`);
         // Sparse checkout
         const sparseCheckout = core.getMultilineInput('sparse-checkout');
         if (sparseCheckout.length) {
diff --git a/src/git-source-provider.ts b/src/git-source-provider.ts
index c1360b8..5c98e9f 100644
--- a/src/git-source-provider.ts
+++ b/src/git-source-provider.ts
@@ -159,7 +159,13 @@ export async function getSource(settings: IGitSourceSettings): Promise<void> {
       fetchTags?: boolean
       showProgress?: boolean
     } = {}
-    if (settings.sparseCheckout) fetchOptions.filter = 'blob:none'
+
+    if (settings.filter) {
+      fetchOptions.filter = settings.filter
+    } else if (settings.sparseCheckout) {
+      fetchOptions.filter = 'blob:none'
+    }
+
     if (settings.fetchDepth <= 0) {
       // Fetch all branches and tags
       let refSpec = refHelper.getRefSpecForAllHistory(
diff --git a/src/git-source-settings.ts b/src/git-source-settings.ts
index 2f80b5e..629350b 100644
--- a/src/git-source-settings.ts
+++ b/src/git-source-settings.ts
@@ -29,6 +29,11 @@ export interface IGitSourceSettings {
    */
   clean: boolean
 
+  /**
+   * The filter determining which objects to include
+   */
+  filter: string | undefined
+
   /**
    * The array of folders to make the sparse checkout
    */
diff --git a/src/input-helper.ts b/src/input-helper.ts
index be9cecd..e546c19 100644
--- a/src/input-helper.ts
+++ b/src/input-helper.ts
@@ -82,6 +82,14 @@ export async function getInputs(): Promise<IGitSourceSettings> {
   result.clean = (core.getInput('clean') || 'true').toUpperCase() === 'TRUE'
   core.debug(`clean = ${result.clean}`)
 
+  // Filter
+  const filter = core.getInput('filter')
+  if (filter) {
+    result.filter = filter
+  }
+
+  core.debug(`filter = ${result.filter}`)
+
   // Sparse checkout
   const sparseCheckout = core.getMultilineInput('sparse-checkout')
   if (sparseCheckout.length) {