gitbash 1.8.2 → 1.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/commands/pr.sh +10 -4
- package/commands/switch.sh +132 -16
- package/package.json +1 -1
package/commands/pr.sh
CHANGED
|
@@ -81,15 +81,21 @@ EOF
|
|
|
81
81
|
if [[ "$has_changes" == true ]]; then
|
|
82
82
|
echo "You have uncommitted changes or untracked files."
|
|
83
83
|
echo ""
|
|
84
|
-
|
|
85
|
-
# Source _utils.sh for prompt_read
|
|
84
|
+
|
|
85
|
+
# Source _utils.sh for prompt_read (status may use prompts)
|
|
86
86
|
if ! declare -f prompt_read >/dev/null 2>&1; then
|
|
87
87
|
SOURCE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]:-$0}")" && pwd)"
|
|
88
88
|
source "$SOURCE_DIR/_utils.sh"
|
|
89
89
|
fi
|
|
90
|
-
|
|
90
|
+
|
|
91
91
|
local commit_answer
|
|
92
|
-
|
|
92
|
+
# If -p/--push was provided, assume the user wants to commit (don't ask)
|
|
93
|
+
if [[ "$should_push" == true ]]; then
|
|
94
|
+
commit_answer="y"
|
|
95
|
+
else
|
|
96
|
+
prompt_read "Would you like to commit them first? (Y/n): " commit_answer
|
|
97
|
+
fi
|
|
98
|
+
|
|
93
99
|
case "$commit_answer" in
|
|
94
100
|
[nN][oO]|[nN])
|
|
95
101
|
echo "Continuing without committing..."
|
package/commands/switch.sh
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
|
+
## switch selects and switches git branches using fzf
|
|
3
|
+
# shellcheck shell=bash
|
|
2
4
|
# shellcheck disable=SC2155
|
|
3
5
|
|
|
4
6
|
# Source common utilities
|
|
@@ -76,6 +78,9 @@ EOF
|
|
|
76
78
|
# Get local branches
|
|
77
79
|
local local_branches
|
|
78
80
|
local_branches=$(git branch --format='%(refname:short)')
|
|
81
|
+
# Get merged local branches (merged into HEAD) in a portable way
|
|
82
|
+
local merged_local_branches
|
|
83
|
+
merged_local_branches=$(git branch --merged | sed 's/^..//' | sed '/^$/d' || true)
|
|
79
84
|
|
|
80
85
|
# Get remote branches, filter out those that already exist locally
|
|
81
86
|
local remote_branches
|
|
@@ -91,8 +96,21 @@ EOF
|
|
|
91
96
|
local branch_list
|
|
92
97
|
branch_list=$(
|
|
93
98
|
{
|
|
94
|
-
# List local branches
|
|
95
|
-
echo "$local_branches" |
|
|
99
|
+
# List local branches, marking merged ones as 'merged:' (but keep current branch as local)
|
|
100
|
+
echo "$local_branches" | while IFS= read -r lb; do
|
|
101
|
+
# Skip empty lines
|
|
102
|
+
[[ -z "$lb" ]] && continue
|
|
103
|
+
if [[ "$lb" == "$current_branch" ]]; then
|
|
104
|
+
echo "local: $lb"
|
|
105
|
+
elif [[ "$lb" == "master" || "$lb" == "main" ]]; then
|
|
106
|
+
# Keep main branches labelled as local
|
|
107
|
+
echo "local: $lb"
|
|
108
|
+
elif echo "$merged_local_branches" | grep -xq -- "${lb}" 2>/dev/null; then
|
|
109
|
+
echo "merged: $lb"
|
|
110
|
+
else
|
|
111
|
+
echo "local: $lb"
|
|
112
|
+
fi
|
|
113
|
+
done
|
|
96
114
|
# Spacer (only if there are remote branches to show)
|
|
97
115
|
if [[ -n "$remote_branches" ]]; then
|
|
98
116
|
echo "─────────────────────────────"
|
|
@@ -102,6 +120,12 @@ EOF
|
|
|
102
120
|
}
|
|
103
121
|
)
|
|
104
122
|
|
|
123
|
+
# If no branches were found, bail out to avoid fzf listing files
|
|
124
|
+
if [[ -z "$(echo "$branch_list" | sed -n '1p' || true)" ]]; then
|
|
125
|
+
echo "No branches found in this repository."
|
|
126
|
+
return 0
|
|
127
|
+
fi
|
|
128
|
+
|
|
105
129
|
# -----------------------------
|
|
106
130
|
# 3b. Check for single match when filter is provided
|
|
107
131
|
# -----------------------------
|
|
@@ -119,25 +143,117 @@ EOF
|
|
|
119
143
|
selected_branch="$matching_branches"
|
|
120
144
|
print_info "Single match found, switching directly..."
|
|
121
145
|
fi
|
|
146
|
+
# If provided filter yields no matches, clear the query so fzf opens unfiltered
|
|
147
|
+
if [[ "$match_count" == "0" ]]; then
|
|
148
|
+
filter_for_fzf=""
|
|
149
|
+
else
|
|
150
|
+
filter_for_fzf="$filter"
|
|
151
|
+
fi
|
|
122
152
|
fi
|
|
123
153
|
|
|
124
154
|
# -----------------------------
|
|
125
155
|
# 3c. Use fzf if no single match
|
|
126
156
|
# -----------------------------
|
|
127
157
|
if [[ -z "$selected_branch" ]]; then
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
158
|
+
# Write branch list to a temp file so fzf can reload after deletions
|
|
159
|
+
branches_file=$(mktemp)
|
|
160
|
+
printf '%s\n' "$branch_list" > "$branches_file"
|
|
161
|
+
|
|
162
|
+
# Create a small helper script to delete the selected branch safely (asks for confirmation).
|
|
163
|
+
delete_script=$(mktemp)
|
|
164
|
+
cat > "$delete_script" <<'DEL_SH'
|
|
165
|
+
#!/usr/bin/env bash
|
|
166
|
+
line="$1"
|
|
167
|
+
branches_file="$2"
|
|
168
|
+
|
|
169
|
+
if [[ "$line" == *───* ]]; then
|
|
170
|
+
echo "Spacer - not deletable"
|
|
171
|
+
exit 0
|
|
172
|
+
fi
|
|
173
|
+
|
|
174
|
+
type="${line%%:*}"
|
|
175
|
+
branch="${line#*: }"
|
|
176
|
+
|
|
177
|
+
if [[ "$type" == "local" || "$type" == "merged" ]]; then
|
|
178
|
+
# Ask for confirmation via the terminal (/dev/tty). Default answer is Yes when empty.
|
|
179
|
+
while true; do
|
|
180
|
+
printf "Delete local branch '%s'? [Y/n]: " "$branch" > /dev/tty
|
|
181
|
+
read -r answer < /dev/tty
|
|
182
|
+
case "$answer" in
|
|
183
|
+
''|[yY]|[yY][eE][sS])
|
|
184
|
+
break
|
|
185
|
+
;;
|
|
186
|
+
[nN]|[nN][oO])
|
|
187
|
+
echo "Aborted deletion of $branch"
|
|
188
|
+
exit 0
|
|
189
|
+
;;
|
|
190
|
+
*)
|
|
191
|
+
echo "Please answer y or n" > /dev/tty
|
|
192
|
+
;;
|
|
193
|
+
esac
|
|
194
|
+
done
|
|
195
|
+
|
|
196
|
+
if git branch -D "$branch"; then
|
|
197
|
+
echo "Deleted local $branch"
|
|
198
|
+
awk -v l="$line" '$0!=l' "$branches_file" > "$branches_file".new && mv "$branches_file".new "$branches_file"
|
|
199
|
+
else
|
|
200
|
+
echo "Failed to delete $branch"
|
|
201
|
+
fi
|
|
202
|
+
else
|
|
203
|
+
echo "Remote branch deletion is disabled in this UI. Delete remote branches manually with: git push <remote> --delete <branch>"
|
|
204
|
+
exit 0
|
|
205
|
+
fi
|
|
206
|
+
DEL_SH
|
|
207
|
+
chmod +x "$delete_script"
|
|
208
|
+
|
|
209
|
+
# Loop running fzf so we can handle delete keys via --expect and reload after deletion
|
|
210
|
+
selected_branch=""
|
|
211
|
+
while true; do
|
|
212
|
+
fzf_out=$(
|
|
213
|
+
fzf \
|
|
214
|
+
--height=40% \
|
|
215
|
+
--reverse \
|
|
216
|
+
--border \
|
|
217
|
+
--expect=enter,delete \
|
|
218
|
+
--query="${filter_for_fzf:-$filter}" \
|
|
219
|
+
-i \
|
|
220
|
+
--preview="branch=\$(echo {} | sed 's/^[^:]*: //'); if [[ \"\$branch\" == *───* ]]; then echo 'Spacer - not selectable'; else git log --color=always -n 1 --format='%C(bold cyan)Author:%C(reset) %an%n%C(bold cyan)Date:%C(reset) %ar (%ad)%n%C(bold cyan)Message:%C(reset) %s%n' --date=format:'%Y-%m-%d %H:%M' \"\$branch\" 2>/dev/null && echo && git log --oneline --color=always -n 10 \"\$branch\" 2>/dev/null; fi" \
|
|
221
|
+
--preview-window=right:50% \
|
|
222
|
+
--header="[Enter] switch | [Del] delete (local only) | [Esc] exit | Current: $current_branch" \
|
|
223
|
+
< "$branches_file"
|
|
224
|
+
) </dev/tty || true
|
|
225
|
+
|
|
226
|
+
key_pressed=$(echo "$fzf_out" | head -n1)
|
|
227
|
+
selection=$(echo "$fzf_out" | tail -n +2 | head -n1)
|
|
228
|
+
|
|
229
|
+
# No selection or escape
|
|
230
|
+
if [[ -z "$key_pressed" && -z "$selection" ]]; then
|
|
231
|
+
selected_branch=""
|
|
232
|
+
break
|
|
233
|
+
fi
|
|
234
|
+
|
|
235
|
+
if [[ "$key_pressed" == "enter" ]]; then
|
|
236
|
+
selected_branch="$selection"
|
|
237
|
+
break
|
|
238
|
+
fi
|
|
239
|
+
|
|
240
|
+
if [[ "$key_pressed" == "delete" ]]; then
|
|
241
|
+
# perform deletion on the selected line and continue loop
|
|
242
|
+
if [[ -n "$selection" ]]; then
|
|
243
|
+
"$delete_script" "$selection" "$branches_file"
|
|
244
|
+
fi
|
|
245
|
+
continue
|
|
246
|
+
fi
|
|
247
|
+
|
|
248
|
+
# If there is a selection without a key, treat as accept
|
|
249
|
+
if [[ -n "$selection" ]]; then
|
|
250
|
+
selected_branch="$selection"
|
|
251
|
+
break
|
|
252
|
+
fi
|
|
253
|
+
done
|
|
254
|
+
|
|
255
|
+
# Clean up temp files
|
|
256
|
+
rm -f "$delete_script" "$branches_file"
|
|
141
257
|
fi
|
|
142
258
|
|
|
143
259
|
# -----------------------------
|
|
@@ -162,7 +278,7 @@ EOF
|
|
|
162
278
|
# 5. Switch to branch
|
|
163
279
|
# -----------------------------
|
|
164
280
|
local switch_success=false
|
|
165
|
-
if [[ "$branch_type" == "local" ]]; then
|
|
281
|
+
if [[ "$branch_type" == "local" || "$branch_type" == "merged" ]]; then
|
|
166
282
|
# Switch to local branch
|
|
167
283
|
echo "Switching to local branch: $branch_name"
|
|
168
284
|
if git checkout "$branch_name"; then
|