Skip to content

Instantly share code, notes, and snippets.

@agross
Created January 30, 2019 18:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save agross/2fb08f1b901c5312ffc973faf1891778 to your computer and use it in GitHub Desktop.
Save agross/2fb08f1b901c5312ffc973faf1891778 to your computer and use it in GitHub Desktop.
#!/usr/bin/env bash
# https://help.github.com/articles/about-git-subtree-merges/
set -euo pipefail
red='\e[1;31m'
green='\e[1;32m'
yellow='\e[1;33m'
reset='\e[0m'
source="${1?Need source directory (first arg)}"
target="${2?Need target directory (second arg)}"
git=(git -C "$target")
rm -rf -- "$target"
mkdir -p -- "$target"
"${git[@]}" init
printf '# Override core.autocrlf with a sane defaults.\n* text=auto\n' > "$target/.gitattributes"
cp "$source/NuGet.config" "$target"
"${git[@]}" add .
"${git[@]}" commit --message 'Initial commit'
while IFS= read -d $'\0' -r dotgit; do
dotgit_absolute="$(readlink -f "$dotgit")"
repo="${dotgit%.git}"
branch="$(git -C "$repo" symbolic-ref --short HEAD)"
printf '%b%s%b is checked out at %b%s%b\n' \
"$red" \
"$repo" \
"$reset" \
"$green" \
"$branch" \
"$reset"
target_dir="${repo#$source}"
target_dir="${target_dir##/}"
printf 'Target directory: %b%s%b\n' \
"$yellow" \
"$target_dir" \
"$reset"
"${git[@]}" remote \
add \
--fetch \
temp \
"$dotgit_absolute"
"${git[@]}" merge \
--strategy ours \
--no-commit \
--allow-unrelated-histories \
"temp/$branch"
"${git[@]}" read-tree \
--prefix "$target_dir" \
-u \
"temp/$branch"
"${git[@]}" commit \
--message "Subtree merged in $target_dir"
"${git[@]}" remote rm temp
done < <(find "$source" -mindepth 1 -type d -name .git -print0 | sort --zero-terminated)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment