Last active
August 29, 2015 14:27
-
-
Save azell/c32bc194c83a66ec6603 to your computer and use it in GitHub Desktop.
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 | |
function avoid_conflict { | |
if [ -f "$1" ]; then | |
git checkout "$2" | |
git mv "$1" "$3/" | |
git commit -am 'Move file into subdirectory.' | |
fi | |
} | |
function base { | |
basename "$1" .git | |
} | |
function clone { | |
[ -d $(base "$1") ] || git clone -b "$2" "$1" | |
} | |
function clone_branches { | |
for branch in $(git branch -r | grep -vw -- '->'); do | |
[ "$branch" = "origin/$1" ] || git checkout --track "$branch" | |
done | |
} | |
function push_down { | |
git filter-branch -f --prune-empty --tree-filter "mkdir .tmp; | |
mv * .tmp; | |
mv .tmp \"$1\" | |
" -- --glob='refs/heads/*' | |
} | |
function track_branches { | |
for branch in $(git branch -r | grep -vw -- '->'); do | |
git checkout -b "$branch" --track "$branch" | |
done | |
} | |
# | |
# New super repo | |
parent='path/to/parent.git' | |
parent_branch=master | |
# | |
# Old silo repos | |
children='path/to/first/child.git | |
path/to/second/child.git' | |
child_branch=master | |
# | |
# Clone all repos at the same level | |
clone "$parent" "$parent_branch" | |
for child in $children; do | |
clone "$child" "$child_branch" | |
done | |
# | |
# Create the child directory and push content down one level | |
for child in $children; do | |
proj=$(base "$child") | |
cd "$proj" | |
clone_branches "$child_branch" | |
push_down "$proj" | |
# | |
# Prevent conflicts | |
avoid_conflict .gitignore "$child_branch" "$proj" | |
avoid_conflict .pairs "$child_branch" "$proj" | |
git gc --aggressive | |
cd - | |
done | |
path="$(pwd)" | |
cd $(base "$parent") | |
# | |
# Add the local repos to the new parent | |
for child in $children; do | |
proj=$(base "$child") | |
git remote add "$proj" "$path/$proj" | |
done | |
git fetch --all | |
track_branches | |
git checkout "$parent_branch" | |
for child in $children; do | |
proj=$(base "$child") | |
git merge --no-edit "$proj/$child_branch" | |
git remote rm "$proj" | |
done | |
# | |
# The new parent is ready for action | |
git gc --aggressive | |
git push --all |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Attempt at reusing logic from http://stackoverflow.com/questions/15477379/merge-two-git-repos-into-one-without-renaming-files/15517913#15517913.