Last active
May 21, 2024 14:49
-
-
Save izzygomez/c4efca57c2237277e3f725b612608b6b to your computer and use it in GitHub Desktop.
git-split.sh
This file contains 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
#!/bin/sh | |
# Any changes to this file should be reflected at: | |
# https://gist.github.com/izzygomez/c4efca57c2237277e3f725b612608b6b | |
# | |
# Quick script to split a file in `git` into two files while preserving blame | |
# history, which is useful for e.g. code blame view on Github.com. | |
# | |
# Inspired by answers [1] & [2] from Stack Overflow. | |
# | |
# Usage: | |
# - From clean working directory in your `main` branch, create a new splitting | |
# branch: `git checkout -b split-NEW-FILE-from-ORIGINAL-FILE` | |
# - Run this script: `git-split.sh ORIGINAL-FILE NEW-FILE` | |
# - Verify `git log` shows all "[Tool commit]" commits created in this script. | |
# - Edit ORIGINAL-FILE & NEW-FILE to only contain contents they should now | |
# contain*. | |
# - Commit new changes: `git add . && git commit -m "Split ORIGINAL-FILE & | |
# NEW-FILE definitions"` | |
# - Push changes to remote directory: `git push` | |
# - Verify history & blame looks correct on remote repo (e.g. on Github.com). | |
# | |
# | |
# * For example, if ORIGINAL-FILE was a file that contained definitions for two | |
# classes A & B, & the refactor is to split these classes into separate files, | |
# then ORIGINAL-FILE should delete class B's definition & NEW-FILE should | |
# delete class A's definition. Put differently, the state of files & file | |
# contents should have the following transformation: | |
# | |
# { ORIGINAL-FILE: {A, B} } ==> { ORIGINAL-FILE: {A}, NEW-FILE: {B} } | |
# | |
# | |
# [1] https://stackoverflow.com/a/53849651 | |
# [2] https://stackoverflow.com/a/53849613 | |
if [[ $# -ne 2 ]]; then | |
echo "Usage: git-split.sh original-file new-file" | |
exit 0 | |
fi | |
GIST_LINK="https://gist.github.com/izzygomez/c4efca57c2237277e3f725b612608b6b" | |
git mv "$1" "$2" | |
git commit -n -m "[Tool Commit] Split history $1 to $2 - rename original-file to new-file" -m "See: $GIST_LINK" | |
REV=$(git rev-parse HEAD) | |
git reset --hard HEAD^ | |
git mv "$1" temp | |
git commit -n -m "[Tool Commit] Split history $1 to $2 - rename original-file to temp" -m "See: $GIST_LINK" | |
git merge $REV | |
git commit -a -n -m "[Tool Commit] Split history $1 to $2 - resolve conflict and keep both files" -m "See: $GIST_LINK" | |
git mv temp "$1" | |
git commit -n -m "[Tool Commit] Split history $1 to $2 - restore name of original-file" -m "See: $GIST_LINK" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment