mirror of
https://github.com/XRPLF/rippled.git
synced 2026-06-03 16:56:48 +00:00
160 lines
4.8 KiB
Bash
Executable File
160 lines
4.8 KiB
Bash
Executable File
#!/bin/bash -e
|
|
|
|
set -o pipefail
|
|
|
|
_usage()
|
|
{
|
|
self=$( basename -- $( echo $0 ) )
|
|
cat << USAGE
|
|
Usage: $self release_branch develop_branch working_branch [new_version]
|
|
|
|
This script is intended to be used to synchronize changes between two
|
|
branches where the "release_branch" has a few insignificant changes (e.g.
|
|
version numbers) compared to the "develop_branch", which has active
|
|
ongoing development. It has not (yet) been tested in scenarios where the
|
|
branches have significantly diverged, or where one has been merged to
|
|
the other.
|
|
|
|
release_branch: Usually a pending release branch, this is the low
|
|
activity branch which needs to be updated from develop_branch.
|
|
|
|
develop_branch: The active development branch.
|
|
|
|
working_branch: This branch will be created from the release_branch to
|
|
have the new commits applied. If it exists, it will be assumed to have
|
|
been created by an earlier invocation, and will be used for
|
|
comparisons instead of release_branch. When the script is done, this
|
|
branch will NOT be pushed. The user must manually push the branch and
|
|
create a pull request.
|
|
|
|
new_version: OPTIONAL. If provided, will update the version string in
|
|
BuildInfo.cpp to this value, and create a version_setting commit.
|
|
|
|
USAGE
|
|
if [[ $# -ne 0 ]]; then
|
|
echo "Error: ${@}"
|
|
echo
|
|
fi
|
|
|
|
exit 1
|
|
}
|
|
|
|
if [[ $# -lt 3 || $# -gt 4 ]]; then
|
|
_usage
|
|
fi
|
|
|
|
release_branch="$1"
|
|
shift
|
|
|
|
develop_branch="$1"
|
|
shift
|
|
|
|
working_branch="$1"
|
|
shift
|
|
|
|
if [[ $# -ne 0 ]]; then
|
|
new_version="$1"
|
|
shift
|
|
fi
|
|
|
|
_run()
|
|
{
|
|
echo
|
|
echo "\$ ${@}"
|
|
"${@}"
|
|
}
|
|
|
|
if git rev-parse --quiet --verify --end-of-options "refs/heads/${working_branch}" > /dev/null; then
|
|
release_branch="${working_branch}"
|
|
_run git checkout "${working_branch}"
|
|
else
|
|
_run git checkout --no-track -B "${working_branch}" "${release_branch}"
|
|
fi
|
|
|
|
|
|
# Fetch if it hasn't been done in a while
|
|
if find "$( git rev-parse --git-dir )/FETCH_HEAD" -type f -mmin +10 | grep -q "FETCH"; then
|
|
_run git fetch --all
|
|
fi
|
|
|
|
temp=$( mktemp )
|
|
|
|
# The "word-diff" option doesn't seem to have any meaningful effect on the output.
|
|
# This may make this script fragile across git versions with differing output formats.
|
|
_run git range-diff --word-diff=porcelain --no-patch --right-only \
|
|
"${release_branch}"..."${develop_branch}" | tee "${temp}"
|
|
|
|
first_commit=$( cat "${temp}" | \
|
|
awk '( $1 == "-:" && $2 ~ /-+/ && $3 == ">" ) { print $5; exit; }' )
|
|
|
|
if [[ "${first_commit}" == "" && "${new_version}" == "" ]]; then
|
|
_usage No divergence found
|
|
exit 1
|
|
fi
|
|
|
|
if [[ "${first_commit}" == "" ]]; then
|
|
echo -e "\nNo divergence found. Continue to update version number"
|
|
else
|
|
echo -e "\nFound first unique commit in ${develop_branch}: ${first_commit}"
|
|
|
|
first_commit=$( git rev-parse --quiet "${first_commit}" )
|
|
|
|
echo "Full commit ID is: ${first_commit}"
|
|
|
|
merge_base=$( git merge-base --octopus "${first_commit}" "${develop_branch}" )
|
|
if [[ "${first_commit}" != "${merge_base}" ]]; then
|
|
echo "Bad first commit: ${first_commit} is not an ancestor of ${develop_branch}"
|
|
exit 1
|
|
fi
|
|
|
|
_run git diff "${first_commit}~" "${release_branch}"
|
|
|
|
read -n 1 -s -p "Does the diff look reasonable? (y to continue / any other key to abort)" continue
|
|
echo
|
|
if [[ ! ( "${continue}" =~ [yY] ) ]]; then
|
|
echo Abort
|
|
exit 1
|
|
fi
|
|
|
|
# Dilemma: if the cherry-pick is interrupted, for example, because of a conflict, the script
|
|
# will abort, and can not easily be resumed. This will prevent the final step(s) from running.
|
|
if ! _run git cherry-pick --empty=drop "${first_commit}~..${develop_branch}"; then
|
|
# Solution: if the cherry-pick is interrupted, run the command again.
|
|
if [[ "${new_version}" != "" ]]; then
|
|
echo
|
|
echo "Cherry pick failed or was interrupted. Resolve issues, finish the"
|
|
echo " cherry pick, then run this script again to with the same parameters"
|
|
echo " to update the version number."
|
|
fi
|
|
exit 1
|
|
fi
|
|
|
|
if [[ "${new_version}" == "" ]]; then
|
|
# If there is no version number change to make, we're done.
|
|
exit 0
|
|
fi
|
|
fi
|
|
|
|
# There should only be one matching file, but loop in case not.
|
|
buildfiles=( $( git ls-files | grep "BuildInfo.cpp" ) )
|
|
|
|
for build in "${buildfiles[@]}"; do
|
|
sed 's/\(^.*versionString =\).*$/\1 "'${new_version}'"/' ${build} > version.cpp && \
|
|
_run diff "${build}" version.cpp && exit 1 || \
|
|
mv -vi version.cpp ${build}
|
|
|
|
git add ${build}
|
|
done
|
|
|
|
_run git commit -S -m "Set version to ${new_version}"
|
|
|
|
_run git log --oneline --first-parent ${release_branch}^..
|
|
|
|
cat << PUSH
|
|
|
|
-------------------------------------------------------------------
|
|
This script will not push to remote. Verify everything is correct,
|
|
then push, and create a PR as described in CONTRIBUTING.md.
|
|
-------------------------------------------------------------------
|
|
PUSH
|