Skip to content

Instantly share code, notes, and snippets.

@tsl0922
Last active September 27, 2022 02:15
Show Gist options
  • Save tsl0922/3ef862a10ebbbeca6cda94028a8dc108 to your computer and use it in GitHub Desktop.
Save tsl0922/3ef862a10ebbbeca6cda94028a8dc108 to your computer and use it in GitHub Desktop.
Replay a range of git commit in another repo (git format-patch + git am with merge commit support)
#!/bin/bash
set -eo pipefail
SRC_REPO=""
TARGET_REPO=""
RANGE=""
# generate patches
patch_gen() {
cd ${SRC_REPO}
LIST=$(git log --oneline --first-parent --reverse ${RANGE});
I=0;
IFS=$'\n';
for ITEM in ${LIST}; do
NNNN=$(printf "%04d\n" $I);
COMMIT=$(echo "${ITEM}" | sed 's|^\([^ ]*\) \(.*\)|\1|');
TITLE=$(echo "${ITEM}" | sed 's|^\([^ ]*\) \(.*\)|\2|' | sed 's|[ -/~]|-|g' | sed 's|--*|-|g' | sed 's|^\(.\{52\}\).*|\1|');
FILENAME="${NNNN}-${TITLE}.patch";
echo "Writing ${FILENAME}...";
git log -p -c --binary --pretty=email --stat -m --first-parent ${COMMIT}~1..${COMMIT} > ${FILENAME};
I=$(($I+1));
done
}
# apply patches
patch_apply() {
cd ${TARGET_REPO}
for patch in ${SRC_REPO}/*.patch; do
echo "== Applying ${patch}..."
COMMIT_USER=$(head -n 2 $patch | grep 'From: ' | sed 's/From: //' | awk -F" <" '{print $1}')
COMMIT_EMAIL=$(head -n 2 $patch | grep 'From: ' | sed 's/From: //' | awk -F"<" '{print $2}' | sed 's/>//')
git -c user.name="${COMMIT_USER}" -c user.email="${COMMIT_EMAIL}" am -3 --keep-cr --committer-date-is-author-date ${patch}
done
}
patch_gen
patch_apply
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment