Skip to content

Instantly share code, notes, and snippets.

@nealeu
Last active September 6, 2024 17:17
Show Gist options
  • Save nealeu/6dae62c653bacf63c65d4019c020936f to your computer and use it in GitHub Desktop.
Save nealeu/6dae62c653bacf63c65d4019c020936f to your computer and use it in GitHub Desktop.
Copilot (mostly) written script to spread commits back to the previous mod of that file
#!/bin/bash
# This gets the list of files changed in the last commit, resets the last commit,
# stages the changes for each file, and then creates a fixup commit for each file.
# Finally, it rebases the fixup commits onto the earliest commit in the list of unique commit hashes.
# It's useful if you have done a load of fixes in response to a review, and then want to apply
# them to the appropriate commits so that the history makes sense.
ROOT=$(git rev-parse --show-toplevel)
pushd $ROOT
# Get the list of files changed in the last commit
files=$(git diff --name-only HEAD~1 HEAD)
git reset --soft HEAD~1
git reset
# Initialize an empty set to hold the unique commit hashes
declare -A commit_hashes
# Create a fixup commit for each file
for file in $files; do
git add $file
TARGET_COMMIT_HASH=$(git log -1 --pretty=format:%H -- $file)
git commit --fixup $TARGET_COMMIT_HASH
commit_hashes[$TARGET_COMMIT_HASH]=1
done
echo Commit hashes: ${!commit_hashes[@]}
earliest_commit=$(git rev-list --date-order --reverse ${!commit_hashes[@]} ^refs/remotes/origin/HEAD | head -n 1)
echo earliest: $earliest_commit
git rebase -i --autosquash ${earliest_commit}~1
popd
@nealeu
Copy link
Author

nealeu commented Sep 6, 2024

A version of this could be called as a git alias where instead of doing git fixup, you change lines 13-15 to instead get the files that are staged for commit.
Or as I've done with this is just commit them, as I'm using this to grab a PR before approving it, once the developer has done their fixes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment