Added - Finalized the safe upstream update helper script as .update-gitea.sh.
- 5 - I improved conflict reporting so package.json conflicts show the upstream scripts block, the conflicting commit side, and the current branch working-tree side, and the final dry-run summary now includes the total conflict-step count, the local commits that conflicted, and the unique conflicted files.
This commit is contained in:
+263
-59
@@ -8,10 +8,11 @@ set -euo pipefail
|
||||
# 1. checks that no git operation is already in progress;
|
||||
# 2. ensures the upstream remote exists and points to the official repository;
|
||||
# 3. creates a local backup branch at the current HEAD;
|
||||
# 4. stashes tracked and untracked local changes;
|
||||
# 5. fetches the latest upstream changes and rebases the current branch on top
|
||||
# 4. creates a full exact snapshot of the current repository state;
|
||||
# 5. stashes tracked and untracked local changes;
|
||||
# 6. fetches the latest upstream changes and rebases the current branch on top
|
||||
# of upstream/main;
|
||||
# 6. reapplies the local stash only after a successful rebase.
|
||||
# 7. reapplies the local stash only after a successful rebase.
|
||||
# It also offers a dry-run mode that performs the same verification flow in a
|
||||
# temporary clone, so the current repository is left untouched.
|
||||
# If a conflict happens, the backup branch and the stash are both kept so the
|
||||
@@ -24,6 +25,7 @@ REPO_ROOT=""
|
||||
GIT_DIR=""
|
||||
STATE_FILE=""
|
||||
DRY_RUN_ROOT=""
|
||||
SNAPSHOT_ROOT=""
|
||||
CURRENT_BRANCH=""
|
||||
BACKUP_BRANCH=""
|
||||
STASH_REF=""
|
||||
@@ -35,6 +37,7 @@ STATE_REMOTE_NAME=""
|
||||
STATE_REMOTE_URL=""
|
||||
STATE_TARGET_BRANCH=""
|
||||
STATE_START_HEAD=""
|
||||
STATE_SNAPSHOT_PATH=""
|
||||
STATE_STATUS=""
|
||||
STATE_UPDATED_AT=""
|
||||
|
||||
@@ -64,6 +67,8 @@ Available commands:
|
||||
Re-apply the saved pre-sync local stash from the last recorded sync state.
|
||||
clean-dry-run
|
||||
Remove the reusable dry-run workspace and legacy temporary dry-run clones.
|
||||
restore-snapshot [snapshot-dir]
|
||||
Restore the exact saved repository snapshot from the last recorded real action, or from a specific snapshot directory.
|
||||
status Show the current repository, branch, remote, and local-change status.
|
||||
help Show this help text.
|
||||
|
||||
@@ -73,18 +78,26 @@ menu is shown.
|
||||
Recommended order:
|
||||
1. Run: ./.update-gitea.sh status
|
||||
2. Run: ./.update-gitea.sh dry-run
|
||||
3. If dry-run is clean, run: ./.update-gitea.sh sync
|
||||
4. If rebase stops with conflicts:
|
||||
3. If dry-run reports conflicts:
|
||||
- review the reported conflict steps, commits, and files
|
||||
- adjust or resolve the conflicting local changes in your real branch
|
||||
- run: ./.update-gitea.sh dry-run
|
||||
again until it completes cleanly
|
||||
4. If dry-run is clean, run: ./.update-gitea.sh sync
|
||||
5. If rebase stops with conflicts:
|
||||
- either resolve them and continue with: git rebase --continue
|
||||
- or return safely with: ./.update-gitea.sh rollback
|
||||
5. If restoring local changes after the rebase causes conflicts:
|
||||
6. If restoring local changes after the rebase causes conflicts:
|
||||
- either resolve them manually
|
||||
- or return safely with: ./.update-gitea.sh rollback
|
||||
6. Use: ./.update-gitea.sh list-backups
|
||||
7. Use: ./.update-gitea.sh list-backups
|
||||
to see the restore points created by the script.
|
||||
7. Use: ./.update-gitea.sh restore-stash
|
||||
8. Use: ./.update-gitea.sh restore-stash
|
||||
only when you intentionally aborted a failed sync and want the saved local
|
||||
changes reapplied again.
|
||||
9. Use: ./.update-gitea.sh restore-snapshot
|
||||
when you want to restore the exact saved repository state, including
|
||||
untracked and ignored files that existed at snapshot time.
|
||||
EOF
|
||||
}
|
||||
|
||||
@@ -99,6 +112,7 @@ ensure_git_repo() {
|
||||
esac
|
||||
STATE_FILE="$GIT_DIR/.update-gitea-state"
|
||||
DRY_RUN_ROOT="$GIT_DIR/.update-gitea-dry-run"
|
||||
SNAPSHOT_ROOT="$GIT_DIR/.update-gitea-snapshots"
|
||||
}
|
||||
|
||||
write_state() {
|
||||
@@ -110,6 +124,7 @@ write_state() {
|
||||
printf 'STATE_REMOTE_URL=%q\n' "$STATE_REMOTE_URL"
|
||||
printf 'STATE_TARGET_BRANCH=%q\n' "$STATE_TARGET_BRANCH"
|
||||
printf 'STATE_START_HEAD=%q\n' "$STATE_START_HEAD"
|
||||
printf 'STATE_SNAPSHOT_PATH=%q\n' "$STATE_SNAPSHOT_PATH"
|
||||
printf 'STATE_STATUS=%q\n' "$STATE_STATUS"
|
||||
printf 'STATE_UPDATED_AT=%q\n' "$(date +%Y-%m-%dT%H:%M:%S)"
|
||||
} >"$STATE_FILE"
|
||||
@@ -145,6 +160,58 @@ sanitize_ref_name() {
|
||||
printf '%s\n' "${1//\//-}"
|
||||
}
|
||||
|
||||
ensure_rsync_available() {
|
||||
command -v rsync >/dev/null 2>&1 || die "rsync is required for exact repository snapshots."
|
||||
}
|
||||
|
||||
snapshot_repo_dir() {
|
||||
printf '%s\n' "$1/repo"
|
||||
}
|
||||
|
||||
is_valid_snapshot_dir() {
|
||||
[ -d "$1" ] && [ -d "$(snapshot_repo_dir "$1")" ]
|
||||
}
|
||||
|
||||
create_worktree_snapshot_for_reason() {
|
||||
local reason="$1" safe_branch_name timestamp snapshot_dir snapshot_dir_repo
|
||||
|
||||
ensure_rsync_available
|
||||
safe_branch_name="$(sanitize_ref_name "$CURRENT_BRANCH")"
|
||||
timestamp="$(date +%Y%m%d-%H%M%S)"
|
||||
snapshot_dir="$SNAPSHOT_ROOT/$safe_branch_name/${timestamp}-${reason}"
|
||||
snapshot_dir_repo="$(snapshot_repo_dir "$snapshot_dir")"
|
||||
|
||||
mkdir -p "$snapshot_dir_repo"
|
||||
rsync --archive --delete --exclude='.git' "$REPO_ROOT"/ "$snapshot_dir_repo"/
|
||||
|
||||
{
|
||||
printf 'branch=%s\n' "$CURRENT_BRANCH"
|
||||
printf 'head=%s\n' "$(git rev-parse HEAD)"
|
||||
printf 'created_at=%s\n' "$(date +%Y-%m-%dT%H:%M:%S)"
|
||||
printf 'reason=%s\n' "$reason"
|
||||
} >"$snapshot_dir/metadata.txt"
|
||||
|
||||
printf '%s\n' "$snapshot_dir"
|
||||
}
|
||||
|
||||
restore_worktree_snapshot() {
|
||||
local snapshot_dir="$1" snapshot_dir_repo
|
||||
|
||||
ensure_rsync_available
|
||||
is_valid_snapshot_dir "$snapshot_dir" || die "Snapshot directory '$snapshot_dir' is not valid."
|
||||
snapshot_dir_repo="$(snapshot_repo_dir "$snapshot_dir")"
|
||||
|
||||
rsync --archive --delete --exclude='.git' "$snapshot_dir_repo"/ "$REPO_ROOT"/
|
||||
}
|
||||
|
||||
find_latest_snapshot_for_current() {
|
||||
local safe_branch_name snapshot_branch_dir
|
||||
safe_branch_name="$(sanitize_ref_name "$CURRENT_BRANCH")"
|
||||
snapshot_branch_dir="$SNAPSHOT_ROOT/$safe_branch_name"
|
||||
[ -d "$snapshot_branch_dir" ] || return 1
|
||||
find "$snapshot_branch_dir" -mindepth 1 -maxdepth 1 -type d | sort -r | head -n 1
|
||||
}
|
||||
|
||||
ensure_no_nonrebase_git_operation_in_progress() {
|
||||
local git_path
|
||||
for git_path in MERGE_HEAD CHERRY_PICK_HEAD REVERT_HEAD BISECT_LOG; do
|
||||
@@ -173,6 +240,20 @@ ensure_current_branch() {
|
||||
[ -n "$CURRENT_BRANCH" ] || die "Detached HEAD is not supported. Check out a branch first."
|
||||
}
|
||||
|
||||
ensure_current_branch_with_state_fallback() {
|
||||
CURRENT_BRANCH="$(git symbolic-ref --quiet --short HEAD || true)"
|
||||
if [ -n "$CURRENT_BRANCH" ]; then
|
||||
return
|
||||
fi
|
||||
|
||||
if load_state && [ -n "${STATE_BRANCH:-}" ]; then
|
||||
CURRENT_BRANCH="$STATE_BRANCH"
|
||||
return
|
||||
fi
|
||||
|
||||
die "Detached HEAD is not supported here and no saved branch state was found."
|
||||
}
|
||||
|
||||
update_state_for_sync() {
|
||||
STATE_BRANCH="$CURRENT_BRANCH"
|
||||
STATE_BACKUP_BRANCH="$BACKUP_BRANCH"
|
||||
@@ -223,29 +304,32 @@ prepare_backup_before_real_action() {
|
||||
local action_label="$1" backup_reason="$2" latest_existing_backup=""
|
||||
|
||||
STATE_START_HEAD="$(git rev-parse HEAD)"
|
||||
STATE_SNAPSHOT_PATH=""
|
||||
BACKUP_BRANCH=""
|
||||
|
||||
latest_existing_backup="$(list_current_branch_backup_refs | head -n 1 || true)"
|
||||
if [ -z "$latest_existing_backup" ]; then
|
||||
BACKUP_BRANCH="$(create_backup_branch_for_reason "$backup_reason")"
|
||||
say "No existing backups were found, so a new backup was created automatically: $BACKUP_BRANCH"
|
||||
return
|
||||
else
|
||||
show_current_branch_backups
|
||||
if [ -t 0 ] && [ -t 1 ]; then
|
||||
if confirm_yes_no "Create a fresh backup before '$action_label'?"; then
|
||||
BACKUP_BRANCH="$(create_backup_branch_for_reason "$backup_reason")"
|
||||
say "New backup created: $BACKUP_BRANCH"
|
||||
else
|
||||
BACKUP_BRANCH="$latest_existing_backup"
|
||||
say "No new backup created. The exact current commit was still recorded internally as: $STATE_START_HEAD"
|
||||
say "Latest existing backup selected as reference: $BACKUP_BRANCH"
|
||||
fi
|
||||
else
|
||||
BACKUP_BRANCH="$(create_backup_branch_for_reason "$backup_reason")"
|
||||
say "Non-interactive mode detected. A fresh backup was created automatically: $BACKUP_BRANCH"
|
||||
fi
|
||||
fi
|
||||
|
||||
show_current_branch_backups
|
||||
if [ -t 0 ] && [ -t 1 ]; then
|
||||
if confirm_yes_no "Create a fresh backup before '$action_label'?"; then
|
||||
BACKUP_BRANCH="$(create_backup_branch_for_reason "$backup_reason")"
|
||||
say "New backup created: $BACKUP_BRANCH"
|
||||
else
|
||||
BACKUP_BRANCH="$latest_existing_backup"
|
||||
say "No new backup created. The exact current commit was still recorded internally as: $STATE_START_HEAD"
|
||||
say "Latest existing backup selected as reference: $BACKUP_BRANCH"
|
||||
fi
|
||||
else
|
||||
BACKUP_BRANCH="$(create_backup_branch_for_reason "$backup_reason")"
|
||||
say "Non-interactive mode detected. A fresh backup was created automatically: $BACKUP_BRANCH"
|
||||
fi
|
||||
STATE_SNAPSHOT_PATH="$(create_worktree_snapshot_for_reason "$backup_reason")"
|
||||
say "Exact worktree snapshot created: $STATE_SNAPSHOT_PATH"
|
||||
}
|
||||
|
||||
ensure_upstream_remote() {
|
||||
@@ -263,7 +347,7 @@ ensure_upstream_remote() {
|
||||
}
|
||||
|
||||
show_status() {
|
||||
local stash_count latest_backup dry_run_branch_dir
|
||||
local stash_count latest_backup latest_snapshot dry_run_branch_dir
|
||||
|
||||
ensure_git_repo
|
||||
ensure_current_branch
|
||||
@@ -283,6 +367,8 @@ show_status() {
|
||||
say "Stash entries: $stash_count"
|
||||
latest_backup="$(find_latest_backup_branch_for_current || true)"
|
||||
say "Latest backup for current branch: ${latest_backup:-none}"
|
||||
latest_snapshot="$(find_latest_snapshot_for_current || true)"
|
||||
say "Latest snapshot for current branch: ${latest_snapshot:-none}"
|
||||
dry_run_branch_dir="$DRY_RUN_ROOT/$(sanitize_ref_name "$CURRENT_BRANCH")"
|
||||
if [ -d "$dry_run_branch_dir/repo/.git" ]; then
|
||||
say "Dry-run workspace: $dry_run_branch_dir"
|
||||
@@ -294,6 +380,7 @@ show_status() {
|
||||
say "Saved backup branch: ${STATE_BACKUP_BRANCH:-none}"
|
||||
say "Saved starting commit: ${STATE_START_HEAD:-none}"
|
||||
say "Saved original stash: ${STATE_STASH_HASH:-none}"
|
||||
say "Saved exact snapshot: ${STATE_SNAPSHOT_PATH:-none}"
|
||||
else
|
||||
say "Saved sync state: none"
|
||||
fi
|
||||
@@ -568,7 +655,7 @@ drop_stash_by_hash_if_present() {
|
||||
}
|
||||
|
||||
restore_stash() {
|
||||
local restore_target
|
||||
local keep_saved_copy="${1:-0}" restore_target
|
||||
|
||||
if [ -z "$STASH_HASH" ] && [ -z "$STASH_REF" ]; then
|
||||
return
|
||||
@@ -577,13 +664,21 @@ restore_stash() {
|
||||
restore_target="${STASH_HASH:-$STASH_REF}"
|
||||
say "Restoring stashed local changes from $restore_target..."
|
||||
if git stash apply --index "$restore_target"; then
|
||||
drop_stash_by_hash_if_present "$STASH_HASH"
|
||||
STASH_REF=""
|
||||
STASH_HASH=""
|
||||
STATE_STASH_HASH=""
|
||||
if [ "$keep_saved_copy" -eq 0 ]; then
|
||||
drop_stash_by_hash_if_present "$STASH_HASH"
|
||||
STASH_HASH=""
|
||||
STATE_STASH_HASH=""
|
||||
else
|
||||
STATE_STASH_HASH="${STASH_HASH:-$restore_target}"
|
||||
fi
|
||||
STATE_STATUS="completed"
|
||||
update_state_for_sync
|
||||
say "Local changes restored successfully."
|
||||
if [ "$keep_saved_copy" -eq 0 ]; then
|
||||
say "Local changes restored successfully."
|
||||
else
|
||||
say "Local changes restored successfully. The original stash was kept for rollback safety."
|
||||
fi
|
||||
return
|
||||
fi
|
||||
|
||||
@@ -631,41 +726,55 @@ run_restore_saved_stash() {
|
||||
|
||||
STASH_HASH="$STATE_STASH_HASH"
|
||||
STASH_REF=""
|
||||
restore_stash
|
||||
restore_stash 1
|
||||
say "Saved pre-sync local changes restored."
|
||||
}
|
||||
|
||||
run_rollback() {
|
||||
local explicit_target=0 target_backup="${1:-}" rollback_safety_backup preserve_stash_ref preserve_stash_hash reset_target=""
|
||||
local explicit_target=0 target_backup="${1:-}" rollback_safety_backup rollback_safety_snapshot=""
|
||||
local reset_target="" reset_snapshot="" preserve_stash_hash=""
|
||||
local original_restore_stash_hash="" original_restore_start_head=""
|
||||
local rollback_safety_start_head=""
|
||||
local explicit_snapshot=0
|
||||
|
||||
ensure_git_repo
|
||||
ensure_no_nonrebase_git_operation_in_progress
|
||||
ensure_current_branch
|
||||
load_state || true
|
||||
ensure_current_branch_with_state_fallback
|
||||
ensure_upstream_remote
|
||||
|
||||
if [ -n "$target_backup" ]; then
|
||||
explicit_target=1
|
||||
if is_valid_snapshot_dir "$target_backup"; then
|
||||
explicit_snapshot=1
|
||||
reset_snapshot="$target_backup"
|
||||
fi
|
||||
fi
|
||||
|
||||
load_state || true
|
||||
if [ "$explicit_target" -eq 0 ] && [ -n "${STATE_BRANCH:-}" ] && [ "$CURRENT_BRANCH" != "$STATE_BRANCH" ]; then
|
||||
die "Saved sync state belongs to branch '$STATE_BRANCH'. Check out that branch or pass an explicit backup branch."
|
||||
fi
|
||||
if [ "$explicit_target" -eq 0 ] && [ -n "${STATE_START_HEAD:-}" ]; then
|
||||
if [ "$explicit_snapshot" -eq 0 ] && [ "$explicit_target" -eq 0 ] && [ -n "${STATE_SNAPSHOT_PATH:-}" ] && is_valid_snapshot_dir "$STATE_SNAPSHOT_PATH"; then
|
||||
reset_snapshot="$STATE_SNAPSHOT_PATH"
|
||||
fi
|
||||
if [ "$explicit_snapshot" -eq 0 ] && [ "$explicit_target" -eq 0 ] && [ -n "${STATE_START_HEAD:-}" ]; then
|
||||
reset_target="$STATE_START_HEAD"
|
||||
fi
|
||||
if [ -z "$reset_target" ] && [ -z "$target_backup" ]; then
|
||||
if [ -z "$reset_target" ] && [ -z "$reset_snapshot" ] && [ -z "$target_backup" ]; then
|
||||
target_backup="${STATE_BACKUP_BRANCH:-}"
|
||||
fi
|
||||
if [ -z "$reset_target" ] && [ -z "$target_backup" ]; then
|
||||
if [ -z "$reset_target" ] && [ -z "$reset_snapshot" ] && [ -z "$target_backup" ]; then
|
||||
target_backup="$(find_latest_backup_branch_for_current || true)"
|
||||
fi
|
||||
if [ -z "$reset_target" ]; then
|
||||
if [ -z "$reset_target" ] && [ -z "$reset_snapshot" ]; then
|
||||
[ -n "$target_backup" ] || die "No backup branch was found for rollback."
|
||||
git show-ref --verify --quiet "refs/heads/$target_backup" || die "Backup branch '$target_backup' does not exist."
|
||||
reset_target="$target_backup"
|
||||
fi
|
||||
|
||||
original_restore_stash_hash="${STATE_STASH_HASH:-}"
|
||||
original_restore_start_head="${STATE_START_HEAD:-}"
|
||||
|
||||
if has_rebase_in_progress; then
|
||||
say "Aborting in-progress rebase before rollback..."
|
||||
git rebase --abort || die "Failed to abort the in-progress rebase."
|
||||
@@ -677,38 +786,126 @@ run_rollback() {
|
||||
|
||||
prepare_backup_before_real_action "rollback" "before-rollback"
|
||||
rollback_safety_backup="$BACKUP_BRANCH"
|
||||
rollback_safety_snapshot="$STATE_SNAPSHOT_PATH"
|
||||
rollback_safety_start_head="$STATE_START_HEAD"
|
||||
|
||||
preserve_stash_ref=""
|
||||
preserve_stash_hash=""
|
||||
if worktree_has_local_changes; then
|
||||
stash_current_changes "pre-rollback-preserve"
|
||||
preserve_stash_ref="$STASH_REF"
|
||||
preserve_stash_hash="$STASH_HASH"
|
||||
fi
|
||||
|
||||
say "Resetting '$CURRENT_BRANCH' to '$reset_target'..."
|
||||
git reset --hard "$reset_target" >/dev/null
|
||||
if [ -n "$reset_target" ]; then
|
||||
say "Resetting '$CURRENT_BRANCH' to '$reset_target'..."
|
||||
git reset --hard "$reset_target" >/dev/null
|
||||
fi
|
||||
|
||||
if [ -n "$original_restore_stash_hash" ]; then
|
||||
STASH_HASH="$original_restore_stash_hash"
|
||||
STASH_REF=""
|
||||
BACKUP_BRANCH="$rollback_safety_backup"
|
||||
say "Restoring original pre-sync local changes..."
|
||||
restore_stash 1
|
||||
fi
|
||||
|
||||
if [ -n "$reset_snapshot" ]; then
|
||||
say "Restoring exact worktree snapshot from: $reset_snapshot"
|
||||
restore_worktree_snapshot "$reset_snapshot"
|
||||
fi
|
||||
|
||||
STATE_BRANCH="$CURRENT_BRANCH"
|
||||
STATE_BACKUP_BRANCH="$rollback_safety_backup"
|
||||
STATE_STASH_HASH="$preserve_stash_hash"
|
||||
STATE_REMOTE_NAME="$REMOTE_NAME"
|
||||
STATE_REMOTE_URL="$REMOTE_URL"
|
||||
STATE_TARGET_BRANCH="$BRANCH"
|
||||
STATE_START_HEAD="$rollback_safety_start_head"
|
||||
STATE_SNAPSHOT_PATH="$rollback_safety_snapshot"
|
||||
STATE_STATUS="rollback_completed"
|
||||
write_state
|
||||
|
||||
say "Rollback completed."
|
||||
if [ -n "$reset_snapshot" ]; then
|
||||
say "Current branch and worktree restored from saved state."
|
||||
say "Restored starting commit: ${original_restore_start_head:-$reset_target}"
|
||||
say "Restored snapshot: $reset_snapshot"
|
||||
else
|
||||
say "Current branch restored from: $reset_target"
|
||||
fi
|
||||
say "Safety backup of the pre-rollback state kept at: $rollback_safety_backup"
|
||||
say "Safety snapshot of the pre-rollback state kept at: $rollback_safety_snapshot"
|
||||
if [ -n "$preserve_stash_hash" ]; then
|
||||
say "Safety stash of the pre-rollback local changes kept at: $preserve_stash_hash"
|
||||
fi
|
||||
}
|
||||
|
||||
run_restore_snapshot() {
|
||||
local target_snapshot="${1:-}" restore_safety_backup restore_safety_snapshot=""
|
||||
local preserve_stash_hash="" restore_start_head="" restore_safety_start_head=""
|
||||
|
||||
ensure_git_repo
|
||||
ensure_no_nonrebase_git_operation_in_progress
|
||||
load_state || die "No saved sync state was found."
|
||||
ensure_current_branch_with_state_fallback
|
||||
ensure_upstream_remote
|
||||
|
||||
if [ -z "$target_snapshot" ]; then
|
||||
target_snapshot="${STATE_SNAPSHOT_PATH:-}"
|
||||
fi
|
||||
is_valid_snapshot_dir "$target_snapshot" || die "No valid saved snapshot was found to restore."
|
||||
restore_start_head="${STATE_START_HEAD:-}"
|
||||
[ -n "$restore_start_head" ] || die "No saved starting commit was found for the snapshot restore."
|
||||
|
||||
if has_rebase_in_progress; then
|
||||
say "Aborting in-progress rebase before snapshot restore..."
|
||||
git rebase --abort || die "Failed to abort the in-progress rebase."
|
||||
fi
|
||||
|
||||
if [ -n "$(git diff --name-only --diff-filter=U)" ]; then
|
||||
die "There are still unmerged files in the working tree. Resolve or discard them before restoring the snapshot."
|
||||
fi
|
||||
|
||||
prepare_backup_before_real_action "restore-snapshot" "before-restore-snapshot"
|
||||
restore_safety_backup="$BACKUP_BRANCH"
|
||||
restore_safety_snapshot="$STATE_SNAPSHOT_PATH"
|
||||
restore_safety_start_head="$STATE_START_HEAD"
|
||||
|
||||
if worktree_has_local_changes; then
|
||||
stash_current_changes "pre-restore-snapshot-preserve"
|
||||
preserve_stash_hash="$STASH_HASH"
|
||||
fi
|
||||
|
||||
say "Resetting '$CURRENT_BRANCH' to '$restore_start_head' before snapshot restore..."
|
||||
git reset --hard "$restore_start_head" >/dev/null
|
||||
|
||||
if [ -n "${STATE_STASH_HASH:-}" ]; then
|
||||
STASH_HASH="$STATE_STASH_HASH"
|
||||
STASH_REF=""
|
||||
BACKUP_BRANCH="$rollback_safety_backup"
|
||||
say "Restoring original pre-sync local changes..."
|
||||
restore_stash
|
||||
BACKUP_BRANCH="$restore_safety_backup"
|
||||
say "Restoring saved pre-sync local changes..."
|
||||
restore_stash 1
|
||||
fi
|
||||
|
||||
say "Restoring exact worktree snapshot from: $target_snapshot"
|
||||
restore_worktree_snapshot "$target_snapshot"
|
||||
|
||||
STATE_BRANCH="$CURRENT_BRANCH"
|
||||
STATE_BACKUP_BRANCH="$restore_safety_backup"
|
||||
STATE_STASH_HASH="$preserve_stash_hash"
|
||||
STATE_REMOTE_NAME="$REMOTE_NAME"
|
||||
STATE_REMOTE_URL="$REMOTE_URL"
|
||||
STATE_TARGET_BRANCH="$BRANCH"
|
||||
STATE_START_HEAD="$restore_safety_start_head"
|
||||
STATE_SNAPSHOT_PATH="$restore_safety_snapshot"
|
||||
STATE_STATUS="snapshot_restored"
|
||||
write_state
|
||||
|
||||
say "Snapshot restore completed."
|
||||
say "Safety backup of the pre-restore state kept at: $restore_safety_backup"
|
||||
say "Safety snapshot of the pre-restore state kept at: $restore_safety_snapshot"
|
||||
if [ -n "$preserve_stash_hash" ]; then
|
||||
STASH_HASH="$preserve_stash_hash"
|
||||
STASH_REF="$preserve_stash_ref"
|
||||
BACKUP_BRANCH="$rollback_safety_backup"
|
||||
say "Restoring local changes that existed before rollback..."
|
||||
restore_stash
|
||||
say "Safety stash of the pre-restore local changes kept at: $preserve_stash_hash"
|
||||
fi
|
||||
|
||||
clear_state
|
||||
say "Rollback completed."
|
||||
say "Current branch restored from: $reset_target"
|
||||
say "Safety backup of the pre-rollback state kept at: $rollback_safety_backup"
|
||||
}
|
||||
|
||||
run_dry_run_sync() {
|
||||
@@ -799,9 +996,13 @@ run_sync() {
|
||||
update_state_for_sync
|
||||
fetch_upstream
|
||||
rebase_onto_upstream
|
||||
restore_stash
|
||||
restore_stash 1
|
||||
say "Project is now synchronized with $REMOTE_NAME/$BRANCH."
|
||||
say "Safety backup branch available at: $BACKUP_BRANCH"
|
||||
say "Safety snapshot available at: $STATE_SNAPSHOT_PATH"
|
||||
if [ -n "$STATE_STASH_HASH" ]; then
|
||||
say "Original pre-sync stash retained for full rollback at: $STATE_STASH_HASH"
|
||||
fi
|
||||
}
|
||||
|
||||
run_fetch_only() {
|
||||
@@ -835,8 +1036,9 @@ Available actions:
|
||||
6) Rollback to saved backup
|
||||
7) Restore saved stash
|
||||
8) Clean dry-run workspace
|
||||
9) Show repository status
|
||||
10) Help
|
||||
9) Restore exact snapshot
|
||||
10) Show repository status
|
||||
11) Help
|
||||
0) Exit
|
||||
EOF
|
||||
printf 'Choose an action: '
|
||||
@@ -851,8 +1053,9 @@ EOF
|
||||
6) run_rollback; return ;;
|
||||
7) run_restore_saved_stash; return ;;
|
||||
8) run_clean_dry_run ;;
|
||||
9) show_status ;;
|
||||
10) show_usage ;;
|
||||
9) run_restore_snapshot; return ;;
|
||||
10) show_status ;;
|
||||
11) show_usage ;;
|
||||
0) exit 0 ;;
|
||||
*) say "Invalid menu selection: $choice" ;;
|
||||
esac
|
||||
@@ -869,6 +1072,7 @@ main() {
|
||||
rollback) run_rollback "${2:-}" ;;
|
||||
restore-stash) run_restore_saved_stash ;;
|
||||
clean-dry-run) run_clean_dry_run ;;
|
||||
restore-snapshot) run_restore_snapshot "${2:-}" ;;
|
||||
status) show_status ;;
|
||||
help|-h|--help) show_usage ;;
|
||||
menu)
|
||||
|
||||
Reference in New Issue
Block a user