#!/usr/bin/env bash # # git-clone-path.sh — clone a shallow Git subdirectory to a target path. # # Usage: # ./git-clone-path.sh [options] # # Options: # -r, --ref Branch, tag, or commit to check out (default: default branch) # -o, --output Destination directory (default: current directory) # -f, --flatten Place the subdirectory's contents directly into # instead of / # -h, --help Show this help # # Examples: # ./git-clone-path.sh -rmain https://github.com/agent-sh/computer-use-linux \ # skills/computer-use-linux -o./skills/ # # -> ./skills/computer-use-linux # # ./git-clone-path.sh -rmain https://github.com/agent-sh/computer-use-linux \ # skills/computer-use-linux -o./skills/ -f # # -> ./skills/ (contents placed directly) set -euo pipefail usage() { sed -n '2,20p' "$0" | sed 's/^# \{0,1\}//' } command -v git >/dev/null 2>&1 || { echo "error: git is required but not found" >&2; exit 1; } REF="" OUTPUT="" FLATTEN=0 # ---- argument parsing ------------------------------------------------------- # Options may appear before, between, or after the positional args. POSITIONAL=() while [[ $# -gt 0 ]]; do case "$1" in -r|--ref) [[ $# -ge 2 ]] || { echo "error: $1 requires a value" >&2; exit 1; } REF="$2"; shift 2 ;; --ref=*) REF="${1#*=}"; shift ;; -r?*) REF="${1#-r}"; shift ;; # -rmain -o|--output) [[ $# -ge 2 ]] || { echo "error: $1 requires a value" >&2; exit 1; } OUTPUT="$2"; shift 2 ;; --output=*) OUTPUT="${1#*=}"; shift ;; -o?*) OUTPUT="${1#-o}"; shift ;; # -o./skills/ -f|--flatten) FLATTEN=1; shift ;; -h|--help) usage; exit 0 ;; -*) echo "error: unknown option: $1" >&2; usage >&2; exit 1 ;; *) POSITIONAL+=("$1"); shift ;; esac done if [[ ${#POSITIONAL[@]} -ne 2 ]]; then echo "error: expected and " >&2 usage >&2 exit 1 fi REPO_URL="${POSITIONAL[0]}" REPO_PATH="${POSITIONAL[1]#./}" # strip leading ./ REPO_PATH="${REPO_PATH#/}" # strip leading / REPO_PATH="${REPO_PATH%/}" # strip trailing / # ---- resolve basename & target --------------------------------------------- if [[ -z "$REPO_PATH" || "$REPO_PATH" == "." ]]; then REPO_PATH="." BASENAME="$(basename "${REPO_URL%%\?*}" .git)" else BASENAME="$(basename "$REPO_PATH")" fi if [[ -n "$OUTPUT" ]]; then OUTDIR="${OUTPUT%/}" else OUTDIR="." fi if [[ "$FLATTEN" -eq 1 ]]; then TARGET="$OUTDIR" else if [[ -n "$OUTPUT" ]]; then TARGET="$OUTDIR/$BASENAME" else TARGET="$BASENAME" fi fi # ---- shallow sparse clone --------------------------------------------------- TMP_DIR="$(mktemp -d)" trap 'rm -rf "$TMP_DIR"' EXIT echo "Cloning $REPO_URL (path: $REPO_PATH) ..." git clone --depth 1 --filter=blob:none --no-checkout "$REPO_URL" "$TMP_DIR/repo" git -C "$TMP_DIR/repo" sparse-checkout init --cone git -C "$TMP_DIR/repo" sparse-checkout set "$REPO_PATH" if [[ -n "$REF" ]]; then git -C "$TMP_DIR/repo" fetch --depth 1 origin "$REF" git -C "$TMP_DIR/repo" checkout --detach FETCH_HEAD else git -C "$TMP_DIR/repo" checkout fi SRC="$TMP_DIR/repo/$REPO_PATH" if [[ ! -e "$SRC" ]]; then echo "error: path '$REPO_PATH' not found in repository" >&2 exit 1 fi # ---- place into target ------------------------------------------------------ if [[ "$FLATTEN" -eq 1 ]]; then mkdir -p "$TARGET" cp -a "$SRC"/. "$TARGET"/ else mkdir -p "$(dirname "$TARGET")" rm -rf "$TARGET" mv "$SRC" "$TARGET" fi echo "Done -> $TARGET"