-
Notifications
You must be signed in to change notification settings - Fork 902
Expand file tree
/
Copy pathcheck_update.sh
More file actions
executable file
·328 lines (285 loc) · 10.7 KB
/
check_update.sh
File metadata and controls
executable file
·328 lines (285 loc) · 10.7 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
#!/usr/bin/env bash
# Git Update Check Utility - Linux/macOS
# This script checks for updates from GitHub and optionally updates the repository
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# Configuration
TIMEOUT_SECONDS=10
GIT_PATH=""
REPO_PATH="$SCRIPT_DIR"
echo "========================================"
echo "ACE-Step Update Check"
echo "========================================"
echo
# Find git
if command -v git &>/dev/null; then
GIT_PATH="$(command -v git)"
echo "[Git] Using system Git: $GIT_PATH"
else
echo "[Error] Git not found."
echo
if [[ "$(uname)" == "Darwin" ]]; then
echo "Please install Git:"
echo " xcode-select --install"
echo " or: brew install git"
else
echo "Please install Git:"
echo " Ubuntu/Debian: sudo apt install git"
echo " CentOS/RHEL: sudo yum install git"
echo " Arch: sudo pacman -S git"
fi
echo
exit 1
fi
echo
# Check if this is a git repository
cd "$REPO_PATH"
if ! "$GIT_PATH" rev-parse --git-dir &>/dev/null; then
echo "[Error] Not a git repository."
echo "This folder does not appear to be a git repository."
echo
exit 1
fi
echo "[1/4] Checking current version..."
CURRENT_BRANCH="$("$GIT_PATH" rev-parse --abbrev-ref HEAD 2>/dev/null || echo "main")"
CURRENT_COMMIT="$("$GIT_PATH" rev-parse --short HEAD 2>/dev/null || echo "unknown")"
echo " Branch: $CURRENT_BRANCH"
echo " Commit: $CURRENT_COMMIT"
echo
echo "[2/4] Checking for updates (timeout: ${TIMEOUT_SECONDS}s)..."
echo " Connecting to GitHub..."
# Fetch remote with timeout
FETCH_SUCCESS=0
if timeout "$TIMEOUT_SECONDS" "$GIT_PATH" fetch origin --quiet 2>/dev/null; then
FETCH_SUCCESS=1
elif command -v gtimeout &>/dev/null; then
# macOS with coreutils installed via brew
if gtimeout "$TIMEOUT_SECONDS" "$GIT_PATH" fetch origin --quiet 2>/dev/null; then
FETCH_SUCCESS=1
fi
else
# Fallback: try without timeout (macOS without coreutils)
if "$GIT_PATH" fetch origin --quiet 2>/dev/null; then
FETCH_SUCCESS=1
fi
fi
if [[ $FETCH_SUCCESS -eq 0 ]]; then
echo " [Failed] Could not fetch from GitHub."
echo " Please check your internet connection."
echo
exit 2
fi
echo " [Success] Fetched latest information from GitHub."
echo
echo "[3/4] Comparing versions..."
REMOTE_COMMIT="$("$GIT_PATH" rev-parse --short "origin/$CURRENT_BRANCH" 2>/dev/null || echo "")"
if [[ -z "$REMOTE_COMMIT" ]]; then
echo " [Warning] Remote branch 'origin/$CURRENT_BRANCH' not found."
echo
echo " Checking main branch instead..."
FALLBACK_BRANCH="main"
REMOTE_COMMIT="$("$GIT_PATH" rev-parse --short "origin/$FALLBACK_BRANCH" 2>/dev/null || echo "")"
if [[ -z "$REMOTE_COMMIT" ]]; then
echo " [Error] Could not find remote main branch either."
exit 1
fi
echo " Found main branch: $REMOTE_COMMIT"
echo
read -rp " Switch to main branch? (Y/N): " SWITCH_BRANCH
if [[ "${SWITCH_BRANCH^^}" == "Y" ]]; then
echo
echo " Switching to main branch..."
if "$GIT_PATH" checkout main; then
echo " [Success] Switched to main branch."
echo " Please run this script again to check for updates."
exit 0
else
echo " [Error] Failed to switch branch."
exit 1
fi
else
echo
echo " Staying on branch '$CURRENT_BRANCH'. No update performed."
exit 0
fi
fi
echo " Local: $CURRENT_COMMIT"
echo " Remote: $REMOTE_COMMIT"
echo
# Compare commits
if [[ "$CURRENT_COMMIT" == "$REMOTE_COMMIT" ]]; then
echo "[4/4] Result: Already up to date!"
echo " You have the latest version."
echo
exit 0
fi
echo "[4/4] Result: Update available!"
# Check if local is behind remote
if "$GIT_PATH" merge-base --is-ancestor HEAD "origin/$CURRENT_BRANCH" 2>/dev/null; then
echo " A new version is available on GitHub."
echo
# Show new commits
echo " New commits:"
"$GIT_PATH" --no-pager log --oneline --graph --decorate "HEAD..origin/$CURRENT_BRANCH" 2>/dev/null
echo
read -rp "Do you want to update now? (Y/N): " UPDATE_CHOICE
if [[ "${UPDATE_CHOICE^^}" != "Y" ]]; then
echo
echo "Update skipped."
exit 0
fi
echo
echo "Updating..."
# Refresh index
"$GIT_PATH" update-index --refresh &>/dev/null || true
# Check for uncommitted changes
if ! "$GIT_PATH" diff-index --quiet HEAD -- 2>/dev/null; then
echo
echo "[Info] Checking for potential conflicts..."
# Get locally modified files
LOCAL_CHANGES="$("$GIT_PATH" diff --name-only HEAD 2>/dev/null || echo "")"
REMOTE_CHANGES="$("$GIT_PATH" diff --name-only "HEAD..origin/$CURRENT_BRANCH" 2>/dev/null || echo "")"
# Check for conflicting files
HAS_CONFLICTS=0
BACKUP_DIR="$SCRIPT_DIR/.update_backup_$(date +%Y%m%d_%H%M%S)"
while IFS= read -r local_file; do
[[ -z "$local_file" ]] && continue
if echo "$REMOTE_CHANGES" | grep -qxF "$local_file"; then
HAS_CONFLICTS=1
# Create backup directory if not exists
if [[ ! -d "$BACKUP_DIR" ]]; then
mkdir -p "$BACKUP_DIR"
echo
echo "[Backup] Creating backup directory: $BACKUP_DIR"
fi
# Backup the file
echo "[Backup] Backing up: $local_file"
FILE_DIR="$(dirname "$local_file")"
if [[ "$FILE_DIR" != "." ]]; then
mkdir -p "$BACKUP_DIR/$FILE_DIR"
fi
cp "$local_file" "$BACKUP_DIR/$local_file" 2>/dev/null || true
fi
done <<< "$LOCAL_CHANGES"
if [[ $HAS_CONFLICTS -eq 1 ]]; then
echo
echo "========================================"
echo "[Warning] Potential conflicts detected!"
echo "========================================"
echo
echo "Your modified files may conflict with remote updates."
echo "Your changes have been backed up to:"
echo " $BACKUP_DIR"
echo
read -rp "Continue with update? (Y/N): " CONFLICT_CHOICE
if [[ "${CONFLICT_CHOICE^^}" != "Y" ]]; then
echo
echo "Update cancelled. Your backup remains at: $BACKUP_DIR"
exit 0
fi
echo
echo "[Restore] Proceeding with update..."
else
echo
echo "[Info] No conflicts detected. Safe to stash and update."
echo
read -rp "Stash your changes and continue? (Y/N): " STASH_CHOICE
if [[ "${STASH_CHOICE^^}" == "Y" ]]; then
echo "Stashing changes..."
"$GIT_PATH" stash push -m "Auto-stash before update - $(date)"
else
echo
echo "Update cancelled."
exit 0
fi
fi
fi
# Check for untracked files that could be overwritten
UNTRACKED_FILES="$("$GIT_PATH" ls-files --others --exclude-standard 2>/dev/null || echo "")"
STASHED_UNTRACKED=0
if [[ -n "$UNTRACKED_FILES" ]]; then
# Check if any untracked files conflict with incoming changes
REMOTE_ALL_FILES="$("$GIT_PATH" diff --name-only --diff-filter=A "HEAD..origin/$CURRENT_BRANCH" 2>/dev/null || echo "")"
CONFLICTING_UNTRACKED=""
while IFS= read -r ufile; do
[[ -z "$ufile" ]] && continue
if echo "$REMOTE_ALL_FILES" | grep -qxF "$ufile"; then
CONFLICTING_UNTRACKED="${CONFLICTING_UNTRACKED}${ufile}"$'\n'
fi
done <<< "$UNTRACKED_FILES"
if [[ -n "$CONFLICTING_UNTRACKED" ]]; then
echo
echo "========================================"
echo "[Warning] Untracked files conflict with update!"
echo "========================================"
echo
echo "The following untracked files would be overwritten:"
echo "$CONFLICTING_UNTRACKED" | sed '/^$/d; s/^/ /'
echo
read -rp "Stash untracked files before updating? (Y/N): " STASH_UNTRACKED_CHOICE
if [[ "${STASH_UNTRACKED_CHOICE^^}" != "Y" ]]; then
echo
echo "Update cancelled. Please move or remove the conflicting files manually."
exit 1
fi
echo "Stashing all changes including untracked files..."
if "$GIT_PATH" stash push --include-untracked -m "pre-update-$(date +%s)"; then
STASHED_UNTRACKED=1
echo "[Stash] Changes stashed successfully."
else
echo "[Error] Failed to stash changes. Update aborted."
exit 1
fi
echo
fi
fi
# Pull changes
echo "Pulling latest changes..."
if "$GIT_PATH" reset --hard "origin/$CURRENT_BRANCH" &>/dev/null; then
echo
echo "========================================"
echo "Update completed successfully!"
echo "========================================"
echo
if [[ -d "${BACKUP_DIR:-}" ]]; then
echo "[Important] Your modified files were backed up to:"
echo " $BACKUP_DIR"
echo
echo "To restore your changes:"
echo " 1. Run ./merge_config.sh to compare and merge files"
echo " 2. Or manually compare backup with new version"
echo
fi
if [[ $STASHED_UNTRACKED -eq 1 ]]; then
echo "[Stash] Untracked files were stashed before the update."
echo " To restore them: git stash pop"
echo " To discard them: git stash drop"
echo
echo " Note: 'git stash pop' may produce merge conflicts if"
echo " the update modified the same files. Resolve manually."
echo
fi
echo "Please restart the application to use the new version."
exit 0
else
echo
echo "[Error] Update failed."
if [[ $STASHED_UNTRACKED -eq 1 ]]; then
echo "[Stash] Restoring stashed changes..."
if "$GIT_PATH" stash pop &>/dev/null; then
echo "[Stash] Changes restored successfully."
else
echo "[Stash] Could not auto-restore. Run 'git stash pop' manually."
fi
fi
if [[ -d "${BACKUP_DIR:-}" ]]; then
echo "Your backup is still available at: $BACKUP_DIR"
fi
exit 1
fi
else
echo " [Warning] Local version has diverged from remote."
echo " This might be because you have local commits."
echo " Please update manually or consult the documentation."
exit 0
fi