Skip to content

Commit e112b91

Browse files
committed
fix(gitutils): 🐛 improve branch validation and error logging in _git-fix-base.sh
1 parent 5d93125 commit e112b91

1 file changed

Lines changed: 40 additions & 46 deletions

File tree

src/gitutils/_git-fix-base.sh

Lines changed: 40 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,25 @@ eval $(
1010
help
1111
)
1212

13+
# Navigate to the repository root
14+
cd "$(git rev-parse --show-toplevel)" >/dev/null
15+
1316
# Validate required arguments
1417
if [ -z "$target" ]; then
1518
zz_log e 'Target branch is required. Use -h for help.'
1619
exit 1
20+
elif ! git rev-parse --verify "$target" >/dev/null 2>&1; then
21+
zz_log e "Target branch '$target' does not exist"
22+
exit 1
1723
fi
1824

19-
# Get current branch if source is not specified
25+
# Get current branch if source is not specified and validate source branch exists
2026
if [ -z "$source" ]; then
2127
source=$(git rev-parse --abbrev-ref HEAD)
2228
zz_log i "Using current branch as source: $source"
29+
elif ! git rev-parse --verify "$source" >/dev/null 2>&1; then
30+
zz_log e "Source branch '$source' does not exist"
31+
exit 1
2332
fi
2433

2534
# Validate that source and target are different
@@ -28,52 +37,37 @@ if [ "$source" = "$target" ]; then
2837
exit 1
2938
fi
3039

31-
# Navigate to the repository root
32-
cd "$(git rev-parse --show-toplevel)" >/dev/null
33-
34-
# Fetch updates from the remote repository
35-
git fetch --progress --prune --recurse-submodules=no origin >/dev/null
36-
37-
# Validate branches exist
38-
if ! git rev-parse --verify "$source" >/dev/null 2>&1; then
39-
zz_log e "Source branch '$source' does not exist"
40-
exit 1
41-
fi
42-
43-
if ! git rev-parse --verify "$target" >/dev/null 2>&1; then
44-
zz_log e "Target branch '$target' does not exist"
45-
exit 1
46-
fi
47-
4840
# Check if there are uncommitted changes
49-
if ! git diff-index --quiet HEAD --; then
41+
if git isDirty; then
5042
zz_log e 'Working directory is not clean. Please commit or stash your changes.'
5143
exit 1
5244
fi
5345

5446
# Find the merge base between source and target
55-
merge_base=$(git merge-base "$source" "$target")
56-
if [ -z "$merge_base" ]; then
47+
base=$(git merge-base "$source" "$target")
48+
if [ -z "$base" ]; then
5749
zz_log e "Could not find common ancestor between '$source' and '$target'"
5850
exit 1
51+
else
52+
zz_log i "Found merge base: $base"
5953
fi
6054

6155
# Get commits that are in source but not in target
62-
commits_to_move=$(git log --reverse --pretty=oneline --all --ancestry-path "$target".."$source" | grep -vE "^[a-f0-9]+ Merge" | awk '{print $1}')
56+
commits=$(git log --reverse --pretty=oneline ${base}..${source} | grep -vE "^[a-f0-9]+ Merge" | awk '{print $1}')
6357

64-
if [ -z "$commits_to_move" ]; then
58+
if [ -z "$commits" ]; then
6559
zz_log i "No commits to move from '$source' to '$target'"
6660
exit 0
6761
fi
6862

6963
# Count commits
70-
commit_count=$(echo "$commits_to_move" | wc -l)
71-
zz_log i "Found $commit_count commit(s) to move from '$source' to '$target'"
64+
count=$(echo "$commits" | wc -l)
65+
zz_log i "Found $count commit(s) to move from '$source' to '$target'"
7266

7367
# Show commits in dry-run mode
7468
if [ -n "$dryrun" ]; then
7569
zz_log i "Commits that would be moved:"
76-
echo "$commits_to_move" | while read commit; do
70+
echo "$commits" | while read commit; do
7771
if [ -n "$commit" ]; then
7872
echo " $(git log --oneline -1 "$commit")"
7973
fi
@@ -83,29 +77,29 @@ if [ -n "$dryrun" ]; then
8377
fi
8478

