486 lines
19 KiB
Bash
Executable File
486 lines
19 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
|
|
set -e
|
|
|
|
cd $(dirname $0)
|
|
cd ..
|
|
cd ..
|
|
|
|
if [[ -z ${PACKAGE} ]] || [[ -z ${TO_COMMIT} ]] ; then
|
|
echo "USAGE: PACKAGE=<package-name> [TO_DIR=<path>] TO_COMMIT=<hash> [TO_REMOTE=<git-repo-url>] ./scripts/rebase"
|
|
exit 1
|
|
fi
|
|
|
|
# Basic environment variables
|
|
STAGING_BRANCH=staging-${RANDOM}
|
|
|
|
FROM_REMOTE_NAME=from-remote-${RANDOM}
|
|
FROM_BRANCH=from-${RANDOM}
|
|
TO_REMOTE_NAME=to-remote-${RANDOM}
|
|
TO_BRANCH=to-${RANDOM}
|
|
|
|
GC_DIRECTORY=packages/${PACKAGE}/generated-changes
|
|
EXCLUDE_DIRECTORY=${GC_DIRECTORY}/exclude
|
|
CHARTS_ORIGINAL_DIRECTORY=packages/${PACKAGE}/charts-original
|
|
CRD_CHART_DIRECTORY=packages/${PACKAGE}/charts-crd # TODO: get from package.yaml
|
|
CRDS_DIRECTORY=crd-manifest # TODO: get from package.yaml
|
|
PACKAGE_YAML_PATH=packages/${PACKAGE}/package.yaml
|
|
|
|
# Grab environment variables from package.yaml
|
|
FROM_REMOTE=$(yq e '.url' ${PACKAGE_YAML_PATH})
|
|
if [[ "${FROM_REMOTE}" != *.git ]]; then
|
|
echo "./scripts/rebase can only be done on Git-based packages, found url: ${FROM_REMOTE}"
|
|
exit 1
|
|
fi
|
|
if [[ -z "${TO_REMOTE}" ]]; then
|
|
TO_REMOTE=${FROM_REMOTE}
|
|
fi
|
|
FROM_COMMIT=$(yq e '.commit' ${PACKAGE_YAML_PATH})
|
|
if [[ -z ${FROM_COMMIT} ]]; then
|
|
echo "Unable to find 'commit' in ${PACKAGE_YAML_PATH}"
|
|
fi
|
|
FROM_DIR=$(yq e '.subdirectory' ${PACKAGE_YAML_PATH})
|
|
if [[ -z ${FROM_DIR} ]]; then
|
|
FROM_DIR="."
|
|
fi
|
|
if [[ -z "${TO_DIR}" ]]; then
|
|
TO_DIR=${FROM_DIR}
|
|
fi
|
|
|
|
CHARTS_WORKING_DIRECTORY=$(yq e '.workingDir' ${PACKAGE_YAML_PATH})
|
|
if [ -z "${CHARTS_WORKING_DIRECTORY}" ] || [ "${CHARTS_WORKING_DIRECTORY}" == "null" ]; then
|
|
DEST_DIRECTORY=packages/${PACKAGE}/charts
|
|
else
|
|
DEST_DIRECTORY=packages/${PACKAGE}/${CHARTS_WORKING_DIRECTORY}
|
|
fi
|
|
|
|
IGNORE_DEPS=$(yq e '.ignoreDependencies' ${PACKAGE_YAML_PATH} -o p | cut -d ' ' -f3)
|
|
|
|
# Start rebase process
|
|
if [ -z "${FROM_DIR}" ] && [ -z "${TO_DIR}" ]; then
|
|
echo "Attempting to rebase ${PACKAGE} from commit ${FROM_COMMIT} to ${TO_DIR}"
|
|
elif [ -z "${FROM_DIR}" ] && [ -n "${TO_DIR}" ]; then
|
|
echo "Attempting to rebase ${PACKAGE} from commit ${FROM_COMMIT} to ${TO_DIR} at subdirectory ${TO_DIR}"
|
|
elif [ -n "${FROM_DIR}" ] && [ -z "${TO_DIR}" ]; then
|
|
echo "Attempting to rebase ${PACKAGE} from commit ${FROM_COMMIT} at subdirectory ${FROM_DIR} to ${TO_DIR}"
|
|
else
|
|
echo "Attempting to rebase ${PACKAGE} from commit ${FROM_COMMIT} at subdirectory ${FROM_DIR} to ${TO_DIR} at subdirectory ${TO_DIR}"
|
|
fi
|
|
echo ""
|
|
|
|
# Pre-rebase checks
|
|
|
|
echo "Running pre-flight checks..."
|
|
|
|
echo "> Checking if Git is clean..."
|
|
if [[ -n "$(git status --porcelain)" ]]; then
|
|
echo "Cannot run rebase on unclean repository:"
|
|
git status --porcelain
|
|
exit 1
|
|
fi
|
|
|
|
echo "> Checking if ${DEST_DIRECTORY} exists..."
|
|
if [ -d "${DEST_DIRECTORY}" ]; then
|
|
echo "Destination directory ${DEST_DIRECTORY} already exists"
|
|
exit 1
|
|
fi
|
|
|
|
remotes=$(git remote)
|
|
echo "> Checking if ${FROM_REMOTE_NAME} exists..."
|
|
if echo ${remotes} | grep -q ${FROM_REMOTE_NAME}; then
|
|
echo "Remote ${FROM_REMOTE_NAME} already exists"
|
|
exit 1
|
|
fi
|
|
|
|
echo "> Checking if ${TO_REMOTE_NAME} exists..."
|
|
if echo ${remotes} | grep -q ${TO_REMOTE_NAME}; then
|
|
echo "Remote ${TO_REMOTE_NAME} already exists"
|
|
exit 1
|
|
fi
|
|
|
|
# Ensure branches doesn't already exist
|
|
echo "> Checking if sandbox branches (${STAGING_BRANCH}, ${FROM_BRANCH}, ${TO_BRANCH}) exist..."
|
|
branches=$(git show-ref --heads | cut -d/ -f3-)
|
|
if echo ${branches} | grep -q ${STAGING_BRANCH}; then
|
|
echo "Branch ${STAGING_BRANCH} already exists"
|
|
exit 1
|
|
elif echo ${branches} | grep -q ${FROM_BRANCH}; then
|
|
echo "Branch ${FROM_BRANCH} already exists"
|
|
exit 1
|
|
elif echo ${branches} | grep -q ${TO_BRANCH}; then
|
|
echo "Branch ${TO_BRANCH} already exists"
|
|
exit 1
|
|
fi
|
|
|
|
CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD)
|
|
|
|
# Cleanup logic
|
|
|
|
trap 'cleanup' EXIT
|
|
|
|
cleanup() {
|
|
# Execute all cleanup even if there is failures
|
|
echo ""
|
|
echo "Cleaning up Git remotes and branches created by this script..."
|
|
set +e
|
|
git remote rm ${FROM_REMOTE_NAME} 2>/dev/null
|
|
git remote rm ${TO_REMOTE_NAME} 2>/dev/null
|
|
git clean -df 1>/dev/null 2>/dev/null
|
|
git reset --hard 1>/dev/null 2>/dev/null
|
|
git checkout ${CURRENT_BRANCH} 2>/dev/null
|
|
git branch -D ${STAGING_BRANCH} 2>/dev/null
|
|
git branch -D ${FROM_BRANCH} 2>/dev/null
|
|
git branch -D ${TO_BRANCH} 2>/dev/null
|
|
}
|
|
|
|
echo ""
|
|
echo "Preparing Git for rebase..."
|
|
|
|
# Start rebase
|
|
echo "> Checking out a new branch at ${STAGING_BRANCH} to sandbox changes..."
|
|
git checkout -b ${STAGING_BRANCH} 1>/dev/null 2>/dev/null
|
|
|
|
# Add provided remotes to git
|
|
echo "> Adding ${FROM_REMOTE} as a remote ${FROM_REMOTE_NAME} on Git"
|
|
git remote add ${FROM_REMOTE_NAME} ${FROM_REMOTE} 1>/dev/null 2>/dev/null
|
|
echo "> Fetching ${FROM_COMMIT} from ${FROM_REMOTE_NAME} on Git"
|
|
git fetch --depth=1 ${FROM_REMOTE_NAME} ${FROM_COMMIT}
|
|
echo "> Adding ${TO_REMOTE} as a remote ${TO_REMOTE_NAME} on Git"
|
|
git remote add ${TO_REMOTE_NAME} ${TO_REMOTE} 1>/dev/null 2>/dev/null
|
|
echo "> Fetching ${TO_COMMIT} from ${TO_REMOTE_NAME} on Git"
|
|
git fetch --depth=1 ${TO_REMOTE_NAME} ${TO_COMMIT}
|
|
|
|
# Checkout the provided tag from that remote into the FROM_BRANCH
|
|
echo "> Checking out a new branch at ${FROM_BRANCH} tracking ${FROM_REMOTE} at ${FROM_COMMIT}..."
|
|
git checkout ${FROM_COMMIT} -b ${FROM_BRANCH} 1>/dev/null 2>/dev/null
|
|
|
|
# Fail if subdirectory specified does not exist on remote
|
|
echo "> Checking if ${FROM_REMOTE} at ${FROM_COMMIT} has subdirectory '${FROM_DIR}'..."
|
|
if [ ! -d "${FROM_DIR}" ]; then
|
|
echo "${FROM_REMOTE} at ${FROM_COMMIT} does not contain subdirectory ${FROM_DIR}"
|
|
exit 1
|
|
fi
|
|
|
|
# Copy subdirectory into a special folder
|
|
mkdir -p .rebase/from
|
|
cp -R ${FROM_DIR}/* .rebase/from
|
|
git add .rebase/from 1>/dev/null 2>/dev/null
|
|
git commit -m "Temporarily moving ${FROM_DIR} to .rebase/from" 1>/dev/null 2>/dev/null
|
|
|
|
# Checkout the provided tag from that remote into the TO_BRANCH
|
|
echo "> Checking out a new branch at ${TO_BRANCH} tracking ${TO_REMOTE} at ${TO_COMMIT}..."
|
|
git checkout ${TO_COMMIT} -b ${TO_BRANCH} 1>/dev/null 2>/dev/null
|
|
|
|
# Fail if subdirectory specified does not exist on remote
|
|
echo "> Checking if ${TO_REMOTE} at ${TO_COMMIT} has subdirectory '${TO_DIR}'..."
|
|
if [ ! -d "${TO_DIR}" ]; then
|
|
echo "${TO_REMOTE} at ${TO_COMMIT} does not contain subdirectory ${TO_DIR}"
|
|
exit 1
|
|
fi
|
|
|
|
# Copy subdirectory into a special folder
|
|
mkdir -p .rebase/to
|
|
cp -R ${TO_DIR}/* .rebase/to
|
|
git add .rebase/to 1>/dev/null 2>/dev/null
|
|
git commit -m "Temporarily moving ${TO_DIR} to .rebase/to" 1>/dev/null 2>/dev/null
|
|
|
|
# Pull charts into directory in order
|
|
git checkout ${STAGING_BRANCH} 1>/dev/null 2>/dev/null
|
|
PACKAGE=${PACKAGE} USE_CACHE=${USE_CACHE} make prepare 1>/dev/null 2>/dev/null
|
|
chmod 644 $(find ${DEST_DIRECTORY} -type f | xargs)
|
|
|
|
# Save changes added by developer
|
|
if [ -d "${CRD_CHART_DIRECTORY}" ]; then
|
|
git add ${DEST_DIRECTORY} ${CRD_CHART_DIRECTORY}
|
|
else
|
|
git add ${DEST_DIRECTORY}
|
|
fi
|
|
git commit -m "Add changes saved in generated-changes" 1>/dev/null 2>/dev/null
|
|
|
|
# Keep track of commits that need to be dropped entirely
|
|
GC_COMMIT=$(git rev-parse --short HEAD)
|
|
|
|
if [ -d "${CRD_CHART_DIRECTORY}" ]; then
|
|
# Move CRDs back into main chart so that you can rebase changes to CRDs as well
|
|
mv ${CRD_CHART_DIRECTORY}/${CRDS_DIRECTORY} ${DEST_DIRECTORY}/crds
|
|
git add ${CRD_CHART_DIRECTORY}/${CRDS_DIRECTORY} ${DEST_DIRECTORY}/crds
|
|
git commit -m "Move CRDs back into main chart" 1>/dev/null 2>/dev/null
|
|
fi
|
|
|
|
if [ -d "${EXCLUDE_DIRECTORY}" ]; then
|
|
# Calculate excluded files and directories
|
|
EXCLUDE_DIRECTORIES=$(find ${EXCLUDE_DIRECTORY}/* -type d | sed "s/${EXCLUDE_DIRECTORY//\//\\/}\///")
|
|
EXCLUDE_FILES=$(find ${EXCLUDE_DIRECTORY}/* -type f | sed "s/${EXCLUDE_DIRECTORY//\//\\/}\///")
|
|
fi
|
|
|
|
git checkout ${FROM_BRANCH} -- .rebase/from 1>/dev/null 2>/dev/null
|
|
git checkout ${TO_BRANCH} -- .rebase/to 1>/dev/null 2>/dev/null
|
|
|
|
ADDED_PATHS=$(diff -rq .rebase/to .rebase/from | grep 'Only in .rebase/to' | cut -d ' ' -f3- | sed 's/: /\//g' || true)
|
|
REMOVED_PATHS=$(diff -rq .rebase/to .rebase/from | grep 'Only in .rebase/from' | cut -d ' ' -f3- | sed 's/: /\//g' || true)
|
|
|
|
git reset HEAD 1>/dev/null 2>/dev/null
|
|
git add .rebase/from 1>/dev/null 2>/dev/null
|
|
git commit -m "Add .rebase/from" 1>/dev/null 2>/dev/null
|
|
mv .rebase/from .rebase/from-copy
|
|
mv .rebase/to .rebase/from
|
|
|
|
if [[ -n ${IGNORE_DEPS} ]]; then
|
|
IGNORE_DEPS_DIFF_ARGS=$(echo "${IGNORE_DEPS}" | tr ' ' '\n' | sed 's:\(.*\):\:!.rebase/from/charts/\1/*:g' | xargs)
|
|
else
|
|
unset IGNORE_DEPS_DIFF_ARGS
|
|
fi
|
|
if [[ -n ${EXCLUDE_FILES} ]]; then
|
|
EXCLUDE_FILES_DIFF_ARGS=$(echo "${EXCLUDE_FILES}" | tr ' ' '\n' | sed 's:\(.*\):\:!.rebase/from/\1:g' | xargs)
|
|
else
|
|
unset EXCLUDE_FILES_DIFF_ARGS
|
|
fi
|
|
git diff -- ${IGNORE_DEPS_DIFF_ARGS} ${EXCLUDE_FILES_DIFF_ARGS} > diff.patch
|
|
|
|
git reset HEAD~1
|
|
git checkout -- .
|
|
|
|
sed -i.bak -e "s:diff \(.*\) a/.rebase/from/\(.*\) b/.rebase/from/\(.*\):diff \1 a/${DEST_DIRECTORY}/\2 b/${DEST_DIRECTORY}/\3 :g" diff.patch
|
|
sed -i.bak "s:--- a/.rebase/from/\(.*\):--- a/${DEST_DIRECTORY}/\1:g" diff.patch
|
|
sed -i.bak "s:+++ b/.rebase/from/\(.*\):+++ b/${DEST_DIRECTORY}/\1:g" diff.patch
|
|
sed -i.bak "s:index \(.*\) \(.*\):index \1 100644:g" diff.patch
|
|
rm diff.patch.bak
|
|
|
|
echo "> Applying difference in three-way merge..."
|
|
git apply --reject diff.patch 1>/dev/null 2>/dev/null || true
|
|
for to_path in ${ADDED_PATHS}; do
|
|
from_paths=$(echo ${to_path} | sed "s:.rebase/to:.rebase/from:g")
|
|
[[ -d ${from_paths} ]] && from_paths=$(find ${from_paths} -type f)
|
|
for from_path in ${from_paths}; do
|
|
unset should_continue
|
|
for ignored_dep in ${IGNORE_DEPS}; do
|
|
if echo ${from_path} | grep ".rebase/from/charts/${ignored_dep}" 1>/dev/null 2>/dev/null; then
|
|
should_continue=1;
|
|
break
|
|
fi
|
|
done
|
|
[[ -n ${should_continue} ]] && continue
|
|
chart_path=$(echo ${from_path} | sed "s:.rebase/from:${DEST_DIRECTORY}:g")
|
|
mkdir -p $(dirname ${chart_path})
|
|
cp ${from_path} ${chart_path}
|
|
done
|
|
done
|
|
|
|
for to_path in ${REMOVED_PATHS}; do
|
|
from_paths=$(echo ${to_path} | sed "s:.rebase/to:.rebase/from:g")
|
|
[[ -d ${from_paths} ]] && from_paths=$(find ${from_paths} -type f)
|
|
for from_path in ${from_paths}; do
|
|
unset should_continue
|
|
for ignored_dep in ${IGNORE_DEPS}; do
|
|
if echo ${from_path} | grep ".rebase/from/charts/${ignored_dep}" 1>/dev/null 2>/dev/null; then
|
|
should_continue=1;
|
|
break
|
|
fi
|
|
done
|
|
[[ -n ${should_continue} ]] && continue
|
|
chart_path=$(echo ${from_path} | sed "s:.rebase/from/::g")
|
|
rm ${DEST_DIRECTORY}/${chart_path} 1>/dev/null 2>/dev/null || true
|
|
done
|
|
done
|
|
|
|
|
|
if [ -d "${EXCLUDE_DIRECTORY}" ]; then
|
|
# Move modified excluded files into excludes directory
|
|
for d in ${EXCLUDE_DIRECTORIES}; do
|
|
mkdir -p ${EXCLUDE_DIRECTORY}/${d}
|
|
done
|
|
for f in ${EXCLUDE_FILES}; do
|
|
# the file might be removed in upstream
|
|
if [ -f .rebase/from-copy/${f} ]; then
|
|
mv .rebase/from-copy/${f} ${EXCLUDE_DIRECTORY}/${f}
|
|
fi
|
|
done
|
|
unset EXCLUDE_DIRECTORIES
|
|
unset EXCLUDE_FILES
|
|
fi
|
|
if [ -d "${CRD_CHART_DIRECTORY}" ]; then
|
|
# Move CRDs back back into CRD chart since changes would have been tracked there
|
|
git reset HEAD~1 1>/dev/null 2>/dev/null
|
|
mv ${DEST_DIRECTORY}/crds ${CRD_CHART_DIRECTORY}/${CRDS_DIRECTORY}
|
|
fi
|
|
|
|
rm diff.patch
|
|
rm -rf .rebase
|
|
|
|
# Clean up empty directories from the merge
|
|
find ${DEST_DIRECTORY} -type d -empty -delete 1>/dev/null 2>/dev/null
|
|
|
|
echo ""
|
|
echo "INTERACTIVE REBASE SHELL"
|
|
echo "==="
|
|
echo ""
|
|
echo "The changes have been loaded into your working directory."
|
|
echo ""
|
|
echo "Please look through each file that was changed and remove .rej files using an editor of your choice."
|
|
echo ""
|
|
echo "Once you have manually resolved the .rej files or added any additonal necessary changes, do the following:"
|
|
if [ -d "${CRD_CHART_DIRECTORY}" ]; then
|
|
echo "1) Add all changes to ${DEST_DIRECTORY}, ${EXCLUDE_DIRECTORY}, and ${CRD_CHART_DIRECTORY} to staging (e.g. git add)"
|
|
else
|
|
echo "1) Add all changes to ${DEST_DIRECTORY} and ${EXCLUDE_DIRECTORY} to staging (e.g. git add)"
|
|
fi
|
|
echo "2) Commit all other changes to save them (e.g. 'git add <changes>; git commit -m \"message\"')"
|
|
echo "Note: Any additional commits you make will show up in your branch at the end of the rebase, so committing changes from 'make patch' could be helpful"
|
|
echo ""
|
|
if [ -d "${CRD_CHART_DIRECTORY}" ]; then
|
|
echo "Once you have added all changes to ${DEST_DIRECTORY}, ${EXCLUDE_DIRECTORY} or ${CRD_CHART_DIRECTORY}, exit out of the shell to move to the next commit."
|
|
else
|
|
echo "Once you have added all changes to ${DEST_DIRECTORY} or ${EXCLUDE_DIRECTORY}, exit out of the shell to move to the next commit."
|
|
fi
|
|
echo ""
|
|
echo "To force abort the rebase and discard your changes at any time, run 'abort'"
|
|
set +e
|
|
CURR_DIR=$(pwd)
|
|
bash --rcfile <(echo "PS1='(interactive-rebase-shell) '; alias abort='touch .abort_rebase; exit'") -i
|
|
set -e
|
|
cd ${CURR_DIR} 1>/dev/null 2>/dev/null
|
|
|
|
# Ensure additional commits do not contain changes to DEST_DIRECTORY, EXCLUDE_DIRECTORY, or CRD_CHART_DIRECTORY
|
|
BAD_COMMITS=$(git log --first-parent --oneline ${GC_COMMIT}..HEAD -- ${DEST_DIRECTORY} ${EXCLUDE_DIRECTORY} ${CRD_CHART_DIRECTORY})
|
|
# Ensure that changes are only added or modified to DEST_DIRECTORY, EXCLUDE_DIRECTORY, or CRD_CHART_DIRECTORY
|
|
BAD_CHANGES=$(
|
|
git status --porcelain \
|
|
| grep -v "A ${DEST_DIRECTORY}" \
|
|
| grep -v "M ${DEST_DIRECTORY}" \
|
|
| grep -v "R ${DEST_DIRECTORY}" \
|
|
| grep -v "D ${DEST_DIRECTORY}" \
|
|
| grep -v "A ${EXCLUDE_DIRECTORY}" \
|
|
| grep -v "M ${EXCLUDE_DIRECTORY}" \
|
|
| grep -v "R ${EXCLUDE_DIRECTORY}" \
|
|
| grep -v "D ${EXCLUDE_DIRECTORY}" \
|
|
| grep -v "A ${CRD_CHART_DIRECTORY}" \
|
|
| grep -v "M ${CRD_CHART_DIRECTORY}" \
|
|
| grep -v "R ${CRD_CHART_DIRECTORY}" \
|
|
| grep -v "D ${CRD_CHART_DIRECTORY}" \
|
|
| tee
|
|
)
|
|
|
|
set +e
|
|
GIT_REJ_CHECK=$(git diff --staged --name-only | grep ".rej")
|
|
if [[ -n ${GIT_REJ_CHECK} ]]; then
|
|
GIT_REJ_CHECK_DIFF_ARGS=$(echo "${GIT_REJ_CHECK}" | tr ' ' '\n' | sed "s:\(.*\):\:!\1:g" | xargs)
|
|
else
|
|
unset GIT_REJ_CHECK_DIFF_ARGS
|
|
fi
|
|
GIT_DIFF_CHECK=$(git diff --staged --check -- ${GIT_REJ_CHECK_DIFF_ARGS} ${EXCLUDE_FILES_DIFF_ARGS} || true)
|
|
set -e
|
|
|
|
# Loop back through shell until the developer resolves all conflicts
|
|
while [ -n "${BAD_COMMITS}" ] || [ -n "${BAD_CHANGES}" ] || [[ -n "${GIT_DIFF_CHECK}" ]]; do
|
|
echo ""
|
|
if [ -f .abort_rebase ]; then
|
|
rm .abort_rebase
|
|
echo "Detected ABORT_REBASE has been set. Exiting..."
|
|
exit 1
|
|
fi
|
|
if [ -n "${BAD_COMMITS}" ]; then
|
|
echo "ERROR: Detected the following commits that violate rebase guidelines:"
|
|
echo "${BAD_COMMITS}"
|
|
echo ""
|
|
fi
|
|
if [ -n "${BAD_CHANGES}" ]; then
|
|
echo "ERROR: Detected the following changes that violate rebase guidelines:"
|
|
echo "${BAD_CHANGES}"
|
|
echo ""
|
|
fi
|
|
if [ -n "${GIT_DIFF_CHECK}" ]; then
|
|
echo "ERROR: Detected unresolved issues in git diff --staged --check:"
|
|
echo "${GIT_DIFF_CHECK}"
|
|
echo ""
|
|
fi
|
|
if [ -n "${GIT_REJ_CHECK}" ]; then
|
|
echo "ERROR: Detected unresolved .rej files in staging:"
|
|
echo "${GIT_REJ_CHECK}"
|
|
echo ""
|
|
fi
|
|
echo "Only changes to ${DEST_DIRECTORY}, ${EXCLUDE_DIRECTORY}, or ${CRD_CHART_DIRECTORY} should be in staging. All other changes should be committed."
|
|
echo ""
|
|
echo "Please modify the commits and try again."
|
|
echo ""
|
|
echo "To force abort the rebase and discard your changes at any time, run 'abort'"
|
|
set +e
|
|
bash --rcfile <(echo "PS1='(interactive-rebase-shell) '; alias abort='touch .abort_rebase; exit'") -i
|
|
set -e
|
|
# Ensure additional commits do not contain changes to DEST_DIRECTORY, EXCLUDE_DIRECTORY, or CRD_CHART_DIRECTORY
|
|
BAD_COMMITS=$(git log --first-parent --oneline ${GC_COMMIT}..HEAD -- ${DEST_DIRECTORY} ${EXCLUDE_DIRECTORY} ${CRD_CHART_DIRECTORY})
|
|
# Ensure that changes are only added or modified to DEST_DIRECTORY, EXCLUDE_DIRECTORY, or CRD_CHART_DIRECTORY
|
|
BAD_CHANGES=$(
|
|
git status --porcelain \
|
|
| grep -v "A ${DEST_DIRECTORY}" \
|
|
| grep -v "M ${DEST_DIRECTORY}" \
|
|
| grep -v "R ${DEST_DIRECTORY}" \
|
|
| grep -v "D ${DEST_DIRECTORY}" \
|
|
| grep -v "A ${EXCLUDE_DIRECTORY}" \
|
|
| grep -v "M ${EXCLUDE_DIRECTORY}" \
|
|
| grep -v "R ${EXCLUDE_DIRECTORY}" \
|
|
| grep -v "D ${EXCLUDE_DIRECTORY}" \
|
|
| grep -v "A ${CRD_CHART_DIRECTORY}" \
|
|
| grep -v "M ${CRD_CHART_DIRECTORY}" \
|
|
| grep -v "R ${CRD_CHART_DIRECTORY}" \
|
|
| grep -v "D ${CRD_CHART_DIRECTORY}" \
|
|
| tee
|
|
)
|
|
set +e
|
|
GIT_REJ_CHECK=$(git diff --staged --name-only | grep ".rej")
|
|
if [[ -n ${GIT_REJ_CHECK} ]]; then
|
|
GIT_REJ_CHECK_DIFF_ARGS=$(echo "${GIT_REJ_CHECK}" | tr ' ' '\n' | sed "s:\(.*\):\:!\1:g" | xargs)
|
|
else
|
|
unset GIT_REJ_CHECK_DIFF_ARGS
|
|
fi
|
|
GIT_DIFF_CHECK=$(git diff --staged --check -- ${GIT_REJ_CHECK_DIFF_ARGS} ${EXCLUDE_FILES_DIFF_ARGS} || true)
|
|
set -e
|
|
done
|
|
|
|
# Merge current staged changes into the GC_COMMIT directly, ignoring any other commits added by the user
|
|
# Then set the GC_COMMIT once more since the commit hash has changed
|
|
NUM_USER_COMMITS=$(git rev-list --count ${GC_COMMIT}..HEAD)
|
|
git commit --fixup "${GC_COMMIT}" 1>/dev/null 2>/dev/null && GIT_SEQUENCE_EDITOR=true git rebase --interactive --autosquash "${GC_COMMIT}^" 1>/dev/null 2>/dev/null
|
|
GC_COMMIT=$(git rev-parse --short HEAD~${NUM_USER_COMMITS})
|
|
|
|
# Run make patch and save all changes that were added to the working directory throughout the rebase
|
|
rm ${CHARTS_ORIGINAL_DIRECTORY} 1>/dev/null 2>/dev/null || true
|
|
PACKAGE=${PACKAGE} USE_CACHE=${USE_CACHE} make patch 1>/dev/null 2>/dev/null
|
|
git add ${GC_DIRECTORY}
|
|
git commit --allow-empty -m "Rebase ${PACKAGE} to ${TO_COMMIT}" 1>/dev/null 2>/dev/null
|
|
|
|
|
|
# Ensure Git is clean
|
|
if [ -n "$(git status --porcelain)" ]; then
|
|
echo "Found unexpected changes after generating final patch post-rebase"
|
|
git status --porcelain
|
|
exit 1
|
|
fi
|
|
|
|
# Cherry pick all changes to the current branch
|
|
COMMITS=$(git log --first-parent --oneline ${GC_COMMIT}..HEAD | cut -d' ' -f1 | tail -r)
|
|
echo ""
|
|
echo "Applying the following commits to your current branch:"
|
|
echo ""
|
|
echo "$(git log --first-parent --oneline ${GC_COMMIT}..HEAD)"
|
|
|
|
git checkout ${CURRENT_BRANCH} 1>/dev/null 2>/dev/null
|
|
for commit in ${COMMITS}; do
|
|
git cherry-pick --allow-empty -m 1 ${commit} 1>/dev/null 2>/dev/null || git commit --allow-empty 1>/dev/null 2>/dev/null
|
|
done
|
|
|
|
echo ""
|
|
echo ">> Modifying the package.yaml and finishing up rebase..."
|
|
PACKAGE=${PACKAGE} USE_CACHE=${USE_CACHE} make prepare 1>/dev/null 2>/dev/null
|
|
yq e -i ".url = \"${TO_REMOTE}\"" ${PACKAGE_YAML_PATH} 1>/dev/null 2>/dev/null
|
|
yq e -i ".commit = \"${TO_COMMIT}\"" ${PACKAGE_YAML_PATH} 1>/dev/null 2>/dev/null
|
|
if [[ ${TO_DIR} != "." ]]; then
|
|
yq e -i ".subdirectory = \"${TO_DIR}\"" ${PACKAGE_YAML_PATH} 1>/dev/null 2>/dev/null
|
|
fi
|
|
PACKAGE=${PACKAGE} USE_CACHE=${USE_CACHE} make patch 1>/dev/null 2>/dev/null
|
|
PACKAGE=${PACKAGE} USE_CACHE=${USE_CACHE} make clean 1>/dev/null 2>/dev/null
|
|
git add ${GC_DIRECTORY} ${PACKAGE_YAML_PATH}
|
|
git commit --allow-empty -m "Update ${PACKAGE} to new base ${TO_COMMIT}" 1>/dev/null 2>/dev/null
|
|
|
|
echo ""
|
|
echo "Hooray! The rebase is complete."
|