Skip to content

Instantly share code, notes, and snippets.

@robinst
Created November 22, 2024 06:09
Show Gist options
  • Save robinst/97bef229d5440208b97d9a449243bd27 to your computer and use it in GitHub Desktop.
Save robinst/97bef229d5440208b97d9a449243bd27 to your computer and use it in GitHub Desktop.
Merge multiple Git repositories for Advent of Code (AOC) into a single one
#!/bin/bash
# Goal:
# Merge multiple repos into one with a separate subdirectory for each source
# repo and interleaved commit history. Wouldn't work well for repos with a lot
# of merges and parallel history, but should work well for these mostly
# chronological repos.
#
# Inspired from https://dev.to/detunized/git-fu-merge-multiple-repos-with-linear-history-4kci
# With changes:
# - Use git filter-repo instead
set -euo pipefail
repos="2018:https://github.com/robinst/advent-of-code-2018
2019:https://github.com/robinst/advent-of-code-2019
2020:https://github.com/robinst/advent-of-code-2020
2022:https://github.com/robinst/advent-of-code-2022
2023:https://github.com/robinst/advent-of-code-2023"
# Clone and filter all individual repos
for repo in $repos; do
path=${repo%%:*}
url=${repo#*:}
if [ ! -e "$path" ]; then
git clone --mirror "$url" "$path"
(cd "$path" && git filter-repo \
--to-subdirectory-filter "$path" \
--message-callback "return b\"$path: \" + message")
fi
done
rm -rf merged
git init merged
cd merged
# Fetch into merged repo
for repo in $repos; do
path=${repo%%:*}
git fetch ../$path HEAD
git branch $path FETCH_HEAD
done
# Make history linear
for i in $(git log --pretty='%H' --author-date-order --reverse --all); do
GIT_COMMITTER_DATE=$(git log -1 --pretty='%at' $i) git cherry-pick $i
done
cd merged
# Remove inputs from merged repository to store in a separate private repository
git filter-repo --invert-paths \
--path 2019/input \
--path 2020/input \
--path 2022/java/src/test/resources \
--path 2022/swift/Sources/AOC2022/Resources \
--path 2022/src/test/resources \
--path-glob '*/input.txt' \
--force
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment