@san-siva/gitsy 1.0.0
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/LICENSE +21 -0
- package/README.md +53 -0
- package/g-cb +47 -0
- package/g-co +106 -0
- package/g-db +122 -0
- package/g-diff +228 -0
- package/g-dlc +109 -0
- package/g-pull +72 -0
- package/g-push +67 -0
- package/g-rmf +57 -0
- package/g-rto +50 -0
- package/g-s +50 -0
- package/g-wa +155 -0
- package/g-wr +260 -0
- package/package.json +70 -0
- package/utils +464 -0
package/package.json
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@san-siva/gitsy",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "A set of bash utilities for managing Git repositories with ease",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"git",
|
|
7
|
+
"cli",
|
|
8
|
+
"bash",
|
|
9
|
+
"git-tools",
|
|
10
|
+
"git-utilities",
|
|
11
|
+
"workflow",
|
|
12
|
+
"productivity"
|
|
13
|
+
],
|
|
14
|
+
"homepage": "https://gitsy-56895.web.app",
|
|
15
|
+
"repository": {
|
|
16
|
+
"type": "git",
|
|
17
|
+
"url": "git+https://github.com/san-siva/gitsy.git"
|
|
18
|
+
},
|
|
19
|
+
"bugs": {
|
|
20
|
+
"url": "https://github.com/san-siva/gitsy/issues"
|
|
21
|
+
},
|
|
22
|
+
"author": {
|
|
23
|
+
"name": "Santhosh Siva",
|
|
24
|
+
"url": "https://github.com/san-siva"
|
|
25
|
+
},
|
|
26
|
+
"license": "MIT",
|
|
27
|
+
"bin": {
|
|
28
|
+
"g-co": "./g-co",
|
|
29
|
+
"g-pull": "./g-pull",
|
|
30
|
+
"g-push": "./g-push",
|
|
31
|
+
"g-wa": "./g-wa",
|
|
32
|
+
"g-wr": "./g-wr",
|
|
33
|
+
"g-db": "./g-db",
|
|
34
|
+
"g-dlc": "./g-dlc",
|
|
35
|
+
"g-rmf": "./g-rmf",
|
|
36
|
+
"g-rto": "./g-rto",
|
|
37
|
+
"g-cb": "./g-cb",
|
|
38
|
+
"g-s": "./g-s",
|
|
39
|
+
"g-diff": "./g-diff"
|
|
40
|
+
},
|
|
41
|
+
"files": [
|
|
42
|
+
"g-co",
|
|
43
|
+
"g-pull",
|
|
44
|
+
"g-push",
|
|
45
|
+
"g-wa",
|
|
46
|
+
"g-wr",
|
|
47
|
+
"g-db",
|
|
48
|
+
"g-dlc",
|
|
49
|
+
"g-rmf",
|
|
50
|
+
"g-rto",
|
|
51
|
+
"g-cb",
|
|
52
|
+
"g-s",
|
|
53
|
+
"g-diff",
|
|
54
|
+
"utils",
|
|
55
|
+
"README.md",
|
|
56
|
+
"LICENSE"
|
|
57
|
+
],
|
|
58
|
+
"scripts": {
|
|
59
|
+
"test": "bash -c 'for script in g-*; do bash -n \"$script\" || exit 1; done'",
|
|
60
|
+
"postinstall": "echo '\\n✓ gitsy installed successfully!\\n\\nDependencies required: git, figlet, lolcat\\n\\nRun any command with --help to get started:\\n g-co --help\\n\\nDocumentation: https://gitsy-56895.web.app\\n'"
|
|
61
|
+
},
|
|
62
|
+
"engines": {
|
|
63
|
+
"node": ">=12.0.0"
|
|
64
|
+
},
|
|
65
|
+
"os": [
|
|
66
|
+
"darwin",
|
|
67
|
+
"linux"
|
|
68
|
+
],
|
|
69
|
+
"preferGlobal": true
|
|
70
|
+
}
|
package/utils
ADDED
|
@@ -0,0 +1,464 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
|
|
3
|
+
# Author: Santhosh Siva
|
|
4
|
+
# Date Created: 03-08-2025
|
|
5
|
+
|
|
6
|
+
# Colors
|
|
7
|
+
BLUE=$(tput setaf 4)
|
|
8
|
+
PROMPT=$(tput setaf 3)
|
|
9
|
+
GREEN=$(tput setaf 2)
|
|
10
|
+
RED=$(tput setaf 1)
|
|
11
|
+
NC=$(tput sgr0)
|
|
12
|
+
|
|
13
|
+
overwrite() { echo -e "\r\033[1A\033[0K$@"; }
|
|
14
|
+
|
|
15
|
+
default_spaces=" "
|
|
16
|
+
|
|
17
|
+
print_message() {
|
|
18
|
+
local number=$2
|
|
19
|
+
local message=$1
|
|
20
|
+
|
|
21
|
+
if [ -z "$message" ]; then
|
|
22
|
+
message=""
|
|
23
|
+
fi
|
|
24
|
+
|
|
25
|
+
if [ -z "$number" ]; then
|
|
26
|
+
number=0
|
|
27
|
+
fi
|
|
28
|
+
|
|
29
|
+
if [ "$number" -eq 0 ]; then
|
|
30
|
+
echo -e " $message"
|
|
31
|
+
return 0
|
|
32
|
+
fi
|
|
33
|
+
|
|
34
|
+
# print_message ""
|
|
35
|
+
|
|
36
|
+
if [ "$number" -lt 10 ]; then
|
|
37
|
+
printf "%d. %s\n" "$number" "$message"
|
|
38
|
+
return 0
|
|
39
|
+
fi
|
|
40
|
+
|
|
41
|
+
printf "%02d. %s\n" "$number" "$message"
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
indent() {
|
|
45
|
+
local prefix=" │ "
|
|
46
|
+
sed "s/^/${prefix}/"
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
install_dependency() {
|
|
50
|
+
local cmd=$1
|
|
51
|
+
local package=$2
|
|
52
|
+
|
|
53
|
+
if ! command -v "$cmd" >/dev/null; then
|
|
54
|
+
if brew install "$package" >>"$log_file" 2>>"$error_log_file"; then
|
|
55
|
+
return
|
|
56
|
+
else
|
|
57
|
+
print_message "${RED}Failed to install $package.${NC}"
|
|
58
|
+
exit 1
|
|
59
|
+
fi
|
|
60
|
+
fi
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
validate_dependencies() {
|
|
64
|
+
for cmd in $@; do
|
|
65
|
+
install_dependency "$cmd" "$cmd"
|
|
66
|
+
done
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
print_banner() {
|
|
70
|
+
print_message ""
|
|
71
|
+
figlet -f slant "Gitsy" | lolcat
|
|
72
|
+
print_message ""
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
prompt_user() {
|
|
76
|
+
local default_to_yes=$1
|
|
77
|
+
local message=$2
|
|
78
|
+
local step_number=$3
|
|
79
|
+
|
|
80
|
+
if [ -n "$step_number" ] && [ "$step_number" -ne 0 ]; then
|
|
81
|
+
local prefix="$(printf "%${default_spaces}s")${step_number}. "
|
|
82
|
+
elif [ "$step_number" -eq 0 ]; then
|
|
83
|
+
local prefix="$(printf "%${default_spaces}s") "
|
|
84
|
+
else
|
|
85
|
+
local prefix="$(printf "%${default_spaces}s")- "
|
|
86
|
+
fi
|
|
87
|
+
|
|
88
|
+
local prompt="${prefix}${PROMPT}${message}${NC} "
|
|
89
|
+
|
|
90
|
+
if [ "$default_to_yes" = "true" ]; then
|
|
91
|
+
read -p "${prompt}(Y/n): " response
|
|
92
|
+
response="${response:-y}"
|
|
93
|
+
else
|
|
94
|
+
read -p "${prompt}(y/N): " response
|
|
95
|
+
response="${response:-n}"
|
|
96
|
+
fi
|
|
97
|
+
|
|
98
|
+
case "$response" in
|
|
99
|
+
[Yy]) echo "y" ;;
|
|
100
|
+
[Nn]) echo "n" ;;
|
|
101
|
+
*) print_message "Invalid input." 0 && exit 1 ;;
|
|
102
|
+
esac
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
fetch_current_branch() {
|
|
106
|
+
current_branch=$(git rev-parse --abbrev-ref HEAD)
|
|
107
|
+
if [ -z "$current_branch" ]; then
|
|
108
|
+
print_message "${RED}Failed to get current branch. [Fail]${NC}"
|
|
109
|
+
exit 1
|
|
110
|
+
fi
|
|
111
|
+
echo "${current_branch}"
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
stash_changes() {
|
|
115
|
+
local stash_changes=$1
|
|
116
|
+
local step_number=$2
|
|
117
|
+
local tag_message=$3
|
|
118
|
+
|
|
119
|
+
if [ -z "$step_number" ]; then
|
|
120
|
+
step_number=0
|
|
121
|
+
fi
|
|
122
|
+
|
|
123
|
+
if [ "$stash_changes" = "true" ]; then
|
|
124
|
+
print_message "${BLUE}Stashing changes...${NC}" $step_number
|
|
125
|
+
|
|
126
|
+
if ! (git -c color.ui=always add -A 2>&1 | indent); then
|
|
127
|
+
print_message "${RED}Failed to add changes to stash. [Fail]${NC}" 0
|
|
128
|
+
exit 1
|
|
129
|
+
fi
|
|
130
|
+
|
|
131
|
+
local stash_message
|
|
132
|
+
local branch_name=$(git rev-parse --abbrev-ref HEAD)
|
|
133
|
+
local stash_date=$(date '+%Y-%m-%d %H:%M:%S')
|
|
134
|
+
|
|
135
|
+
if [ -n "$tag_message" ]; then
|
|
136
|
+
stash_message="Manual stash; Branch: ${branch_name}; Date: ${stash_date}; Message: ${tag_message}"
|
|
137
|
+
else
|
|
138
|
+
stash_message="Auto stash; Branch: ${branch_name}; Date: ${stash_date}"
|
|
139
|
+
fi
|
|
140
|
+
|
|
141
|
+
if ! (git -c color.ui=always stash push -m "$stash_message" 2>&1 | indent 4); then
|
|
142
|
+
print_message "${RED}Failed to stash changes. [Fail]${NC}" 0
|
|
143
|
+
exit 1
|
|
144
|
+
fi
|
|
145
|
+
|
|
146
|
+
print_message "${GREEN}Changes stashed successfully.${NC}" 0
|
|
147
|
+
fi
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
fetch_changes() {
|
|
151
|
+
local target_branch=$1
|
|
152
|
+
|
|
153
|
+
if [ -z "$target_branch" ]; then
|
|
154
|
+
print_message "${RED}Target branch is not set. [Fail]${NC}" 0
|
|
155
|
+
return 1
|
|
156
|
+
fi
|
|
157
|
+
|
|
158
|
+
if ! git -c color.ui=always fetch origin "${target_branch}" 2>&1 | indent; then
|
|
159
|
+
print_message "${PROMPT}Auto-Fetch failed, Please do it manually.${NC}"
|
|
160
|
+
return 1
|
|
161
|
+
else
|
|
162
|
+
return 0
|
|
163
|
+
fi
|
|
164
|
+
|
|
165
|
+
return 0
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
checkout_branch() {
|
|
169
|
+
local target_branch=$1
|
|
170
|
+
local new_branch=$2
|
|
171
|
+
|
|
172
|
+
if [ -z "$target_branch" ]; then
|
|
173
|
+
print_message "${RED}Target branch is not set. [Fail]${NC}"
|
|
174
|
+
exit 1
|
|
175
|
+
fi
|
|
176
|
+
|
|
177
|
+
if [ "$new_branch" = "true" ]; then
|
|
178
|
+
if ! git -c color.ui=always checkout -b "${target_branch}" 2>&1 | indent; then
|
|
179
|
+
print_message "${RED}Failed to create new branch. [Fail]${NC}"
|
|
180
|
+
exit 1
|
|
181
|
+
fi
|
|
182
|
+
print_message "${GREEN}Created new local branch ${NC}${target_branch}${GREEN}. [DONE]${NC}"
|
|
183
|
+
return 0
|
|
184
|
+
fi
|
|
185
|
+
|
|
186
|
+
if ! git -c color.ui=always checkout "${target_branch}" 2>&1 | indent; then
|
|
187
|
+
print_message "${RED}Failed to checkout to branch ${NC}${target_branch}${RED}. [Fail]${NC}"
|
|
188
|
+
exit 1
|
|
189
|
+
fi
|
|
190
|
+
return 0
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
create_worktree() {
|
|
194
|
+
local target_branch="$1"
|
|
195
|
+
local worktree_path="$2"
|
|
196
|
+
local new_branch="$3"
|
|
197
|
+
local base_branch
|
|
198
|
+
local created_worktree_message="${GREEN}Successfully created worktree for branch ${NC}$target_branch${GREEN} at ${NC}$worktree_path${GREEN}. [DONE]${NC}"
|
|
199
|
+
local failed_worktree_message="${RED}Failed to create worktree for branch ${NC}$target_branch${RED}. [Fail]${NC}"
|
|
200
|
+
|
|
201
|
+
if [ -z "$target_branch" ]; then
|
|
202
|
+
print_message "${RED}Target branch is not set. [Fail]${NC}"
|
|
203
|
+
exit 1
|
|
204
|
+
fi
|
|
205
|
+
if [ -z "$worktree_path" ]; then
|
|
206
|
+
print_message "${RED}Worktree path is not set. [Fail]${NC}"
|
|
207
|
+
exit 1
|
|
208
|
+
fi
|
|
209
|
+
if [ -d "$worktree_path" ]; then
|
|
210
|
+
print_message "${RED}Worktree path already exists. [Fail]${NC}"
|
|
211
|
+
exit 1
|
|
212
|
+
fi
|
|
213
|
+
|
|
214
|
+
base_branch=$(fetch_current_branch)
|
|
215
|
+
if [ -z "$base_branch" ]; then
|
|
216
|
+
print_message "${RED}Failed to get current branch. [Fail]${NC}"
|
|
217
|
+
exit 1
|
|
218
|
+
fi
|
|
219
|
+
|
|
220
|
+
if [ "$new_branch" = "true" ]; then
|
|
221
|
+
# Make sure the source branch exists remotely!
|
|
222
|
+
if ! git rev-parse --verify "origin/$base_branch" >/dev/null 2>&1; then
|
|
223
|
+
print_message "${RED}Base branch ${NC}origin/$base_branch${RED} not found. Cannot create new branch.${NC}"
|
|
224
|
+
exit 1
|
|
225
|
+
fi
|
|
226
|
+
|
|
227
|
+
# Use the -b flag on worktree directly:
|
|
228
|
+
local worktree_output
|
|
229
|
+
worktree_output=$(git -c color.ui=always worktree add -b "$target_branch" "$worktree_path" "origin/$base_branch" 2>&1)
|
|
230
|
+
local worktree_exit_code=$?
|
|
231
|
+
|
|
232
|
+
echo "$worktree_output" | indent
|
|
233
|
+
|
|
234
|
+
if [ $worktree_exit_code -ne 0 ]; then
|
|
235
|
+
print_message "${failed_worktree_message}"
|
|
236
|
+
exit 1
|
|
237
|
+
fi
|
|
238
|
+
|
|
239
|
+
print_message "${BLUE}Pushing new branch ${NC}$target_branch${BLUE} to remote...${NC}"
|
|
240
|
+
if ! git -c color.ui=always push -u origin "$target_branch" 2>&1 | indent; then
|
|
241
|
+
print_message "${RED}Failed to push new branch ${NC}$target_branch${RED} to remote. [Fail]${NC}"
|
|
242
|
+
exit 1
|
|
243
|
+
fi
|
|
244
|
+
|
|
245
|
+
print_message "${created_worktree_message}"
|
|
246
|
+
return 0
|
|
247
|
+
fi
|
|
248
|
+
|
|
249
|
+
# Just add the worktree to an existing branch:
|
|
250
|
+
local worktree_output
|
|
251
|
+
worktree_output=$(git -c color.ui=always worktree add "$worktree_path" "$target_branch" 2>&1)
|
|
252
|
+
local worktree_exit_code=$?
|
|
253
|
+
|
|
254
|
+
echo "$worktree_output" | indent
|
|
255
|
+
|
|
256
|
+
if [ $worktree_exit_code -ne 0 ]; then
|
|
257
|
+
print_message "${failed_worktree_message}"
|
|
258
|
+
exit 1
|
|
259
|
+
fi
|
|
260
|
+
|
|
261
|
+
print_message "${created_worktree_message}"
|
|
262
|
+
return 0
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
reset_to_target_branch() {
|
|
266
|
+
local target_branch=$1
|
|
267
|
+
local step_number=$2
|
|
268
|
+
|
|
269
|
+
if [ -z "$step_number" ]; then
|
|
270
|
+
step_number=0
|
|
271
|
+
fi
|
|
272
|
+
|
|
273
|
+
if [ -z "$target_branch" ]; then
|
|
274
|
+
print_message "${RED}Target branch is not set. [Fail]${NC}"
|
|
275
|
+
exit 1
|
|
276
|
+
fi
|
|
277
|
+
|
|
278
|
+
print_message "${BLUE}Resetting to ${NC}origin/${target_branch}${BLUE}...${NC}" $step_number
|
|
279
|
+
|
|
280
|
+
if ! git -c color.ui=always reset --hard "origin/${target_branch}" 2>&1 | indent; then
|
|
281
|
+
print_message "${RED}Failed to reset to ${NC}origin/${target_branch}${RED}. [Fail]${NC}"
|
|
282
|
+
exit 1
|
|
283
|
+
fi
|
|
284
|
+
|
|
285
|
+
print_message "${GREEN}Reset to ${NC}origin/${target_branch}${GREEN} successfully.${NC}"
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
pull_changes() {
|
|
289
|
+
local target_branch=$1
|
|
290
|
+
local step_number=$2
|
|
291
|
+
|
|
292
|
+
if [ -z "$step_number" ]; then
|
|
293
|
+
step_number=0
|
|
294
|
+
fi
|
|
295
|
+
|
|
296
|
+
if [ -z "$target_branch" ]; then
|
|
297
|
+
print_message "${RED}Target branch is not set. [Fail]${NC}"
|
|
298
|
+
exit 1
|
|
299
|
+
fi
|
|
300
|
+
|
|
301
|
+
print_message "${BLUE}Pulling changes from ${NC}remote/${target_branch}${BLUE}...${NC}" $step_number
|
|
302
|
+
if ! git -c color.ui=always pull origin "${target_branch}" 2>&1 | indent; then
|
|
303
|
+
print_message "${RED}Failed to pull changes from remote. [Fail]${NC}"
|
|
304
|
+
exit 1
|
|
305
|
+
fi
|
|
306
|
+
print_message "${GREEN}Pulled changes from ${NC}remote/${target_branch} ${GREEN}successfully.${NC}"
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
push_changes() {
|
|
310
|
+
local target_branch=$1
|
|
311
|
+
local should_force_push=$2
|
|
312
|
+
local step_number=$3
|
|
313
|
+
|
|
314
|
+
if [ -z "$step_number" ]; then
|
|
315
|
+
step_number=0
|
|
316
|
+
fi
|
|
317
|
+
|
|
318
|
+
if [ -z "$target_branch" ]; then
|
|
319
|
+
print_message "${RED}Target branch is not set. [Fail]${NC}"
|
|
320
|
+
exit 1
|
|
321
|
+
fi
|
|
322
|
+
|
|
323
|
+
# Check if local branch is behind remote
|
|
324
|
+
if [ "$should_force_push" = "false" ]; then
|
|
325
|
+
fetch_changes "${target_branch}" >/dev/null 2>&1
|
|
326
|
+
local local_commit=$(git rev-parse "${target_branch}" 2>/dev/null)
|
|
327
|
+
local remote_commit=$(git rev-parse "origin/${target_branch}" 2>/dev/null)
|
|
328
|
+
|
|
329
|
+
if [ -n "$local_commit" ] && [ -n "$remote_commit" ] && [ "$local_commit" != "$remote_commit" ]; then
|
|
330
|
+
if ! git merge-base --is-ancestor "origin/${target_branch}" "${target_branch}" 2>/dev/null; then
|
|
331
|
+
print_message "${RED}Error: Your local branch is behind or has diverged from remote.${NC}" 0
|
|
332
|
+
print_message "${RED}Use ${NC}--force${RED} flag if you want to force push.${NC}" 0
|
|
333
|
+
exit 1
|
|
334
|
+
fi
|
|
335
|
+
fi
|
|
336
|
+
fi
|
|
337
|
+
|
|
338
|
+
if [ "$should_force_push" = "true" ]; then
|
|
339
|
+
print_message "${BLUE}Force pushing changes to ${NC}remote/${target_branch}${BLUE}...${NC}" $step_number
|
|
340
|
+
if ! git -c color.ui=always push --force origin "${target_branch}" 2>&1 | indent; then
|
|
341
|
+
print_message "${RED}Failed to force push changes to remote. [Fail]${NC}"
|
|
342
|
+
exit 1
|
|
343
|
+
fi
|
|
344
|
+
else
|
|
345
|
+
print_message "${BLUE}Pushing changes to ${NC}remote/${target_branch}${BLUE}...${NC}" $step_number
|
|
346
|
+
if ! git -c color.ui=always push origin "${target_branch}" 2>&1 | indent; then
|
|
347
|
+
print_message "${RED}Failed to push changes to remote. [Fail]${NC}"
|
|
348
|
+
exit 1
|
|
349
|
+
fi
|
|
350
|
+
fi
|
|
351
|
+
print_message "${GREEN}Pushed changes to ${NC}remote/${target_branch} ${GREEN}successfully.${NC}"
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
already_on_branch() {
|
|
355
|
+
local target_branch=$1
|
|
356
|
+
print_message "${BLUE}Checking current branch...${NC}" 1
|
|
357
|
+
current_branch=$(fetch_current_branch true)
|
|
358
|
+
if [ "${target_branch}" = "${current_branch}" ]; then
|
|
359
|
+
print_message "${GREEN}Already on branch ${NC}${target_branch}${GREEN}. [DONE]${NC}"
|
|
360
|
+
exit 1
|
|
361
|
+
fi
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
check_if_target_branch_is_set() {
|
|
365
|
+
local target_branch=$1
|
|
366
|
+
if [ -z "${target_branch}" ]; then
|
|
367
|
+
print_message "${RED}Error: No target branch specified, use -t or --target-branch option.${NC}"
|
|
368
|
+
exit 1
|
|
369
|
+
fi
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
navigate_to_dir() {
|
|
373
|
+
local dir=$1
|
|
374
|
+
if pwd | grep -q "$dir"; then
|
|
375
|
+
return 0
|
|
376
|
+
fi
|
|
377
|
+
if ! cd "$dir" 2>/dev/null; then
|
|
378
|
+
return 1
|
|
379
|
+
fi
|
|
380
|
+
return 0
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
check_uncommitted_changes() {
|
|
384
|
+
if ! git diff-index --quiet HEAD --; then
|
|
385
|
+
return 1
|
|
386
|
+
fi
|
|
387
|
+
return 0
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
is_git_repo() {
|
|
391
|
+
local dir=$1
|
|
392
|
+
local original_path=$PWD
|
|
393
|
+
|
|
394
|
+
if ! navigate_to_dir "$dir"; then
|
|
395
|
+
print_message "${RED}Failed to navigate to directory: ${NC}${dir}${RED}. [Fail]${NC}" 0
|
|
396
|
+
exit 1
|
|
397
|
+
fi
|
|
398
|
+
|
|
399
|
+
if git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
|
|
400
|
+
navigate_to_dir "$original_path"
|
|
401
|
+
return 0
|
|
402
|
+
fi
|
|
403
|
+
|
|
404
|
+
navigate_to_dir "$original_path"
|
|
405
|
+
return 1
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
has_uncommitted_changes() {
|
|
409
|
+
local original_path=$PWD
|
|
410
|
+
local worktree_path=$1
|
|
411
|
+
|
|
412
|
+
if ! navigate_to_dir "$worktree_path"; then
|
|
413
|
+
print_message "${RED}Failed to navigate to worktree directory: ${NC}${worktree_path}${RED}. [Fail]${NC}" 0
|
|
414
|
+
exit 1
|
|
415
|
+
fi
|
|
416
|
+
|
|
417
|
+
if ! is_git_repo "$worktree_path"; then
|
|
418
|
+
return 1
|
|
419
|
+
fi
|
|
420
|
+
|
|
421
|
+
if ! check_uncommitted_changes; then
|
|
422
|
+
if ! navigate_to_dir "$original_path"; then
|
|
423
|
+
print_message "${RED}Failed to navigate to original directory: ${NC}${original_path}${RED}. [Fail]${NC}" 0
|
|
424
|
+
exit 1
|
|
425
|
+
fi
|
|
426
|
+
return 0
|
|
427
|
+
fi
|
|
428
|
+
|
|
429
|
+
if ! navigate_to_dir "$original_path"; then
|
|
430
|
+
print_message "${RED}Failed to navigate to original directory: ${NC}${original_path}${RED}. [Fail]${NC}" 0
|
|
431
|
+
exit 1
|
|
432
|
+
fi
|
|
433
|
+
return 1
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
branch_exists_locally() {
|
|
437
|
+
local branch=$1
|
|
438
|
+
if git show-ref --verify --quiet "refs/heads/${branch}"; then
|
|
439
|
+
return 0
|
|
440
|
+
fi
|
|
441
|
+
return 1
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
branch_exists_on_remote() {
|
|
445
|
+
local branch=$1
|
|
446
|
+
if git ls-remote --heads origin "${branch}" | grep -q "${branch}"; then
|
|
447
|
+
return 0
|
|
448
|
+
fi
|
|
449
|
+
return 1
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
copy_to_clipboard() {
|
|
453
|
+
local content="$1"
|
|
454
|
+
local message="$2"
|
|
455
|
+
|
|
456
|
+
if [ -n "$content" ]; then
|
|
457
|
+
# Strip all ANSI escape sequences: colors, character sets, etc.
|
|
458
|
+
printf '%s' "$content" | sed -E $'s/\033(\\[[0-9;]*[a-zA-Z]|\\([0-9A-B])//g' | pbcopy
|
|
459
|
+
fi
|
|
460
|
+
|
|
461
|
+
if [ -n "$message" ]; then
|
|
462
|
+
print_message "${GREEN}${message}${NC}"
|
|
463
|
+
fi
|
|
464
|
+
}
|