Skip to content

Instantly share code, notes, and snippets.

@dsfaccini
Created October 19, 2025 01:40
Show Gist options
  • Select an option

  • Save dsfaccini/239136e5c2690e2750f0cb64e7defc46 to your computer and use it in GitHub Desktop.

Select an option

Save dsfaccini/239136e5c2690e2750f0cb64e7defc46 to your computer and use it in GitHub Desktop.
How do I clone a sub directory from a github repository? This script clones only a specific folder from a git(hub) repository, without history, then deletes the repository and inits a new one. This is particularly useful for cloning templates.
# add this line to you .zshrc to make the command globally available:
# source ~/.shell-functions/clone-git-folder.zsh
# you'll need to open a new shell or run source ~/.zshrc to reload your shell config
#
# usage example: the template for deploying payloadcms on cloudflare
# running `clone-git-folder https://github.com/payloadcms/payload/tree/main/templates/with-cloudflare-d1`
# will create a new folder called "with-cloudflare-d1"
# running `clone-git-folder https://github.com/payloadcms/payload/tree/main/templates/with-cloudflare-d1 payloadcms-on-cloudflare`
# will create a new folder called "payloadcms-on-cloudflare"
clone-git-folder() {
# Usage:
# clone-git-folder <github_folder_url> [<new_folder_name>]
# clone-git-folder <repo_url> <path/in/repo> [<new_folder_name>]
if [[ $# -lt 1 ]]; then
echo "Usage:"
echo " clone-git-folder <github_folder_url> [<new_folder_name>]"
echo " clone-git-folder <repo_url> <path/in/repo> [<new_folder_name>]"
return 1
fi
local REPO_URL FOLDER_PATH DEST
if [[ "$1" =~ "github.com/([^/]+)/([^/]+)/tree/([^/]+)/(.*)" ]]; then
# GitHub URL mode (zsh regex -> $match)
local OWNER="${match[1]}"
local REPO="${match[2]}"
local BRANCH="${match[3]}" # not used, but parsed for correctness
FOLDER_PATH="${match[4]}"
REPO_URL="https://github.com/${OWNER}/${REPO}.git"
DEST="${2:-$(basename "$FOLDER_PATH")}"
elif [[ $# -ge 2 ]]; then
# Manual mode
REPO_URL="$1"
FOLDER_PATH="$2"
DEST="${3:-$(basename "$FOLDER_PATH")}"
else
echo "❌ Missing folder path argument."
echo "Usage: clone-git-folder <repo_url> <path/in/repo> [<new_folder_name>]"
return 1
fi
local CWD TMP_DIR
CWD="$(pwd)"
TMP_DIR="$(mktemp -d)"
echo "πŸ“¦ Cloning '$FOLDER_PATH' from $REPO_URL ..."
git clone --depth 1 --filter=blob:none --sparse "$REPO_URL" "$TMP_DIR" >/dev/null 2>&1 || {
echo "❌ git clone failed"
rm -rf "$TMP_DIR"
return 1
}
# Limit checkout to the target folder (run inside tmp, but don't change caller's dir)
( cd "$TMP_DIR" && git sparse-checkout set "$FOLDER_PATH" >/dev/null 2>&1 ) || {
echo "❌ Folder '$FOLDER_PATH' not found in repo"
rm -rf "$TMP_DIR"
return 1
}
# Copy into destination under the ORIGINAL directory; include dotfiles
mkdir -p "$CWD/$DEST"
( cd "$TMP_DIR/$FOLDER_PATH" && tar -cf - . ) | ( cd "$CWD/$DEST" && tar -xf - )
# Clean up tmp
rm -rf "$TMP_DIR"
# Nuke any git metadata that might have been copied and init fresh repo
rm -rf "$CWD/$DEST/.git"
git -C "$CWD/$DEST" init -q
echo "βœ… Folder '$FOLDER_PATH' cloned into '$DEST' (fresh git repo) β€” staying in $(pwd)"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment