-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathgho.sh
More file actions
368 lines (328 loc) · 12.8 KB
/
Copy pathgho.sh
File metadata and controls
368 lines (328 loc) · 12.8 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
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
#!/bin/bash
# Git Genius v5.0 – Developer-Focused GitHub CLI Toolkit
# Author: moHaN-ShaArmA
# Features: Offline mode, GPG commit signing, PAT validation, interactive commit picker, GUI-ready
VERSION="v5.0"
GIT_DIR=".git"
GENIUS_DIR="$GIT_DIR/.genius"
CONFIG_FILE="$GENIUS_DIR/config"
TOKEN_FILE="$GENIUS_DIR/token"
BRANCH_FILE="$GENIUS_DIR/branch"
REMOTE_FILE="$GENIUS_DIR/remote"
BACKUP_FILE="$GENIUS_DIR/config.backup"
# Colors
GREEN="\033[1;32m"
YELLOW="\033[1;33m"
RED="\033[1;31m"
CYAN="\033[1;36m"
BLUE="\033[1;34m"
BOLD="\033[1m"
MAGENTA="\033[1;35m"
NC="\033[0m"
trap 'echo -e "\n${YELLOW}👋 Exiting Git Genius. Goodbye!${NC}"; exit 0' SIGINT
# ------------ Prerequisite Checks ------------
ensure_git_installed() {
command -v git &>/dev/null || {
echo -e "${RED}❌ Git not installed!${NC}"
echo -e "${YELLOW}📦 Installing Git...${NC}"
if command -v pkg &>/dev/null; then
pkg install git -y
elif command -v apt &>/dev/null; then
sudo apt update && sudo apt install git -y
else
echo -e "${RED}⚠ Unsupported package manager.${NC}"
exit 1
fi
}
command -v gh &>/dev/null || echo -e "${YELLOW}⚠ GitHub CLI (gh) not found. Some features disabled.${NC}"
}
check_internet() {
if ! curl -s https://github.com &>/dev/null; then
echo -e "${YELLOW}⚠ No internet detected. Offline mode enabled.${NC}"
ONLINE_MODE=false
else
ONLINE_MODE=true
fi
}
validate_token() {
if [ -f "$TOKEN_FILE" ]; then
TOKEN=$(<"$TOKEN_FILE")
if $ONLINE_MODE; then
VALID=$(curl -s -H "Authorization: token $TOKEN" https://api.github.com/user | grep login)
if [[ -z "$VALID" ]]; then
echo -e "${RED}❌ Invalid or expired GitHub token.${NC}"
rm -f "$TOKEN_FILE"
setup_config
fi
fi
fi
}
# ------------ Setup / Config ------------
setup_genius_dir() {
mkdir -p "$GENIUS_DIR"
}
backup_config() {
cp "$CONFIG_FILE" "$BACKUP_FILE" 2>/dev/null
}
setup_config() {
echo -e "${YELLOW}⚙ First-time Setup:${NC}"
read -p "🧑 Username: " GITHUB_USER
read -p "✉️ Email: " GITHUB_EMAIL
git config --global user.name "$GITHUB_USER"
git config --global user.email "$GITHUB_EMAIL"
echo "username=$GITHUB_USER" > "$CONFIG_FILE"
echo "email=$GITHUB_EMAIL" >> "$CONFIG_FILE"
echo -e "${CYAN}🔑 Enter GitHub Personal Access Token (PAT):${NC}"
echo -e "${MAGENTA}📌 Token must have 'repo' and 'workflow' scopes.${NC}"
read -s TOKEN
echo "$TOKEN" > "$TOKEN_FILE"
chmod 600 "$TOKEN_FILE"
echo -e "${GREEN}✔ Token saved.${NC}"
}
validate_git_repo_directory() {
if [ ! -d "$GIT_DIR" ]; then
echo -e "${RED}❌ Not a Git repository!${NC}"
echo -e "${YELLOW}💡 Use 'git init' or clone a repo.${NC}"
exit 1
fi
[ ! -d "$GENIUS_DIR" ] && setup_genius_dir
if [ -f "$REMOTE_FILE" ]; then
CONFIGURED_REMOTE=$(<"$REMOTE_FILE")
ACTUAL_REMOTE=$(git remote get-url origin 2>/dev/null)
REPO_NAME=$(basename -s .git "$CONFIGURED_REMOTE")
CURRENT_DIR_NAME=$(basename "$PWD")
if [[ "$CONFIGURED_REMOTE" != "$ACTUAL_REMOTE" ]]; then
echo -e "${RED}⚠ Remote mismatch!${NC}"
echo -e "${CYAN}Expected: $CONFIGURED_REMOTE"
echo -e "Found: $ACTUAL_REMOTE${NC}"
echo -e "${YELLOW}💡 Fixing it in settings...${NC}"
settings_menu
elif [[ "$CURRENT_DIR_NAME" != "$REPO_NAME" ]]; then
echo -e "${RED}⚠ Folder name mismatch!${NC}"
echo -e "${CYAN}Expected: $REPO_NAME"
echo -e "Found: $CURRENT_DIR_NAME${NC}"
echo -e "${YELLOW}💡 Please rename folder or adjust remote.${NC}"
settings_menu
fi
fi
}
# ------------ Main Execution Entry Point ------------
show_header() {
echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo -e " ${CYAN}✨ GitHub CLI – Git Genius $VERSION ✨${BLUE}"
echo -e " ${MAGENTA}Crafted with ♥ by moHaN-ShaArmA${BLUE}"
echo -e "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
}
# ------------ Commit Helpers ------------
interactive_commit_picker() {
echo -e "${CYAN}📝 Choose a commit type:"
PS3="> "
select type in "✨ feat" "🐛 fix" "📚 docs" "🎨 style" "🧪 test" "⚙️ chore" "🔀 merge" "⏪ revert" "Custom"; do
case $REPLY in
1) TYPE="✨ feat"; break ;;
2) TYPE="🐛 fix"; break ;;
3) TYPE="📚 docs"; break ;;
4) TYPE="🎨 style"; break ;;
5) TYPE="🧪 test"; break ;;
6) TYPE="⚙️ chore"; break ;;
7) TYPE="🔀 merge"; break ;;
8) TYPE="⏪ revert"; break ;;
9) read -p "🔤 Custom type: " TYPE; break ;;
*) echo -e "${RED}❌ Invalid choice.${NC}" ;;
esac
done
read -p "🗒 Commit message: " MSG
echo "$TYPE: $MSG"
}
make_commit() {
git add .
COMMIT_MSG=$(interactive_commit_picker)
echo -e "${YELLOW}🔐 Sign commit with GPG? (y/n)${NC}"
read -r SIGN
if [[ "$SIGN" == "y" ]]; then
git commit -S -m "$COMMIT_MSG"
else
git commit -m "$COMMIT_MSG"
fi
}
# ------------ Core Git Actions ------------
push_code() {
echo -e "${CYAN}🚀 Pushing changes..."
if $ONLINE_MODE; then
git push origin "$(get_branch)"
else
echo -e "${RED}❌ Offline! Push skipped.${NC}"
fi
}
pull_code() {
echo -e "${CYAN}📥 Pulling latest changes..."
if $ONLINE_MODE; then
git pull origin "$(get_branch)"
else
echo -e "${RED}❌ Offline! Pull skipped.${NC}"
fi
}
get_branch() {
if [ -f "$BRANCH_FILE" ]; then
cat "$BRANCH_FILE"
else
git rev-parse --abbrev-ref HEAD
fi
}
git_status() {
echo -e "${CYAN}📊 Git Status:"
git status
}
# ------------ Settings / Config Options ------------
settings_menu() {
echo -e "${CYAN}⚙ Settings:"
PS3="Select an option: "
select opt in "Set Remote" "Change Branch" "Edit User Info" "View Config" "Back"; do
case $REPLY in
1)
read -p "🌐 Enter remote URL: " REMOTE
git remote remove origin 2>/dev/null
git remote add origin "$REMOTE"
echo "$REMOTE" > "$REMOTE_FILE"
;;
2)
read -p "🌿 Enter branch name: " BRANCH
git checkout -B "$BRANCH"
echo "$BRANCH" > "$BRANCH_FILE"
;;
3)
read -p "🧑 New username: " NAME
read -p "✉️ New email: " EMAIL
git config --global user.name "$NAME"
git config --global user.email "$EMAIL"
sed -i "s/^username=.*/username=$NAME/" "$CONFIG_FILE"
sed -i "s/^email=.*/email=$EMAIL/" "$CONFIG_FILE"
;;
4)
echo -e "${CYAN}🔍 Current config:"
cat "$CONFIG_FILE"
echo -e "Remote: $(<"$REMOTE_FILE")"
echo -e "Branch: $(<"$BRANCH_FILE")"
;;
5) break ;;
*) echo -e "${RED}❌ Invalid option.${NC}" ;;
esac
done
}
# ------------ GUI Stub for Future Enhancement ------------
launch_gui() {
if command -v yad &>/dev/null; then
yad --form --title="Git Genius GUI" \
--text="This is a placeholder GUI." \
--field="Commit message" \
--field="Push to origin:CHK" "" TRUE
else
echo -e "${YELLOW}💡 GUI support (YAD) not installed.${NC}"
fi
}
# ------------ Multi-repo Dashboard ------------
multi_repo_dashboard() {
echo -e "${CYAN}📂 Multi-Repo Dashboard"
read -p "📁 Enter parent directory of repos: " DIR
if [[ ! -d "$DIR" ]]; then
echo -e "${RED}❌ Invalid directory.${NC}"
return
fi
ORIGINAL_DIR=$(pwd)
REPO_COUNT=0
for repo in "$DIR"/*; do
if [[ -d "$repo/.git" ]]; then
REPO_COUNT=$((REPO_COUNT + 1))
echo -e "\n${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo -e "📌 Repo: ${GREEN}${repo}${NC}"
cd "$repo" || continue
BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null)
echo -e "🔀 Branch: ${YELLOW}${BRANCH}${NC}"
# Show last commit info
LAST_COMMIT=$(git log -1 --pretty=format:"%C(cyan)%s%Creset by %C(green)%an%Creset on %C(yellow)%ad%Creset" --date=short)
echo -e "🕒 Last Commit: $LAST_COMMIT"
# Git status
STATUS=$(git status --porcelain)
if [[ -z "$STATUS" ]]; then
echo -e "${GREEN}✔ Clean working tree${NC}"
else
echo -e "${RED}⚠ Uncommitted changes present${NC}"
fi
# Sync check
LOCAL=$(git rev-parse @ 2>/dev/null)
REMOTE=$(git rev-parse @{u} 2>/dev/null)
BASE=$(git merge-base @ @{u} 2>/dev/null)
if [[ "$LOCAL" == "$REMOTE" ]]; then
echo -e "${GREEN}✔ Local and remote in sync${NC}"
elif [[ "$LOCAL" == "$BASE" ]]; then
echo -e "${YELLOW}⬇ Behind remote (need pull)${NC}"
elif [[ "$REMOTE" == "$BASE" ]]; then
echo -e "${YELLOW}⬆ Ahead of remote (need push)${NC}"
else
echo -e "${RED}⚠ Diverged from remote${NC}"
fi
cd "$ORIGINAL_DIR"
fi
done
echo -e "\n${CYAN}✅ Dashboard complete. ${REPO_COUNT} repositories scanned.${NC}"
}
# ------------ Git Log Viewer ------------
view_git_log() {
echo -e "${CYAN}📖 Commit Log:"
git log --pretty=format:"%C(yellow)%h%Creset - %C(cyan)%an%Creset | %Cgreen%ad%Creset%n%s%n" --date=short -n 10
}
# ------------ Remote Sync Verification ------------
check_sync_status() {
echo -e "${CYAN}🔃 Checking remote sync..."
LOCAL=$(git rev-parse @)
REMOTE=$(git rev-parse @{u})
BASE=$(git merge-base @ @{u})
if [ "$LOCAL" = "$REMOTE" ]; then
echo -e "${GREEN}✔ Local and remote are in sync.${NC}"
elif [ "$LOCAL" = "$BASE" ]; then
echo -e "${YELLOW}⬇ Need to pull.${NC}"
elif [ "$REMOTE" = "$BASE" ]; then
echo -e "${YELLOW}⬆ Need to push.${NC}"
else
echo -e "${RED}⚠️ Local and remote have diverged.${NC}"
fi
}
# ------------ Main Menu ------------
main_menu() {
echo -e "${BOLD}${CYAN}
███████╗██╗ ██████╗ ██████╗ ███████╗███╗ ██╗██╗██╗ ██╗███████╗
██╔════╝██║██╔════╝ ██╔══██╗██╔════╝████╗ ██║██║██║ ██║██╔════╝
█████╗ ██║██║ ███╗ ██████╔╝█████╗ ██╔██╗ ██║██║██║ ██║███████╗
██╔══╝ ██║██║ ██║ ██╔═══╝ ██╔══╝ ██║╚██╗██║██║╚██╗ ██╔╝╚════██║
██║ ██║╚██████╔╝ ██║ ███████╗██║ ╚████║██║ ╚████╔╝ ███████║
╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚══════╝╚═╝ ╚═══╝╚═╝ ╚═══╝ ╚══════╝
${NC}"
while true; do
echo -e "${BLUE}🧠 What do you want to do?"
PS3="> "
select opt in "📝 Commit" "🚀 Push" "📥 Pull" "📊 Status" "📖 View Log" "🔃 Check Sync" "🛠 Settings" "📂 Multi-Repo Dashboard" "🖼 GUI (YAD)" "Exit"; do
case $REPLY in
1) make_commit ;;
2) push_code ;;
3) pull_code ;;
4) git_status ;;
5) view_git_log ;;
6) check_sync_status ;;
7) settings_menu ;;
8) multi_repo_dashboard ;;
9) launch_gui ;;
10) echo -e "${MAGENTA}👋 Exiting Git Genius!"; exit ;;
*) echo -e "${RED}❌ Invalid choice.${NC}" ;;
esac
break
done
done
}
# ------------ Start Script ------------
setup_genius_dir
ensure_git_installed
check_internet
validate_git_repo_directory
validate_token
show_header
main_menu