Last active
October 23, 2020 02:21
-
-
Save lloeki/37044e3f28812ce4ced0d9924a65172f to your computer and use it in GitHub Desktop.
Merge repos and keep whole history by creating a single multi-parent merge commit
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
#!/bin/bash | |
set -e | |
set -u | |
set -o pipefail | |
prefix="[email protected]:mygroup" | |
target="$1" | |
shift | |
repos="$*" | |
if [[ -z $repos ]]; then | |
echo "usage: $0 repo [repo ...]" 1>&2 | |
exit 1 | |
fi | |
# clone locally as cache | |
for repo in $repos; do | |
if [[ ! -d cache/$repo ]]; then | |
git clone "$prefix/$repo.git" "cache/$repo" | |
fi | |
done | |
rm -rf "$target" | |
# make a repo with each source as remote | |
git init "$target" | |
cd "$target" | |
for repo in $repos; do | |
git remote add "$repo" "$PWD/../cache/$repo" | |
done | |
for repo in $repos; do | |
git fetch --no-tags "$repo" | |
done | |
# checkout each one in a subdir and make a commit on a dedicated branch materialising the move to subdir on each | |
for repo in $repos; do | |
mkdir -p "$repo" | |
git --work-tree="$repo" checkout "$repo"/master | |
git checkout -b "$repo" | |
git add . | |
git commit -m "Move $repo into subdir" | |
git checkout --orphan master | |
git reset --hard | |
rm -rf "$repo" | |
done | |
p_args="$(echo "$repos" | perl -ne 's/ /\n/g and print' | perl -ne '/(.*)/ and { print "-p " and system("git rev-parse $1") }' | xargs echo)" | |
# checkout all of them in a subdir | |
for repo in $repos; do | |
mkdir -p "$repo" | |
git --work-tree="$repo" checkout "$repo"/master | |
done | |
# make a merge commit of all dedicated move branches | |
git checkout --orphan master | |
git reset | |
git add . | |
tree=$(git write-tree) | |
echo "$p_args" | |
commit=$(git commit-tree "$tree" $p_args -m "Merge of $(echo "$repos" | wc -w | sed 's/ //g') repos $(echo -e "\n"; echo "$repos" | perl -ne 's/ /\n/g and print')") | |
git reset --hard "$commit" | |
# finalize | |
git remote add origin "$prefix/$target" | |
git fetch --no-tags origin | |
git branch -u origin/master |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment