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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
|
#!/usr/bin/env bash
TEMP=$(getopt -o hvdymr: --long help,verbose,debug,submodule,remote:,visibility: \
-n 'javawrap' -- "$@")
if [ $? != 0 ]; then
echo "Terminating..." >&2
exit 1
fi
if ! git rev-parse --is-inside-work-tree &>/dev/null; then
echo "Must be run inside a git repository" >&2
exit 1
fi
eval set -- "$TEMP"
SCRIPT="$(basename $0)"
read -r -d '' USAGE <<-EOF
USAGE: $SCRIPT [OPTIONS]
OPTIONS:
-h, --help Show this message
-v, --verbose Show more output
-d, --debug NOT IMPLEMENTED
-y, --confirm Do not prompt for confirmation
-m, --submodule
Migrate directory in original repository to submodule
-r, --remote=<user/repo>
Github remote, defaults to $(git config user.username)/${directory}
--private
Create the new remote repository as private. It is created
as public if ommited
ARGS:
<DIRECTORY>... Directory to split out of original repository,
defaults to current directory
EOF
VERBOSE=false
DEBUG=false
CONFIRMED=false
SUBMODULE=false
REPO=$(git rev-parse --show-toplevel)
DIRECTORY="$(basename $(git rev-parse --show-prefix))"
REMOTE="$(basename $DIRECTORY)/$(git config user.username)"
VISIBILITY="--public"
while true; do
case "$1" in
-h | --help)
echo "$USAGE"
exit 0
;;
-v | --verbose)
VERBOSE=true
shift
;;
-d | --debug)
DEBUG=true
shift
;;
-y)
CONFIRMED=true
shift
;;
-m | --submodule)
SUBMODULE=true
shift
;;
-r | --remote)
REMOTE="$2"
shift 2
;;
--public | --private)
VISIBILITY="$1"
shift
;;
--)
shift
break
;;
*)
DIRECTORY="$2"
shift
break
;;
esac
done
if [[ "$REMOTE" = "$(basename $DIRECTORY)/$(git config user.username)" && $? -ne 0 ]]; then
echo "ERROR: No remote provided and user.username was not set." >&2
echo "$USAGE"
exit 1
fi
cd $REPO
git subtree split -P $DIRECTORY -b $DIRECTORY
cd "$(mktemp -d)"
git init && git pull $REPO $DIRECTORY && git branch -M main
files=(".gitignore" ".gitattributes" ".vscode" "LICENSE")
for f in "${files[@]}"; do
if [ ! -e "./${f}" && -e "${REPO}/${f}" ]; then
printf '%s\n' "Copying ${f} to new repository..."
cp -r "${REPO}/${f}" ./
fi
done
git add -A && git commit -m "split out $DIRECTORY into submodule"
# TODO check if remote already exists
if command -v gh &>/dev/null; then
yes "n" | gh repo create --confirm "${REMOTE}" "${VISIBILITY}"
else
printf '%s\n' 'gh cli tool could not be found. Explicitly adding git remote to your local repository.'
git remote add origin https://github.com/${REMOTE}
fi
if git ls-remote git@github.com:${REMOTE} &>/dev/null; then
git push -u origin main
else
printf '%s\n' 'Remote repository not found.'
fi
if [ $? -ne 0 ]; then
printf '\n%s\n' 'Verify/create the remote repository and push to it with the following command: '
printf '\n\t%s%s%s\n\n' '`cd ' "$(pwd)" ' && git push -u origin main`'
printf '\t%s\n' \
'*********************************************************************************' \
'* The new repository was created in a temp directory! *' \
'* If the local repository is not pushed to remote, it will be lost on reboot. *' \
'*********************************************************************************'
else
tempdir="$(pwd)"
cd "$REPO"
rm -rf "$tempdir"
fi
# Migrate to submodule
if [ "$SUBMODULE" != true ]; then
exit 0
fi
# TODO fix and remove warning
printf 'Migrating the original subdirectory to submodule.\n'
if [ "$QUIET" != true ]; then
printf '\t%s\n' \
'*************************************************************************************' \
'* THIS IS NOT TESTED AND HAS A POSSIBLY OF DATA LOSS! *' \
'* *' \
'* This runs `git rm -rf` and `rm -rf` on the original subdirectory. *' \
'* Double check you succesfully migrated the subdirectory to the new repository. *' \
'*************************************************************************************'
fi
if [ "$CONFIRMED" != true ]; then
read -p "Proceed? (Y/n) " -n 1 -r
printf '\n'
if [[ $REPLY =~ ^[Yy]$ ]]; then
CONFIRMED=true
else
[[ "$0" = "$BASH_SOURCE" ]] && exit 1 || return 1
fi
fi
cd $REPO
git rm -rf $DIRECTORY
rm -rf $DIRECTORY
git submodule add git@github.com:$REMOTE $DIRECTORY
git submodule update --init --recursive
git commit -m "split out $DIRECTORY into submodule"
if [ $? -ne 0 ]; then
printf '%s\n' 'Submodule succesfully added. Be sure to `git push -u origin main` after verifing the migration.'
fi
|