Last active
October 5, 2023 03:11
-
-
Save creasty/cb1b42d21fc85edc0bd41fb335af4b62 to your computer and use it in GitHub Desktop.
Merge two git repositories while perfectly preserving all commit histories
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
set -euo pipefail | |
# shellcheck disable=1091 | |
source "$(dirname "$0")/shared.sh" | |
# Funtions | |
#----------------------------------------------- | |
install_git_filter_repo() { | |
local bin_dir="$TMP_DIR/bin" | |
export PATH="$bin_dir:$PATH" | |
if command -v 'git-filter-repo' > /dev/null 2>&1; then | |
echo "Skipping (already installed)" | |
return 0 | |
fi | |
[ -d "$bin_dir" ] || mkdir -p "$bin_dir" | |
curl -L https://raw.githubusercontent.com/newren/git-filter-repo/main/git-filter-repo -o "$bin_dir/git-filter-repo" | |
chmod +x "$bin_dir/git-filter-repo" | |
} | |
remove_submodule() { | |
local module="$1" | |
subsection "$module" | |
local module_dir="$ROOT_DIR/$module" | |
if ! [ -d "$module_dir" ]; then | |
echo "Skipping (not found)" | |
return 0 | |
fi | |
git -C "$ROOT_DIR" rm --cached "$module_dir" | |
git -C "$ROOT_DIR" config -f "$ROOT_DIR/.git/config" --remove-section "submodule.$module" | |
git -C "$ROOT_DIR" config -f "$ROOT_DIR/.gitmodules" --remove-section "submodule.$module" | |
rm -rf "$module_dir" | |
rm -rf "$ROOT_DIR/.git/modules/$module" | |
git -C "$ROOT_DIR" add -A | |
git -C "$ROOT_DIR" commit -m "Remove submodule: $module" | |
} | |
cleanup_root() { | |
git filter-repo --force --invert-paths \ | |
--path 'general-api' --path 'receipt-api' --path '.gitmodules' | |
} | |
clone_module() { | |
local module="$1" | |
local repo_url="$2" | |
subsection "$module" | |
local module_dir="$TMP_DIR/$module" | |
if [ -d "$module_dir" ]; then | |
echo "Skipping (already cloned)" | |
return 0 | |
fi | |
git clone -b "$WORK_BRANCH" "$repo_url" "$module_dir" | |
} | |
hoist_module() { | |
local module="$1" | |
local module_dir="$TMP_DIR/$module" | |
subsection "$module: Rewriting histories" | |
if [ -d "$module_dir/$module" ]; then | |
echo "Skipping (already rewritten)" | |
else | |
git -C "$module_dir" filter-repo --path-rename ":$module/" --tag-rename ":$module-" | |
fi | |
subsection "$module: Updating remote" | |
git -C "$ROOT_DIR" remote remove "$module" || echo "Ignored" | |
git -C "$ROOT_DIR" remote add -f "$module" "$module_dir" | |
subsection "$module: Merging" | |
git -C "$ROOT_DIR" merge --allow-unrelated-histories "$module/$WORK_BRANCH" | |
} | |
# Main | |
#----------------------------------------------- | |
main() { | |
mkdir -p "$TMP_DIR" | |
section 'Install git-filter-repo' | |
install_git_filter_repo | |
section 'Remove submodules' | |
for_each_repo remove_submodule | |
section 'Clean up root' | |
cleanup_root | |
section 'Clone modules' | |
for_each_repo clone_module | |
section 'Hoist modules' | |
for_each_repo hoist_module | |
} | |
main |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
set -euo pipefail | |
# shellcheck disable=1091 | |
source "$(dirname "$0")/shared.sh" | |
update_submodule() { | |
local module="$1" | |
local module_dir="$ROOT_DIR/$module" | |
subsection "$module" | |
git -C "$module_dir" checkout "$WORK_BRANCH" | |
git -C "$module_dir" pull --ff origin "$WORK_BRANCH" | |
} | |
create_commit() { | |
git -C "$ROOT_DIR" add -A | |
git -C "$ROOT_DIR" commit -m 'Update submodules' | |
} | |
main() { | |
section 'Update submodule' | |
for_each_repo update_submodule | |
section 'Create commit' | |
create_commit | |
} | |
main |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
pull
全ての submodule を最新の monorepo branch でチェックアウトします。
submodule の ref 更新用のコミットも自動で作成します。
finalize