Skip to content

Instantly share code, notes, and snippets.

@lloeki
Last active October 23, 2020 02:21
Show Gist options
  • Save lloeki/37044e3f28812ce4ced0d9924a65172f to your computer and use it in GitHub Desktop.
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
#!/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