#!/bin/bash # Git Configuration Automation Script with Directory Management # ------------------------------------------------------------- # This enhanced script automates the process of applying Git configurations # based on the current working directory, ensuring all repositories for a specific # client use the correct Git user name and email settings. It is essential for maintaining # consistent commit metadata across projects and minimizing the risk of commits being # attributed to the wrong user. Additionally, it now includes functionality to detect # when a project (repository) is deleted from or re-added to the client's directory, # updating the configuration accordingly. # # How It Works: # The script reads a JSON configuration file (`git-configs.json`) that contains mappings # between directory paths and the corresponding Git configurations (user name and email), # along with a list of subdirectories (`subDirs`) under each path. When executed, it # checks the current directory against the configured paths and applies the matching Git # configuration if found. If a repository is deleted or re-added, the script updates # `subDirs` to reflect these changes, ensuring the Git configuration is accurate and current. # # JSON Configuration File Structure: # The configuration file should be structured as follows, with each key being a path # to a client's main directory, and each value being an object with `email`, `name`, # and `subDirs` properties for Git configuration and directory tracking. # # Example: # { # "/Users/username/Projects/ClientA": { # "email": "clienta@example.com", # "name": "Client A", # "subDirs": ["/Users/username/Projects/ClientA/Repo1", "/Users/username/Projects/ClientA/Repo2"] # }, # "/Users/username/Projects/ClientB": { # "email": "clientb@example.com", # "name": "Client B", # "subDirs": ["/Users/username/Projects/ClientB/Repo1"] # } # } # # Setup Instructions for Zsh Users: # 1. Place the `git-configs.json` file in a directory accessible by this script. # 2. Ensure this script is executable by running `chmod +x this_script_name.sh`. # 3. To execute this script automatically in Zsh, open your `.zshrc` file in a text editor, # add a line to source this script when a new shell session starts, and use the `chpwd` # hook to execute this script after each directory change. Save the changes to `.zshrc` # and apply them by running `source ~/.zshrc` or by opening a new terminal window. # # Usage: # Navigate to a project directory in your terminal, and the script will automatically apply # the appropriate Git configuration based on the current directory's match in the # `git-configs.json` file. It will also update the configuration if projects are deleted # or re-added to the client's directory, ensuring accurate and up-to-date Git settings. # # Note: This script requires `jq` for JSON parsing. Ensure it is installed and available in # your PATH. # # Following these setup and usage guidelines, teams can streamline their Git workflow, # ensuring all commits are correctly attributed and consistent across projects for each client, # and dynamically manage project directories within each client's configuration. # Workflow Diagram: # +----------------------------------+ +-------------------+ +---------------------+ +------------------------+ # | Manually add the folder and | | Verify if the | No | Read the JSON | | Iterate over each | # | configuration in +------->+ current directory +------->+ configuration file +------>+ configured directory | # | git-configs.json | | is a Git repo | | (git-configs.json) | | in the JSON | # +----------------------------------+ +--------+----------+ +---------------------+ +------------+-----------+ # | | # Yes | # | | # v v # +-----+------+ Configuration not exists / +-------------------------+ +--------------------------------+ # | End script | already applied for this dir | Apply Git configuration | | Update JSON file with the | # | execution |<------------------------------------ + (name, email) and +------>+ current directory added to | # +------------+ | update `subDirs` | | `subDirs` | # +-------------------------+ +--------------------------------+ # Path to the JSON configuration file, located in the same directory as this script CONFIG_FILE="$HOME/.config/git-configs.json" # This script dynamically applies Git configurations based on the current directory. # It reads settings from a JSON file, located in the same directory as the script. # The JSON file contains key-value pairs where each key is a path to a directory # (or parent directory of multiple repositories), and the value is an object # containing 'email' and 'name' for Git configuration. # JSON File Structure Example: # { # "/Users/username/Projects/ClientA": { # "email": "clienta@example.com", # "name": "Client A", # "subDirs": ["/Users/username/Projects/ClientA/Repo1", "/Users/username/Projects/ClientA/Repo2"] # }, # "/Users/username/Projects/ClientB": { # "email": "clientb@example.com", # "name": "Client B", # "subDirs": ["/Users/username/Projects/ClientB/Repo1"] # } # } # Each key in the JSON file represents a directory path for which the specified # Git configuration (email and name) should be applied. This allows for different # Git configurations to be automatically applied based on the current working directory. # Function to apply Git configuration apply_git_config() { local config_email=$(jq -r ".[\"$1\"].email" "$CONFIG_FILE") local config_name=$(jq -r ".[\"$1\"].name" "$CONFIG_FILE") local config_subdirs=$(jq -r ".[\"$1\"].subDirs[]" "$CONFIG_FILE") # Check if configuration exists for the path and has not been applied yet if [ "$config_email" != "null" ] && [ "$config_name" != "null" ] && [[ ! " $config_subdirs " =~ " $CURRENT_DIR " ]]; then git config user.email "$config_email" git config user.name "$config_name" # Update the 'subDirs' array in the JSON file jq --arg dir "$1" --arg subdir "$CURRENT_DIR" 'if .[$dir].subDirs == null then .[$dir].subDirs = [$subdir] else if (.[$dir].subDirs | index($subdir)) == null then .[$dir].subDirs += [$subdir] else . end end' "$CONFIG_FILE" > temp.$$ && mv temp.$$ "$CONFIG_FILE" fi } # Check if the current directory is a Git repository if git rev-parse --is-inside-work-tree > /dev/null 2>&1; then # Iterate through the directories defined in the JSON file and apply configuration if the current directory matches or is a subdirectory CURRENT_DIR=$(pwd) for KEY in $(jq -r 'keys[]' "$CONFIG_FILE"); do if [[ "$CURRENT_DIR" == "$KEY"* ]]; then apply_git_config "$KEY" break fi done fi