forked from humanlayer/humanlayer
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcreate_worktree.sh
More file actions
executable file
·148 lines (124 loc) · 4.58 KB
/
create_worktree.sh
File metadata and controls
executable file
·148 lines (124 loc) · 4.58 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#!/bin/bash
# create_worktree.sh - Create a new worktree for development work
# Usage: ./create_worktree.sh [--no-thoughts] [worktree_name] [base_branch]
# If no name provided, generates a unique human-readable one
# If no base branch provided, uses current branch
set -e # Exit on any error
# Function to generate a unique worktree name
generate_unique_name() {
local adjectives=("swift" "bright" "clever" "smooth" "quick" "clean" "sharp" "neat" "cool" "fast")
local nouns=("fix" "task" "work" "dev" "patch" "branch" "code" "build" "test" "run")
local adj=${adjectives[$RANDOM % ${#adjectives[@]}]}
local noun=${nouns[$RANDOM % ${#nouns[@]}]}
local timestamp=$(date +%H%M)
echo "${adj}_${noun}_${timestamp}"
}
# Parse flags
INIT_THOUGHTS=true
while [[ $# -gt 0 ]]; do
case $1 in
--no-thoughts)
INIT_THOUGHTS=false
shift
;;
*)
break
;;
esac
done
# Get worktree name from parameter or generate one
WORKTREE_NAME=${1:-$(generate_unique_name)}
# Get base branch from second parameter or use current branch
BASE_BRANCH=${2:-$(git branch --show-current)}
# Get base directory name (should be 'humanlayer')
REPO_BASE_NAME=$(basename "$(pwd)")
if [ ! -z "$HUMANLAYER_WORKTREE_OVERRIDE_BASE" ]; then
WORKTREE_DIR_NAME="${WORKTREE_NAME}"
WORKTREES_BASE="${HUMANLAYER_WORKTREE_OVERRIDE_BASE}/${REPO_BASE_NAME}"
else
WORKTREE_DIR_NAME="${WORKTREE_NAME}"
WORKTREES_BASE="$HOME/wt/${REPO_BASE_NAME}"
fi
WORKTREE_PATH="${WORKTREES_BASE}/${WORKTREE_DIR_NAME}"
echo "🌳 Creating worktree: ${WORKTREE_NAME}"
echo "📁 Location: ${WORKTREE_PATH}"
# Check if worktrees base directory exists
if [ ! -d "$WORKTREES_BASE" ]; then
echo "❌ Error: Directory $WORKTREES_BASE does not exist."
echo " Please create it first: mkdir -p $WORKTREES_BASE"
exit 1
fi
# Check if worktree already exists
if [ -d "$WORKTREE_PATH" ]; then
echo "❌ Error: Worktree directory already exists: $WORKTREE_PATH"
exit 1
fi
# Display base branch info
echo "🔀 Creating from branch: ${BASE_BRANCH}"
# Create worktree (creates branch if it doesn't exist)
if git show-ref --verify --quiet "refs/heads/${WORKTREE_NAME}"; then
echo "📋 Using existing branch: ${WORKTREE_NAME}"
git worktree add "$WORKTREE_PATH" "$WORKTREE_NAME"
else
echo "🆕 Creating new branch: ${WORKTREE_NAME}"
git worktree add -b "$WORKTREE_NAME" "$WORKTREE_PATH" "$BASE_BRANCH"
fi
# Copy .claude directory if it exists
if [ -d ".claude" ]; then
echo "📋 Copying .claude directory..."
cp -r .claude "$WORKTREE_PATH/"
fi
# Change to worktree directory
cd "$WORKTREE_PATH"
echo "🔧 Setting up worktree dependencies..."
if ! make setup; then
echo "❌ Setup failed. Cleaning up worktree..."
cd - > /dev/null
git worktree remove --force "$WORKTREE_PATH"
git branch -D "$WORKTREE_NAME" 2>/dev/null || true
echo "❌ Not allowed to create worktree from a branch that isn't passing setup."
exit 1
fi
# echo "🧪 Verifying worktree with checks and tests..."
# temp_output=$(mktemp)
# if make check test > "$temp_output" 2>&1; then
# rm "$temp_output"
# echo "✅ All checks and tests pass!"
# else
# cat "$temp_output"
# rm "$temp_output"
# echo "❌ Checks and tests failed. Cleaning up worktree..."
# cd - > /dev/null
# git worktree remove --force "$WORKTREE_PATH"
# git branch -D "$WORKTREE_NAME" 2>/dev/null || true
# echo "❌ Not allowed to create worktree from a branch that isn't passing checks and tests."
# exit 1
# fi
# Initialize thoughts (non-interactive mode with hardcoded directory)
if [ "$INIT_THOUGHTS" = true ]; then
echo "🧠 Initializing thoughts..."
cd "$WORKTREE_PATH"
if humanlayer thoughts init --directory humanlayer > /dev/null 2>&1; then
echo "✅ Thoughts initialized!"
# Run sync to create searchable directory
if humanlayer thoughts sync > /dev/null 2>&1; then
echo "✅ Thoughts searchable index created!"
else
echo "⚠️ Could not create searchable index. Run 'humanlayer thoughts sync' manually."
fi
else
echo "⚠️ Could not initialize thoughts automatically. Run 'humanlayer thoughts init' manually."
fi
fi
# Return to original directory
cd - > /dev/null
echo "✅ Worktree created successfully!"
echo "📁 Path: ${WORKTREE_PATH}"
echo "🔀 Branch: ${WORKTREE_NAME}"
echo ""
echo "To work in this worktree:"
echo " cd ${WORKTREE_PATH}"
echo ""
echo "To remove this worktree later:"
echo " git worktree remove ${WORKTREE_PATH}"
echo " git branch -D ${WORKTREE_NAME}"