Revision control

Copy as Markdown

#!/bin/sh
set -e
set -x
# FIXME: make rename detection configurable and switch to glandium/git-cinnabar:master
CINNABAR_BRANCH=detect-more-renames
SOURCE_REPO_NAME=${SOURCE_REPO##*/}
SOURCE_BRANCH=main
DEST_REPO="$(readlink -f "$1")"
DEST_SUBDIR=mobile/android
SCRIPT_DIR="$(dirname $(readlink -f "$0"))"
EXPRESSIONS_FILE_PATH="${SCRIPT_DIR}/data/message-expressions.txt"
TEMPDIR=$(mktemp -d)
trap "rm -rf ${TEMPDIR}" EXIT
CINNABAR_PATH="${TEMPDIR}/git-cinnabar"
SOURCE_REPO_PATH="${TEMPDIR}/${SOURCE_REPO_NAME}"
setup_temporary_repo() {
git clone "${SOURCE_REPO}" "${SOURCE_REPO_PATH}"
git -C "${SOURCE_REPO_PATH}" config user.email release@mozilla.com
git -C "${SOURCE_REPO_PATH}" config user.name "Mozilla Release Engineering"
}
setup_cinnabar() {
git clone --branch "${CINNABAR_BRANCH}" --depth 1 "${CINNABAR}" "${CINNABAR_PATH}"
make -C "${CINNABAR_PATH}"
}
rewrite_git_history() {
# replace octopus merges with a series of two-parent merges
# commit-filter is called with args "<tree> [-p <parent>]*" and with the commit message on stdin
FILTER_BRANCH_SQUELCH_WARNING=1 \
git -C "${SOURCE_REPO_PATH}" filter-branch \
--force \
--commit-filter \
'if test "$#" -lt 7; then
# 0, 1 or 2 parents, call commit-tree as-is
git commit-tree "$@"
else
# octopus merge, replace it with a series of manual merges
commit_message=$(mktemp)
cat > $commit_message
final_tree="$1"
shift
shift
p1="$1"
shift
part=1
while test "$#" -ge 2; do
shift
p2="$1"
shift
tree=$(git merge-tree --write-tree --allow-unrelated-histories "$p1" "$p2")
p1="$(sed "1s/$/ (part $part)/" $commit_message | git commit-tree "$tree" -p "$p1" -p "$p2")"
part=$((part + 1))
done
rm -f $commit_message
# sanity check that the end result is what we expected
git diff-tree --exit-code $tree $final_tree
echo "$p1"
fi' \
-- "$SOURCE_BRANCH"
# to-subdirectory-filter: move everything to $DEST_SUBDIR
# replace-message: replace references to pull requests with the full URL
python3 ${SCRIPT_DIR}/filter-repo.py \
--source "${SOURCE_REPO_PATH}" \
--target "${SOURCE_REPO_PATH}" \
--force \
--to-subdirectory-filter "$DEST_SUBDIR/" \
--replace-message "$EXPRESSIONS_FILE_PATH" \
--refs "$SOURCE_BRANCH"
}
convert_to_hg() {
PATH="${PATH}:${CINNABAR_PATH}" \
git -C "${SOURCE_REPO_PATH}" \
-c cinnabar.experiments=merge \
push "hg::${DEST_REPO}" "${SOURCE_BRANCH}"
}
setup_cinnabar
setup_temporary_repo
rewrite_git_history
if ! [ -d "${DEST_REPO}" ]; then
hg init "${DEST_REPO}"
fi
convert_to_hg