Skip to content

Instantly share code, notes, and snippets.

@jphalip
Last active January 3, 2025 23:03
Show Gist options
  • Save jphalip/b7d0bc22c908eac956d2adae733796c8 to your computer and use it in GitHub Desktop.
Save jphalip/b7d0bc22c908eac956d2adae733796c8 to your computer and use it in GitHub Desktop.
# 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