-
Notifications
You must be signed in to change notification settings - Fork 1
/
move_to_monorepo.sh
62 lines (48 loc) · 1.75 KB
/
move_to_monorepo.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#!/bin/sh
# Creates a new monorepo by fusing multiple repositories
# Child repositories that are going to be fused
CHILDREN="repo_lib_a repo_lib_b"
# Name of the created monorepo
MONOREPO="monorepo"
# Exit in case of any error
set -e
# Be verbose
set -x
# create the monorepo
mkdir $MONOREPO
cd $MONOREPO
git init
# Create a first commit. A first commit is needed in order to be able to merge into master afterwards
echo "*~" >.placeholder
git add .placeholder
git commit -m "First commit"
git rm .placeholder
git commit -m "Remove placeholder file"
# Add remotes for all children
for repo in $CHILDREN; do
git remote add "$repo" "[email protected]:path/${repo}.git"
done
# Fetch all child repositories
git fetch --all
# Checkout all the master branches of the child repositories
for repo in $CHILDREN; do
git checkout -f -b "${repo}_master" "${repo}/master"
# Rewrite history to move all repo files into a subdirectory
export SUBDIRECTORY="${repo}"
git filter-branch -f --index-filter '
git ls-files -s | sed "s-\t-&${SUBDIRECTORY}/-" | GIT_INDEX_FILE=$GIT_INDEX_FILE.new git update-index --index-info && if [ -f "$GIT_INDEX_FILE.new" ]; then mv "$GIT_INDEX_FILE.new" "$GIT_INDEX_FILE"; fi' --
done
# Switch back to our master branch
git checkout -f master
# Merge all the repositories in our master branch.
for repo in $CHILDREN; do
git merge --no-commit --allow-unrelated-histories "${repo}_master"
git commit -a -m "Merge ${repo} in subdir"
done
# remove all child repo branches and remotes
for repo in $CHILDREN; do
git branch -D "${repo}_master"
git remote remove "${repo}"
done
# prune all history and do an aggressive gc
git reflog expire --expire=now --all && git gc --prune=now --aggressive