-
Notifications
You must be signed in to change notification settings - Fork 1
/
.git_subtree_funcs
executable file
·222 lines (194 loc) · 4.91 KB
/
.git_subtree_funcs
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
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
gitrc_git_is_clean()
{
if ! git rev-parse --git-dir > /dev/null 2>&1; then
echo "Not in git repository directory"
return 0
fi
if git diff --quiet 2>/dev/null >&2; then
return 0
else
return 1
fi
}
gitrc_git_subtree_add_help()
{
read -d '' help <<- EOF
usage "git st-add <-bbranch> <-aalias> <-pprefix> <-r> REMOTE"
EOF
echo "$help"
}
gitrc_git_subtree_add()
{
if ! git rev-parse --git-dir > /dev/null 2>&1; then
echo "Not in git repository directory"
return 1
fi
OPTIND=1
remote=""
remote_alias=""
prefix=""
branch="master"
dry_run=0
reg_only=0
while getopts "a:b:p:nr" opt; do
case "$opt" in
a)
remote_alias=$OPTARG
;;
b)
branch=$OPTARG
;;
p)
prefix=$OPTARG
;;
n)
dry_run=1
;;
r)
reg_only=1
;;
esac
done
shift $((OPTIND - 1))
[ "$1" = "--" ] && shift
remote=$1 && shift
if [ -z "$remote" ]; then
echo "Remote name is empty";
gitrc_git_subtree_add_help;
return 1;
fi
if [ -z "$remote_alias" ]; then
if [[ "$remote" =~ ^.*/([a-zA-Z0-9_-]+)\.git$ ]]; then
remote_alias=${BASH_REMATCH[1]};
else
echo "Failed to parse remote";
return 1;
fi
fi
subtree_prefix=$(git config --local --get subtrees.prefix)
if [ -z "$subtree_prefix" ]; then
echo "WARNING. Subtree prefix is empty. Use gitrc_git_set_default_subtree_prefix to set it";
fi
if [ -z "$prefix" ]; then
prefix=$remote_alias;
fi
if [ $dry_run -ne 0 ]; then
echo "Will store setting for remote $remote alias $remote_alias branch $branch prefix $prefix"
echo "Will run commands:"
echo " git remote add -f $remote_alias $remote"
echo " git subtree add --prefix $subtree_prefix/$prefix $remote_alias $branch --squash"
else
git config --local subtrees.$remote_alias.remote "$remote"
git config --local subtrees.$remote_alias.prefix "$subtree_prefix/$prefix"
git config --local subtrees.$remote_alias.branch "$branch"
if [ $reg_only -ne 0 ]; then
echo "Registered data for subtree alias $remote_alias"
else
repo_dirty=1
if gitrc_git_is_clean; then
repo_dirty=0
fi
pushd `git rev-parse --show-toplevel` > /dev/null 2>&1
if [ $repo_dirty -eq 1 ]; then
echo "Stash uncommitted changes"
git stash
fi
echo "Add remote $remote with alias $remote_alias"
git remote add -f $remote_alias $remote
echo "Add subtree $subtree_prefix/$prefix"
if ! [ -z "$subtree_prefix" ]; then
mkdir -p $subtree_prefix
fi
git subtree add --prefix "$subtree_prefix/$prefix" $remote_alias $branch --squash
if [ $repo_dirty -eq 1 ]; then
echo "Unstash uncommitted changes"
git stash pop
fi
popd > /dev/null 2>&1
fi
fi
}
gitrc_subtree_command()
{
cmd=$1
remote_alias=$2
if [ -z "$remote_alias" ]; then
echo "usage 'git st-$2 remote_alias'";
gitrc_list_subtrees;
return 1;
fi
prefix=$(git config --local --get subtrees.$remote_alias.prefix)
if [ -z "$prefix" ]; then
echo "$prefix was not registered. Pleas use git st-add to add or register a subtree";
return 1;
fi
branch=$(git config --local --get subtrees.$remote_alias.branch)
if [ -z "$branch" ]; then
branch="master"
fi
repo_dirty=1
if gitrc_git_is_clean; then
repo_dirty=0
fi
pushd `git rev-parse --show-toplevel` > /dev/null 2>&1
if [ $repo_dirty -eq 1 ]; then
echo "Stash uncommitted changes"
git stash
fi
_gitrc_git_subtree_${cmd}_impl $remote_alias $prefix $branch
if [ $repo_dirty -eq 1 ]; then
echo "Unstash uncommitted changes"
git stash pop
fi
popd > /dev/null 2>&1
}
_gitrc_git_subtree_pull_impl()
{
# alias prefix branch
git fetch $1
git subtree pull --prefix $2 $1 $3 --squash
}
_gitrc_git_subtree_push_impl()
{
# alias prefix branch
git subtree push --prefix $2 $1 $3
}
gitrc_list_subtrees()
{
echo "Registered subtree aliases"
git config -l | grep "^subtrees.*branch=" | awk -F[.=] -e '{print $2 " (" $4 ")"}'
}
gitrc_git_set_default_subtree_prefix()
{
git config --local subtrees.prefix $1
}
gitrc_git_get_default_subtree_prefix()
{
subtree_prefix=$(git config --local --get subtrees.prefix)
echo "$subtree_prefix"
}
gitrc_git_subtree_prefix()
{
if [[ -z "$1" || "$1" = "--get" ]]; then
gitrc_git_get_default_subtree_prefix
else
gitrc_git_set_default_subtree_prefix $1
fi
}
gitrc_register_aliases()
{
script_name=$1
if [ -z "$script_name" ]; then
echo "Usage";
echo "gitrc_register_aliases <path to .git_subtree_funcs script>";
return 1;
fi
git config --global alias.st-prefix "!bash -c '. $script_name && gitrc_git_subtree_prefix \$@' -"
git config --global alias.st-add "!bash -c '. $script_name && gitrc_git_subtree_add \$@' -"
git config --global alias.st-pull "!bash -c '. $script_name && gitrc_subtree_command pull \$@' -"
git config --global alias.st-push "!bash -c '. $script_name && gitrc_subtree_command push \$@' -"
git config --global alias.st-ls "!bash -c '. $script_name && gitrc_list_subtrees \$@' -"
}
if [ "$1" = "--install" ]; then
gitrc_register_aliases $0
fi