/
tomono
executable file
·101 lines (87 loc) · 3.15 KB
/
tomono
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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
#!/usr/bin/env bash
set -euo pipefail ${DEBUGSH+-x}
if ((BASH_VERSINFO[0] > 4 || (BASH_VERSINFO[0] == 4 && BASH_VERSINFO[1] >= 4))); then
shopt -s inherit_errexit
fi
# Poor man’s arg parse :/
arg="${1-}"
: "${MONOREPO_NAME:=core}"
case "$arg" in
"")
if [[ -d "$MONOREPO_NAME" ]]; then
>&2 echo "monorepo directory $MONOREPO_NAME already exists"
exit 1
fi
mkdir "$MONOREPO_NAME"
cd "$MONOREPO_NAME"
git init
;;
"--continue")
if [[ ! -d "$MONOREPO_NAME" ]]; then
>&2 echo "Asked to --continue, but monorepo directory $MONOREPO_NAME doesn’t exist"
exit 1
fi
cd "$MONOREPO_NAME"
if git status --porcelain | grep . ; then
>&2 echo "Git status shows pending changes in the repo. Cannot --continue."
exit 1
fi
# There isn’t anything special about --continue, really.
;;
"--help" | "-h" | "help")
cat <<EOF
Usage: tomono [--continue]
For more information, see the documentation at "https://tomono.0brg.net".
EOF
exit 0
;;
*)
>&2 echo "Unexpected argument: $arg"
>&2 echo
>&2 echo "Usage: tomono [--continue]"
exit 1
;;
esac
empty_tree="$(git hash-object -t tree /dev/null)"
# Note this is top-level in the script so it’s reading from the script’s stdin
while IFS=$'\r'"$IFS" read -r repourl reponame repopath; do
if [[ -z "$repopath" ]]; then
repopath="$reponame"
fi
git remote add "$reponame" "$repourl"
git config --add "remote.$reponame.fetch" "+refs/tags/*:refs/tags/$reponame/*"
git config "remote.$reponame.tagOpt" --no-tags
git fetch --atomic "$reponame"
git branch -r --no-color --list "$reponame/*" --format "%(refname:lstrip=3)" | while read -r branch ; do
if ! git show-ref --verify --quiet "refs/heads/$branch"; then
tree="$(git commit-tree \
"$empty_tree" \
-m "Root commit for monorepo branch $branch")"
git branch -- "$branch" "$tree"
fi
git symbolic-ref HEAD "refs/heads/$branch"
git reset -q
git read-tree --prefix "$repopath" "refs/remotes/$reponame/$branch"
tree="$(git write-tree)"
commit="$(git commit-tree \
"$tree" \
-p "$branch" \
-p "refs/remotes/$reponame/$branch" \
-m "Merge $reponame/$branch")"
git reset -q "$commit"
done
done
git checkout .
# Copyright © 2020, 2022, 2023 Hraban Luyat
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, version 3 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.