Last active
February 20, 2025 17:18
-
-
Save burbma/35dbe05aaf2e0cf4d0b76d6374985e39 to your computer and use it in GitHub Desktop.
Cherry pick commits from a legacy repo into your new one where you've changed the directory structure and already made a bunch of changes. This is useful during the early stages of a cut over when you are still maintaining both repos but once you launch the new one the old one will go away.
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
#!/usr/bin/env bash | |
# Ensure your legacy repo is on a clean check out of main. | |
# | |
# First arg is path to legacy repo. | |
# Second arg is the arg for git rev-list. | |
# Third arg is the leading directory structure to match for replacement. | |
# Fourth arg is the directory structure to put in as a replatement. | |
# Note the comment below about tabs to spaces, I could've but didn't | |
# parameterize that with a fifth arg. | |
# | |
# Ex: bin/cherry-pick.sh ~/src/legacy-repo HEAD...2bc237f6 src src\/js\/legacy | |
# Pro tip: git rev-list is inclusive...exclusive. | |
# | |
# The script will pause after getting the changes from each commit. Look for | |
# any weirdness like patch rejects or files not found etc. If it looks weird | |
# you can open another shell to manually intervene and get it sorted out. Then | |
# you can press any key to continue and the script will git add -a and make | |
# the commit automatically. | |
# | |
legacy_path=${1:-~/src/legacy-repo} | |
commit_range=${2:-HEAD...HEAD~} | |
dir_match=${3:-src} | |
dir_replace=${4:-src\/js\/legacy} | |
for commit in $(cd $legacy_path && git rev-list $commit_range | tac) | |
do | |
echo $commit | |
for file in $(git diff-tree --no-commit-id --name-only $commit -r) | |
do | |
new=${file/#$dir_match/$dir_replace} | |
git show $commit --no-color -- $file | patch --ignore-whitespace $new | |
# This part changes tabs to spaces. Because obviously legacy uses tabs | |
# and the new-shiney uses spaces. You might have different file extensions | |
# you want to put in here. | |
find -E $new -type f -regex '.*.(yaml|vue|js|ts|html)' -exec bash -c 'echo "$0" && expand -t 4 "$0" > /tmp/expand.$$ && mv /tmp/expand.$$ "$0" || exit 255' {} \; | |
done | |
read -p "Make any manual interventions then press any key to continue..." -n1 -s | |
echo | |
git add -A | |
git commit -m "cherry-pick legacy: $(git rev-list --abbrev-commit --format=oneline --max-count=1 $commit)" | |
echo | |
done |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment