Created
November 6, 2025 11:40
-
-
Save kljensen/2c77af125b6a42af3c71c7f835f583a7 to your computer and use it in GitHub Desktop.
gc.zsh - Smart Git Clone with Organized Directory Structure
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env zsh | |
| # | |
| # gc - Git Clone with Smart Directory Organization | |
| # | |
| # This function clones Git repositories into a well-organized directory structure | |
| # based on the repository's domain, user/org, and name. | |
| # | |
| # USAGE: | |
| # gc <git-url> | |
| # | |
| # EXAMPLES: | |
| # gc https://github.com/kubernetes/kubernetes | |
| # # Creates: ~/src/github.com/kubernetes/kubernetes | |
| # | |
| # gc git@github.com:torvalds/linux.git | |
| # # Creates: ~/src/github.com/torvalds/linux | |
| # | |
| # gc https://gitlab.com/gitlab-org/gitlab | |
| # # Creates: ~/src/gitlab.com/gitlab-org/gitlab | |
| # | |
| # WHY THIS IS USEFUL: | |
| # - Organizes all Git repos in a predictable hierarchy: ~/src/domain/user/repo | |
| # - No more scattered repos in random locations | |
| # - Easy to find repos: you know exactly where they'll be | |
| # - Works with any Git hosting service (GitHub, GitLab, custom domains) | |
| # - If the repo already exists, it just cd's into it (idempotent) | |
| # - Domain whitelist via directory existence (only clone from trusted domains) | |
| # | |
| # SETUP: | |
| # 1. Save this file to your zsh functions directory | |
| # 2. Ensure your .zshrc has: fpath=(~/.local/share/zsh/functions $fpath) | |
| # 3. Add: autoload -Uz gc | |
| # | |
| # The function expects ~/src/<domain> to already exist for the domain to be | |
| # allowed. This acts as a simple whitelist. For example, create ~/src/github.com | |
| # to allow cloning from GitHub. | |
| gc () { | |
| url=$1 | |
| # Get the domain, user, and repo for two different | |
| # format, HTTP and git, e.g. | |
| # https://github.com/dev-sec/ansible-ssh-hardening | |
| # or | |
| # git@github.com:dev-sec/ansible-ssh-hardening.git | |
| # | |
| if [[ "$url" =~ ^[Hh][Tt][Tt][Pp][Ss]?:// ]] | |
| then | |
| protocol=$(echo "$1" | awk -F'[/:@]' '{print $1}') | |
| domain=$(echo "$1" | awk -F'[/:@]' '{print $4}') | |
| user=$(echo "$1" | awk -F'[/:@]' '{print $5}') | |
| repo=$(echo "$1" | awk -F'[/:@]' '{print $6}') | |
| sanitized_url="$protocol://$domain/$user/$repo" | |
| if [ "$sanitized_url" != "$url" ] | |
| then | |
| echo "Invalid remote: $url" | |
| fi | |
| else | |
| if [[ "$url" =~ ^git@.*\.git ]] | |
| then | |
| gituser=$(echo "$1" | awk -F'[/:@]' '{print $1}') | |
| domain=$(echo "$1" | awk -F'[/:@]' '{print $2}') | |
| user=$(echo "$1" | awk -F'[/:@]' '{print $3}') | |
| repo=$(echo "$1" | awk -F'[/:@]' '{print $4}' | sed 's/\..*$//') | |
| sanitized_url="$gituser@$domain:$user/$repo.git" | |
| if [ "$sanitized_url" != "$url" ] | |
| then | |
| echo "Invalid remote: $url" | |
| fi | |
| else | |
| echo "Invalid remote: $url" | |
| return 1 | |
| fi | |
| fi | |
| # workdir should be something like $HOME/src/github.com | |
| workdir="$HOME/src/$domain" | |
| # See if the workdir exists. In effect, certain domains | |
| # are whitelisted if they already exist, e.g. 'git.yale.edu' | |
| if [ ! -d "$workdir" ] | |
| then | |
| echo "Error: invalid domain for git checkout: $domain" | |
| return 1 | |
| fi | |
| userdir="$HOME/src/$domain/$user" | |
| if [ ! -d "$userdir" ] | |
| then | |
| mkdir -p "$userdir" | |
| fi | |
| cd "$userdir" || exit | |
| filepath="$userdir/$repo" | |
| if [ ! -d "$filepath" ] | |
| then | |
| git clone "$1" | |
| fi | |
| cd "$filepath" || exit | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment