-
Notifications
You must be signed in to change notification settings - Fork 5.9k
feat: Add git workflow configuration to specify init #1483
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
2a5646c
45073d6
9c4b31c
cf9a82d
dfa0685
34ab928
a64247f
36fb9e6
48eaf15
e23e0e0
bba1991
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,238 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #!/usr/bin/env bash | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Configure git worktree preferences for Spec Kit | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| set -e | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Get script directory and source common functions | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| SCRIPT_DIR="$(CDPATH="" cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| source "$SCRIPT_DIR/common.sh" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Parse arguments | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| MODE="" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| STRATEGY="" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| CUSTOM_PATH="" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| SHOW_CONFIG=false | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| show_help() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| cat << 'EOF' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Usage: configure-worktree.sh [OPTIONS] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Configure git worktree preferences for Spec Kit feature creation. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Options: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| --mode <branch|worktree> Set git mode (default: branch) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| --strategy <nested|sibling|custom> Set worktree placement strategy | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| --path <path> Custom base path (required if strategy is 'custom') | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| --show Display current configuration | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| --help, -h Show this help message | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Strategies: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| nested - Worktrees in .worktrees/ directory inside the repository | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| sibling - Worktrees as sibling directories to the repository | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| custom - Worktrees in a custom directory (requires --path) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Examples: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Enable worktree mode with nested strategy | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| configure-worktree.sh --mode worktree --strategy nested | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Enable worktree mode with sibling strategy | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| configure-worktree.sh --mode worktree --strategy sibling | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Enable worktree mode with custom path | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| configure-worktree.sh --mode worktree --strategy custom --path /tmp/worktrees | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Switch back to branch mode | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| configure-worktree.sh --mode branch | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Show current configuration | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| configure-worktree.sh --show | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| EOF | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Parse command line arguments | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| while [[ $# -gt 0 ]]; do | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| case "$1" in | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| --mode) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [[ -z "$2" || "$2" == --* ]]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "Error: --mode requires a value (branch or worktree)" >&2 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| exit 1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| MODE="$2" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| shift 2 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ;; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| --strategy) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [[ -z "$2" || "$2" == --* ]]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "Error: --strategy requires a value (nested, sibling, or custom)" >&2 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| exit 1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| STRATEGY="$2" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| shift 2 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ;; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| --path) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [[ -z "$2" || "$2" == --* ]]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "Error: --path requires a value" >&2 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| exit 1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| CUSTOM_PATH="$2" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| shift 2 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ;; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| --show) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| SHOW_CONFIG=true | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| shift | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ;; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| --help|-h) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| show_help | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| exit 0 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ;; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| *) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "Error: Unknown option: $1" >&2 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "Use --help for usage information" >&2 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| exit 1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ;; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| esac | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| done | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Get repository root | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| REPO_ROOT=$(get_repo_root) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| CONFIG_FILE="$REPO_ROOT/.specify/config.json" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Show current configuration | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if $SHOW_CONFIG; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [[ ! -f "$CONFIG_FILE" ]]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "No configuration file found. Using defaults:" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo " git_mode: branch" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo " worktree_strategy: sibling" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo " worktree_custom_path: (none)" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| else | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "Current configuration ($CONFIG_FILE):" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo " git_mode: $(read_config_value "git_mode" "branch")" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo " worktree_strategy: $(read_config_value "worktree_strategy" "sibling")" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo " worktree_custom_path: $(read_config_value "worktree_custom_path" "(none)")" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| exit 0 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # If no options provided, show help | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [[ -z "$MODE" && -z "$STRATEGY" && -z "$CUSTOM_PATH" ]]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| show_help | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| exit 0 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Validate mode | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [[ -n "$MODE" ]]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [[ "$MODE" != "branch" && "$MODE" != "worktree" ]]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "Error: Invalid mode '$MODE'. Must be 'branch' or 'worktree'" >&2 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| exit 1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Validate strategy | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [[ -n "$STRATEGY" ]]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [[ "$STRATEGY" != "nested" && "$STRATEGY" != "sibling" && "$STRATEGY" != "custom" ]]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "Error: Invalid strategy '$STRATEGY'. Must be 'nested', 'sibling', or 'custom'" >&2 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| exit 1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Validate custom path requirements | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [[ "$STRATEGY" == "custom" && -z "$CUSTOM_PATH" ]]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "Error: --path is required when strategy is 'custom'" >&2 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| exit 1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Validate custom path is absolute | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [[ -n "$CUSTOM_PATH" ]]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [[ "$CUSTOM_PATH" != /* ]]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "Error: --path must be an absolute path (got: $CUSTOM_PATH)" >&2 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| exit 1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Check if path is writable (create parent if needed) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| CUSTOM_PARENT=$(dirname "$CUSTOM_PATH") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [[ ! -d "$CUSTOM_PARENT" ]]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "Error: Parent directory does not exist: $CUSTOM_PARENT" >&2 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| exit 1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [[ ! -w "$CUSTOM_PARENT" ]]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "Error: Parent directory is not writable: $CUSTOM_PARENT" >&2 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| exit 1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+149
to
+158
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Check if path is writable (create parent if needed) | |
| CUSTOM_PARENT=$(dirname "$CUSTOM_PATH") | |
| if [[ ! -d "$CUSTOM_PARENT" ]]; then | |
| echo "Error: Parent directory does not exist: $CUSTOM_PARENT" >&2 | |
| exit 1 | |
| fi | |
| if [[ ! -w "$CUSTOM_PARENT" ]]; then | |
| echo "Error: Parent directory is not writable: $CUSTOM_PARENT" >&2 | |
| exit 1 | |
| fi | |
| # Validate the custom path itself (if it exists) or its parent (if it does not) | |
| if [[ -e "$CUSTOM_PATH" ]]; then | |
| if [[ ! -d "$CUSTOM_PATH" ]]; then | |
| echo "Error: Custom path exists but is not a directory: $CUSTOM_PATH" >&2 | |
| exit 1 | |
| fi | |
| if [[ ! -w "$CUSTOM_PATH" ]]; then | |
| echo "Error: Custom path directory is not writable: $CUSTOM_PATH" >&2 | |
| exit 1 | |
| fi | |
| else | |
| CUSTOM_PARENT=$(dirname "$CUSTOM_PATH") | |
| if [[ ! -d "$CUSTOM_PARENT" ]]; then | |
| echo "Error: Parent directory does not exist: $CUSTOM_PARENT" >&2 | |
| exit 1 | |
| fi | |
| if [[ ! -w "$CUSTOM_PARENT" ]]; then | |
| echo "Error: Parent directory is not writable: $CUSTOM_PARENT" >&2 | |
| exit 1 | |
| fi | |
| fi |
Copilot
AI
Jan 17, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The default value for worktree_strategy in the scripts is "nested", but the init command and documentation state the default is "sibling". This creates an inconsistency where the --show command will display "nested" as default instead of "sibling".
Copilot
AI
Jan 17, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The default value for worktree_strategy in the scripts is "nested", but the init command and documentation state the default is "sibling". This creates an inconsistency where the --show command will display "nested" as default instead of "sibling".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The default value for worktree_strategy in the scripts is "nested", but the init command and documentation state the default is "sibling". This creates an inconsistency where the --show command will display "nested" as default instead of "sibling".