Skip to content

Commit c17a3d2

Browse files
committed
fix(gitutils): 🐛 enhance hotfix branch creation and rebase handling
1 parent 9de255e commit c17a3d2

2 files changed

Lines changed: 100 additions & 7 deletions

File tree

src/gitutils/_git-release-hotfix.sh

Lines changed: 90 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,105 @@ cd "$(git rev-parse --show-toplevel)" >/dev/null
66
# Parse arguments and print help if needed
77
eval $(
88
zz_args "Create HotFix branch" $0 "$@" <<-help
9+
r - rebase force rebase of current commits onto hotfix branch
910
help
1011
)
1112

1213
#### GET last vX.Y.Z tag on the main branch, removing the leading 'v' and replacing last number with 'X'
13-
current=$(git describe --tags --abbrev=0 --match "v[0-9]*.[0-9]*.[0-9]*" main | sed -e 's/^v//' -e 's/\.[0-9]*$/.X/')
14+
main=$(git describe --tags --abbrev=0 --match "v[0-9]*.[0-9]*.[0-9]*" main)
1415

15-
#### SAVE CURRENT STATUS
16-
git stash --include-untracked --message "Before $current" --keep-index
16+
if [ -z "$main" ]; then
17+
zz_log e "No tag found on main branch"
18+
exit 1
19+
else
20+
zz_log i "Current version is $main"
21+
fi
22+
23+
# Check if all commits since the last tag are conventional commits of 'fix:' type
24+
# or if rebase is forced via command line option
25+
if [ -n "$rebase" ]; then
26+
zz_log i "Rebase forced via command line option, will rebase commits onto hotfix branch"
27+
elif git log "$main"..HEAD --pretty=%B | grep -v -E '^fix(\(.+\))?: ' | grep -E '^[a-zA-Z]' >/dev/null; then
28+
zz_log w "There are commits since $main that are not of type 'fix:', creating hotfix branch and reapplying stash"
29+
rebase=false
30+
else
31+
zz_log i "All commits since $main are of type 'fix:', creating hotfix branch and rebasing current history + stash on top of it"
32+
rebase=true
33+
fi
34+
35+
# If rebase needed, check that develop branch has not been pushed since last tag
36+
if [ -n "$rebase" ]; then
37+
if [ "$(git rev-parse develop)" != "$(git rev-parse origin/develop)" ]; then
38+
zz_log e "Develop branch has been pushed since last tag, cannot rebase safely, aborting"
39+
exit 1
40+
fi
41+
fi
42+
43+
# Ensure working directory is clean
44+
if [ -n "$(git status --porcelain)" ]; then
45+
zz_log e "Working directory is not clean. Please commit or stash changes."
46+
exit 1
47+
fi
1748

1849
#### PREVENT GIT EDITOR PROMPT
1950
GIT_EDITOR=:
2051

52+
current=$(echo "$main" | sed -E 's/([0-9]+)\.([0-9]+)\.([0-9]+)/\1.\2.X/')
53+
2154
#### START HOTFIX
2255
git flow hotfix start $current
2356

24-
#### RESTORE STATUS
25-
git stash apply
57+
#### RESTORE STATUS AND HANDLE REBASE
58+
if [ -n "$rebase" ]; then
59+
60+
zz_log i "Rebasing: inverting develop and hotfix branches..."
61+
62+
# Store current branch heads
63+
develop_head=$(git rev-parse develop)
64+
hotfix_head=$(git rev-parse "hotfix/$current")
65+
66+
# Pick all "fix" commits from develop and rebase them onto hotfix branch
67+
zz_log i "Cherry-picking fix commits from develop branch..."
68+
69+
# Get all fix commits from develop since the main tag
70+
fix_commits=$(git log --reverse --pretty=format:"%H" "$main"..develop --grep="^fix")
71+
72+
if [ -n "$fix_commits" ]; then
73+
# Cherry-pick each fix commit onto the hotfix branch
74+
echo "$fix_commits" | while read commit; do
75+
76+
zz_log i "Cherry-picking commit: $(git log --oneline -1 $commit)"
77+
if ! git cherry-pick "$commit"; then
78+
zz_log e "Failed to cherry-pick commit $commit"
79+
zz_log i "Please resolve conflicts and run 'git cherry-pick --continue'"
80+
exit 1
81+
fi
82+
done
83+
zz_log s "Successfully cherry-picked all fix commits"
84+
85+
# Now, remove the fix commits on develop branch that are now on hotfix
86+
echo "$fix_commits" | while read commit; do
87+
88+
if ! git checkout develop && git revert --no-commit "$commit"; then
89+
zz_log e "Failed to revert commit $commit on develop"
90+
exit 1
91+
fi
92+
93+
done
94+
95+
96+
else
97+
zz_log i "No fix commits found to cherry-pick"
98+
fi
99+
100+
# Reset develop branch to the main tag (removing the fix commits that are now on hotfix)
101+
git checkout develop
102+
git reset --hard "$main"
103+
zz_log i "Reset develop branch to $main"
104+
105+
# Return to hotfix branch
106+
git checkout "hotfix/$current"
107+
108+
zz_log s "Successfully inverted develop and hotfix branches"
109+
fi
110+

src/gitutils/_git-release-prod.sh

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,12 @@ if ! git checkout $flow/$name >/dev/null 2>&1; then
4343
fi
4444
zz_log s "On branch: {Blue $flow/$name}"
4545

46+
# Ensure working directory is clean
47+
if [ -n "$(git status --porcelain)" ]; then
48+
zz_log e "Working directory is not clean. Please commit or stash changes."
49+
exit 1
50+
fi
51+
4652
# Get the new version from gitversion
4753
GBV=$(gv -showvariable MajorMinorPatch)
4854
if [ -z "$GBV" ]; then
@@ -68,6 +74,9 @@ if bump-changelog -f $GBV -b; then
6874
if git flow $flow finish $name --push --tagname $GBV --message $GBV ; then
6975
zz_log s "Release finished: {B $GBV}"
7076
rm -f .git/RELEASE
77+
78+
# Create git tag for the new version
79+
bump-tag $GBV
7180
else
7281
git undo
7382
zz_log e "Cannot finish release. CHANGELOG & VERSION are not updated."
@@ -76,5 +85,4 @@ else
7685
zz_log e "Cannot update version & finish release"
7786
fi
7887

79-
# Follow major/minor tags
80-
bump-tag $GBV
88+

0 commit comments

Comments
 (0)