#!/bin/bash

checkout-git-folder() {
    if [[ -z "$1" ]]; then
        echo '$1/branch is empty.'
        exit 1
    fi
    if [[ -z "$2" ]]; then
        echo '$2/path is empty.'
        exit 1
    fi

    local git_branch="$1"
    local base_path="$2"
    local git_folders=$(ls-git-folder "$base_path")

    for git_folder in $git_folders; do
        git_folder="${git_folder#./}"

        local commit_ref=$(git config -f .gitmodules --get submodule."$git_folder".commit)
        if [[ -z "$commit_ref" ]]; then
            echo "No commit found in .gitmodules for submodule: $git_folder" >&2
            continue
        fi

        echo "Stash changes $git_folder"
        git -C "$git_folder" stash >/dev/null 2>&1 || true

        local shallow=$(git config --file .gitmodules --get submodule."$git_folder".shallow)
        if [[ "$shallow" = "true" ]]; then
            if ! git -C "$git_folder" rev-parse --verify "$commit_ref^{commit}" >/dev/null 2>&1; then
                echo "Fetch origin $commit_ref for $git_folder"
                git -C "$git_folder" fetch origin "$commit_ref"
            fi
        fi

        echo "Checkout $commit_ref in $git_folder"
        git -C "$git_folder" checkout "$commit_ref" >/dev/null 2>&1
    done
}
cgf() {
    checkout-git-folder "$@"
}
