mirror of
https://gitee.com/dgiiot/dgiot.git
synced 2024-12-02 12:18:30 +08:00
203 lines
5.6 KiB
Bash
203 lines
5.6 KiB
Bash
#!/usr/bin/env bash
|
|
|
|
set -euo pipefail
|
|
|
|
# ensure dir
|
|
cd -P -- "$(dirname -- "${BASH_SOURCE[0]}")/../.."
|
|
|
|
CE_BASES=( 'release-v43' 'release-v44' 'main-v4.3' 'main-v4.4' )
|
|
EE_BASES=( 'release-e43' 'release-e44' 'main-v4.3-enterprise' 'main-v4.4-enterprise' )
|
|
|
|
usage() {
|
|
cat <<EOF
|
|
$0 [option]
|
|
|
|
options:
|
|
|
|
-h|--help:
|
|
This script works on one of the branches listed in the -b|--base option below.
|
|
It tries to merge (by default with --ff-only option)
|
|
upstreams branches for the current working branch.
|
|
The uppstream branch of the current branch are as below:
|
|
* v43: [] # no upstream for 4.3 opensource edition
|
|
* e43: [v43] # 4.3 enterprise has 4.3 opensource as upstream
|
|
* v44: [v43] # 4.4 opensource has 4.3 opensource as upstream
|
|
* e44: [e43, v44, v43] # 4.4 enterprise has all the above 3 as upstream
|
|
For e44:
|
|
v43 is an indirect upstream.
|
|
Ideally the merge of v43 should be done through v44 or e43,
|
|
but it does not hurt to apply a direct merge.
|
|
|
|
-b|--base:
|
|
The base branch of current working branch if currently is not
|
|
on one of the following branches.
|
|
${CE_BASES[@]}
|
|
${EE_BASES[@]}
|
|
|
|
-i|--interactive:
|
|
With this option, the script will try to merge upstream
|
|
branches to local working branch interactively.
|
|
That is, there will be git prompts to edit commit messages etc.
|
|
Without this option, the script executes 'git merge' command
|
|
with '--ff-only' option which conveniently pulls remote
|
|
updates if there is any, and fails when fast-forward is not possible
|
|
EOF
|
|
}
|
|
|
|
logerr() {
|
|
echo "$(tput setaf 1)ERROR: $1$(tput sgr0)"
|
|
}
|
|
logwarn() {
|
|
echo "$(tput setaf 3)WARNING: $1$(tput sgr0)"
|
|
}
|
|
|
|
logmsg() {
|
|
echo "INFO: $1"
|
|
}
|
|
|
|
INTERACTIVE='no'
|
|
while [ "$#" -gt 0 ]; do
|
|
case $1 in
|
|
-h|--help)
|
|
usage
|
|
exit 0
|
|
;;
|
|
-i|--interactive)
|
|
shift
|
|
INTERACTIVE='yes'
|
|
;;
|
|
-b|--base)
|
|
shift
|
|
BASE_BRANCH="$1"
|
|
shift
|
|
;;
|
|
*)
|
|
logerr "Unknown option $1"
|
|
exit 1
|
|
;;
|
|
esac
|
|
done
|
|
|
|
if [ -f EMQX_ENTERPRISE ]; then
|
|
IS_ENTERPRISE='yes'
|
|
BASE_BRANCHES=( "${EE_BASES[@]}" )
|
|
else
|
|
IS_ENTERPRISE='no'
|
|
BASE_BRANCHES=( "${CE_BASES[@]}" )
|
|
fi
|
|
|
|
CURRENT_BRANCH="$(git branch --show-current)"
|
|
BASE_BRANCH="${BASE_BRANCH:-${CURRENT_BRANCH}}"
|
|
|
|
## check if arg1 is one of the elements in arg2-N
|
|
is_element() {
|
|
local e match="$1"
|
|
shift
|
|
for e in "${@}"; do
|
|
if [ "$e" = "$match" ]; then
|
|
return 0
|
|
fi
|
|
done
|
|
return 1
|
|
}
|
|
|
|
if ! is_element "$BASE_BRANCH" "${BASE_BRANCHES[@]}"; then
|
|
logerr "Cannot work with branch $BASE_BRANCH"
|
|
logerr "The base branch must be one of: ${BASE_BRANCHES[*]}"
|
|
logerr "Change work branch to one of the above."
|
|
logerr "OR: use -b|--base to specify from which base branch is current working branch created"
|
|
exit 1
|
|
fi
|
|
|
|
## Find git remotes to fetch from.
|
|
##
|
|
## NOTE: For enterprise, the opensource repo must be added as a remote.
|
|
## Because not all changes in opensource repo are synced to enterprise repo immediately.
|
|
##
|
|
## NOTE: grep -v enterprise here, but why not to match on full repo name 'emqx/emqx.git'?
|
|
## It's because the git remote does not always end with .git
|
|
GIT_REMOTE_CE="$(git remote -v | grep 'emqx/emqx' | grep -v enterprise | grep fetch | head -1 | awk '{print $1}' || true)"
|
|
if [ -z "$GIT_REMOTE_CE" ]; then
|
|
logerr "Cannot find git remote for emqx/emqx"
|
|
exit 1
|
|
fi
|
|
REMOTES=( "${GIT_REMOTE_CE}" )
|
|
if [ "$IS_ENTERPRISE" = 'yes' ]; then
|
|
GIT_REMOTE_EE="$(git remote -v | grep 'emqx/emqx-enterprise' | grep fetch | head -1 | awk '{print $1}' || true)"
|
|
if [ -z "$GIT_REMOTE_EE" ]; then
|
|
logerr "Cannot find git remote for emqx/emqx-enterprise"
|
|
exit 1
|
|
fi
|
|
REMOTES+=( "$GIT_REMOTE_EE" )
|
|
fi
|
|
|
|
## Fetch the remotes
|
|
for remote in "${REMOTES[@]}"; do
|
|
logwarn "Fetching from remote=${remote} (force tag sync)."
|
|
git fetch "$remote" --tags --force
|
|
done
|
|
|
|
logmsg 'Fetched all remotes'
|
|
|
|
if [ "$INTERACTIVE" = 'yes' ]; then
|
|
MERGE_OPTS=''
|
|
else
|
|
## Using --ff-only to *check* if the remote is already merged
|
|
## Also conveniently merged it in case it's *not* merged but can be fast-forwarded
|
|
## Alternative is to check with 'git merge-base'
|
|
MERGE_OPTS='--ff-only'
|
|
fi
|
|
|
|
## Get the git remote reference of the given 'release-' or 'main-' branch
|
|
remote_ref() {
|
|
local branch="$1"
|
|
if is_element "$branch" "${EE_BASES[@]}"; then
|
|
echo -n "${GIT_REMOTE_EE}/${branch} "
|
|
else
|
|
echo -n "${GIT_REMOTE_CE}/${branch} "
|
|
fi
|
|
}
|
|
|
|
remote_refs() {
|
|
local br
|
|
for br in "${@}"; do
|
|
remote_ref "$br"
|
|
done
|
|
}
|
|
|
|
## Get upstream branches of the given branch
|
|
upstream_branches() {
|
|
local base="$1"
|
|
case "$base" in
|
|
release-v43)
|
|
remote_ref "$base"
|
|
;;
|
|
release-v44)
|
|
remote_refs "$base" 'release-v43'
|
|
;;
|
|
release-e43)
|
|
remote_refs "$base" 'release-v43'
|
|
;;
|
|
release-e44)
|
|
remote_refs "$base" 'release-v44' 'release-e43' 'release-v43'
|
|
;;
|
|
main-v4.3)
|
|
remote_refs "$base" 'release-v43'
|
|
;;
|
|
main-v4.4)
|
|
remote_refs "$base" 'release-v44' 'main-v4.3'
|
|
;;
|
|
main-v4.3-enterprise)
|
|
remote_refs "$base" 'release-e43' 'main-v4.3'
|
|
;;
|
|
main-v4.4-enterprise)
|
|
remote_refs "$base" 'release-e44' 'main-v4.4' 'main-v4.3-enterprise' 'main-v4.3'
|
|
;;
|
|
esac
|
|
}
|
|
|
|
for remote_ref in $(upstream_branches "$BASE_BRANCH"); do
|
|
logmsg "Merging $remote_ref"
|
|
git merge $MERGE_OPTS "$remote_ref"
|
|
done
|