Last active
January 3, 2025 23:03
-
-
Save jphalip/b7d0bc22c908eac956d2adae733796c8 to your computer and use it in GitHub Desktop.
Read more about it here: https://www.julienphalip.com/blog/git-hard-rebase/
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Takes two parameters: target branch and commit message. | |
# Does a hard reset on the target branch then adds a single commit with the diff | |
# between the two branches. Sort of simulates a rebase but without having to | |
# resolve potential conflicts in intermediary commits. | |
function git-hard-rebase() { | |
# Parameter validation | |
if [ "$#" -ne 2 ]; then | |
echo "Usage: git-hard-rebase <branch-to-rebase-on> <commit-message>" | |
return 1 | |
fi | |
# Store the original directory and move to repo root | |
original_dir=$(pwd) | |
repo_root=$(git rev-parse --show-toplevel) | |
if [ $? -ne 0 ]; then | |
echo "Error: Not in a git repository." | |
return 1 | |
fi | |
cd "${repo_root}" || return 1 | |
# Validate branch exists | |
target_branch="$1" | |
if ! git rev-parse --quiet --verify "${target_branch}" > /dev/null; then | |
echo "Branch name ${target_branch} does not exist." | |
cd "${original_dir}" || return 1 | |
return 1 | |
fi | |
# Validate commit message | |
message="$2" | |
if [ -z "${message}" ]; then | |
echo "Message is empty" | |
cd "${original_dir}" || return 1 | |
return 1 | |
fi | |
# Create diff file | |
current_branch=$(git branch --show-current) | |
file_diff=$(mktemp "/tmp/${current_branch}.${target_branch}.XXXXXX") | |
echo "Diff file: ${file_diff}" | |
git diff "${target_branch}" > "${file_diff}" | |
# Validate diff is not empty | |
if [ ! -s "${file_diff}" ]; then | |
echo "Warning: Diff file is empty. No changes to apply." | |
rm "${file_diff}" | |
cd "${original_dir}" || return 1 | |
return 1 | |
fi | |
# Create backup and reset to target | |
backup_branch="backup/${current_branch}-$(date '+%Y_%m_%d-%H_%M_%S')" | |
git branch "${backup_branch}" | |
git reset --hard "${target_branch}" | |
# Apply changes and commit | |
if ! git apply --verbose "${file_diff}"; then | |
echo "Error: Failed to apply the patch cleanly." | |
echo "You may need to resolve conflicts manually." | |
echo "The diff file is located at: ${file_diff}" | |
cd "${original_dir}" || return 1 | |
return 1 | |
fi | |
# Verify changes were applied | |
if git diff --quiet; then | |
echo "Warning: No changes were applied by the patch." | |
rm "${file_diff}" | |
cd "${original_dir}" || return 1 | |
return 1 | |
else | |
git add -A | |
git commit -m "${message}" | |
echo "Changes have been committed." | |
fi | |
# Cleanup | |
rm "${file_diff}" | |
echo "Hard rebase completed successfully." | |
cd "${original_dir}" || return 1 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment