I hope this script may help you
#!/bin/bash
set -euo pipefail
usage() {
echo "Usage: $0 -u <clone_url> -d <target_dir> -b <branch>"
exit 1
}
while getopts "su:d:b:" opt; do
case $opt in
u) CLONE_URL=$OPTARG ;;
d) TARGET_DIR=$OPTARG ;;
b) BRANCH=$OPTARG ;;
*) usage ;;
esac
done
if [[ -z "${CLONE_URL-}" || -z "${TARGET_DIR-}" || -z "${BRANCH-}" ]]; then
usage
fi
git clone --filter=blob:none --no-checkout "$CLONE_URL" "$TARGET_DIR"
cd "$TARGET_DIR"
git config core.sparseCheckout true
{
echo "/*"
echo "!/*/"
} > .git/info/sparse-checkout
git checkout "$BRANCH"
git ls-tree -r -d --name-only HEAD | xargs -I{} mkdir -p "{}"
exit 0
This script performs a sparse checkout with the following behavior:
1. Clone the repository without downloading file contents (--filter=blob:none
) and without checking out files initially (--no-checkout
).
2. Enable sparse checkout mode in the cloned repository.
3. Set sparse checkout rules to:
/*
).!/*/
).4. Checkout the specified branch, applying the sparse checkout rules. Only root-level files appear in the working directory.
5. Create empty directories locally by git ls-tree -r -d --name-only HEAD
listing all directories in the repo and making those folders. This recreates the directory structure without file contents because Git does not track empty directories.
6. Exit after completing these steps.
https://ohgoshgit.github.io/posts/2025-08-04-git-sparse-checkout/