8579
# Confirm the operation
86-
zz_log i "About to move $commit_count commit(s) from '$source' to '$target':"
87-
echo "$commits_to_move" | while read commit; do
80+
zz_log i "About to move $count commit(s) from '$source' to '$target':"
81+
echo "$commits" | while read commit; do
8882
if [ -n "$commit" ]; then
8983
zz_log - " $(git log --oneline -1 "$commit")" >&2
9084
fi
9185
done
9286
zz_log i "This will:"
93-
zz_log - "1. Checkout '$target' branch"
94-
zz_log - "2. Create a temporary branch for the rebase"
95-
zz_log - "3. Cherry-pick commits from '$source'"
96-
zz_log - "4. Reset '$source' to the merge base"
97-
zz_log - "5. Fast-forward '$target' to include the rebased commits"
87+
zz_log - " 1. Checkout '$target' branch"
88+
zz_log - " 2. Create a temporary branch for the rebase"
89+
zz_log - " 3. Cherry-pick commits from '$source'"
90+
zz_log - " 4. Reset '$source' to the merge base"
91+
zz_log - " 5. Fast-forward '$target' to include the rebased commits"
9892
echo ""
9993
if ! zz_ask "Yn" "Continue?"; then
10094
zz_log e "Operation cancelled"
10195
exit 1
10296
fi
10397

10498
# Store current branch
105-
current_branch=$(git rev-parse --abbrev-ref HEAD)
99+
current=$(git rev-parse --abbrev-ref HEAD)
106100

107101
# Create a temporary branch name
108-
temp_branch="temp-fix-base-$(date +%s)"
102+
temp="temp-fix-base-$(date +%s)"
109103

110104
# Checkout target branch
111105
zz_log i "Checking out '$target' branch"
@@ -115,17 +109,17 @@ if ! git checkout "$target"; then
115109
fi
116110

117111
# Create temporary branch from target
118-
zz_log i "Creating temporary branch '$temp_branch'"
119-
if ! git checkout -b "$temp_branch"; then
112+
zz_log i "Creating temporary branch '$temp'"
113+
if ! git checkout -b "$temp"; then
120114
zz_log e "Failed to create temporary branch"
121-
git checkout "$current_branch"
115+
git checkout "$current" 2>/dev/null
122116
exit 1
123117
fi
124118

125119
# Cherry-pick commits from source
126120
zz_log i "Cherry-picking commits..."
127121
failed=0
128-
echo "$commits_to_move" | while read commit; do
122+
echo "$commits" | while read commit; do
129123
if [ -n "$commit" ]; then
130124
if ! git cherry-pick "$commit" --strategy=recursive -X theirs --allow-empty; then
131125
zz_log e "Cherry-pick failed on commit $commit"
@@ -147,11 +141,11 @@ zz_log i "Resetting '$source' to merge base"
147141
if ! git checkout "$source"; then
148142
zz_log e "Failed to checkout '$source' branch"
149143
# Cleanup temp branch
150-
git branch -D "$temp_branch" 2>/dev/null
144+
git branch -D "$temp" 2>/dev/null
151145
exit 1
152146
fi
153147

154-
if ! git reset --hard "$merge_base"; then
148+
if ! git reset --hard "$base"; then
155149
zz_log e "Failed to reset '$source' branch"
156150
exit 1
157151
fi
@@ -163,20 +157,20 @@ if ! git checkout "$target"; then
163157
exit 1
164158
fi
165159

166-
if ! git merge --ff-only "$temp_branch"; then
160+
if ! git merge --ff-only "$temp"; then
167161
zz_log e "Failed to fast-forward '$target' branch"
168162
# Cleanup temp branch
169-
git branch -D "$temp_branch" 2>/dev/null
163+
git branch -D "$temp" 2>/dev/null
170164
exit 1
171165
fi
172166

173167
# Cleanup temporary branch
174168
zz_log i "Cleaning up temporary branch"
175-
git branch -D "$temp_branch"
169+
git branch -D "$temp"
176170

177171
# Return to original branch if it still exists and is different from source
178-
if [ "$current_branch" != "$source" ] && git rev-parse --verify "$current_branch" >/dev/null 2>&1; then
179-
git checkout "$current_branch"
172+
if [ "$current" != "$source" ] && git rev-parse --verify "$current" >/dev/null 2>&1; then
173+
git checkout "$current"
180174
else
181175
# If original branch was source, stay on target
182176
zz_log i "Staying on '$target' branch"

0 commit comments

Comments
 (0)