-
Notifications
You must be signed in to change notification settings - Fork 7
/
git-helper.sh
executable file
·449 lines (400 loc) · 14.5 KB
/
git-helper.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
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
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
#!/bin/bash
# Prints the name of the current local branch.
function git_current_branch {
# "git branch" prints a list of local branches, the current one being marked with a "*". Extract it.
echo "`git branch | grep '*' | sed 's/* //'`"
}
# Prints the name of the remote branch (subversion trunk, branch or tag) tracked by the current local branch.
function git_current_remote_branch {
# This is the current remote URL corresponding to the local branch
current_url=`git svn info --url`
# Obtain the URL parts corresponding to the base repository address, and the prefixes for the trunk, the branches, and the tags
base_url=`git config --list | grep "svn-remote.svn.url" | cut -d '=' -f 2`
trunk_url=$base_url/`git config --list | grep "svn-remote.svn.fetch" | cut -d '=' -f 2 | sed 's/:.*//'`
branches_url=$base_url/`git config --list | grep branches | sed 's/.*branches=//' | sed 's/*:.*//'`
tags_url=$base_url/`git config --list | grep tags | sed 's/.*tags=//' | sed 's/*:.*//'`
# Check if the current URL matches the trunk URL
if [ $trunk_url == $current_url ]; then
if [ "$1" == "-s" ]; then
echo "trunk"
else
echo "You are on trunk"
fi
# ...or has the branches URL as a prefix
elif [ `echo $current_url | grep $branches_url` ]; then
# Escape / in order to use the URL as a regular expression in sed
escaped_prefix=`echo $branches_url | sed 's/\//\\\\\//g'`
if [ "$1" == "-s" ]; then
echo `echo $current_url | sed "s/$escaped_prefix//"`
else
echo You are on branch `echo $current_url | sed "s/$escaped_prefix//"`
fi
# ...or has the tags URL as a prefix
elif [ `echo $current_url | grep $tags_url` ]; then
# Escape / in order to use the URL as a regular expression in sed
escaped_prefix=`echo $tags_url | sed 's/\//\\\\\//g'`
if [ "$1" == "-s" ]; then
echo `echo $current_url | sed "s/$escaped_prefix//"`
else
echo You are on tag `echo $current_url | sed "s/$escaped_prefix//"`
fi
else
if [ "$1" == "-s" ]; then
echo "unknown"
else
echo "You are on an unknown remote branch"
fi
fi
}
# Merge the changes from the current branch into another branch (either an existing local branch or a remote branch) and
# commit them to the remote server. After that, switch back to the original branch.
function git_svn_transplant_to {
current_branch=`git_current_branch`
git checkout $1 && git merge $current_branch && git svn dcommit && git checkout $current_branch
}
# Remove a remote branch from the central server. Equivalent of "svn remove <branch> && svn commit".
function git_svn_remove_branch {
# Compute the location of the remote branches
svnremote=`git config --list | grep "svn-remote.svn.url" | cut -d '=' -f 2`
branches=$svnremote/`git config --list | grep branches | sed 's/.*branches=//' | sed 's/*:.*//'`
if [ "$2" == "-f" ]; then
# Remove the branch using svn
svn rm "$branches$1" -m "Removing branch $1"
else
echo "Would remove branch $branches$1"
echo "To actually remove the branch, use:"
echo " ${FUNCNAME[0]} $1 -f"
fi
}
# Remove a remote tag from the central server. Equivalent of "svn remove <tag> && svn commit".
# Note that removing tags is not recommended.
function git_svn_remove_tag {
svnremote=`git config --list | grep "svn-remote.svn.url" | cut -d '=' -f 2`
tags=$svnremote/`git config --list | grep tags | sed 's/.*tags=//' | sed 's/*:.*//'`
if [ "$2" == "-f" ]; then
svn rm "$tags$1" -m "Removing tag $1"
else
echo "Would remove tag $tag$1"
echo "To actually remove the tag, use:"
echo " ${FUNCNAME[0]} $1 -f"
fi
}
# Create a remote svn branch from the currently tracked one, and check it out in a new local branch.
function git_svn_create_branch {
# Compute the location of the remote branches
svnremote=`git config --list | grep "svn-remote.svn.url" | cut -d '=' -f 2`
branches=$svnremote/`git config --list | grep branches | sed 's/.*branches=//' | sed 's/*:.*//'`
destination=$branches$1
# Determine the current remote branch (or trunk)
current=`git svn info --url`
if [ "$2" == "-n" ]; then
echo " ** Dry run only ** "
echo "svn cp $current $destination -m \"creating branch\""
echo "git svn fetch"
echo "git branch --track svn-$1 $1"
echo "git checkout svn-$1"
else
svn cp $current $destination -m "creating branch"
git svn fetch
git branch --track svn-$1 $1
git checkout svn-$1
fi
echo "Created branch $1 at $destination (locally svn-$1)"
}
# Create a remote svn tag from the currently tracked branch/trunk.
function git_svn_create_tag {
if [ "$2" == "-n" ]; then
echo " ** Dry run only ** "
fi
# Determine the name of the current remote branch (or trunk)
source=`git_current_remote_branch -s`
# Determine if there are local changes that are not pushed to the central server
if ((git svn dcommit -n > /dev/null 2> /dev/null) && [[ "`git svn dcommit -n 2> /dev/null | grep diff-tree | wc -l`" == "0" ]]); then
echo "Using $source as the source branch to tag"
else
echo "Local branch contains changes, please push to the svn repository or checkout a clean branch."
return 1
fi
# Compute the location of the remote tags
svnremote=`git config --list | grep "svn-remote.svn.url" | cut -d '=' -f 2`
tags=$svnremote/`git config --list | grep tags | sed 's/.*tags=//' | sed 's/*:.*//'`
destination=$tags$1
# Determine the remote URL of the current branch
current=`git svn info --url`
if [ "$2" == "-n" ]; then
echo "svn cp $current $destination -m \"creating tag $1 from $source\""
echo "git svn fetch"
echo "Would create tag $1 from $source at $destination"
else
# Create the tag remotely
svn cp $current $destination -m "creating tag $1 from $source"
# Update remote tag names
git svn fetch
echo "Created tag $1 from $source at $destination"
fi
}
# List the remote branches, as known locally by git.
function git_svn_branches {
# List all known remote branches and filter out the trunk (named trunk) and the tags (which contain a / in their name)
git branch -r | cut -d ' ' -f 3 | grep -E -v '^trunk(@.*)?$' | grep -v '/'
}
# List the remote tags, as known locally by git.
function git_svn_tags {
# List all known remote branches and filter only the tags, which contain a / in their name
git branch -r | cut -d ' ' -f 3 | grep '/' | cut -d '/' -f2
}
# Remove from the git references fake trunk remotes pointing to different versions.
# These are created when the codebase was moved on SVN from one location to the other.
# Their names look like "trunk@35107"
function git_svn_prune_trunk {
# List the versioned trunk remotes
to_remove=`git branch -r | grep --color=never 'trunk@'`
# Check each locally known remote branch
for branch in $to_remove; do
if [[ "$1" == "-f" ]]; then
git branch -r -D $branch
else
echo "Would remove $branch"
fi
done
# If this was only a dry run, indicate how to actually prune
if [[ "$1" != "-f" && "$1" != "-q" ]]; then
echo "To actually prune dead versions, use:"
echo " ${FUNCNAME[0]} -f"
fi
}
# Remove branches which no longer exist remotely from the local git references.
function git_svn_prune_branches {
# List the real remote and locally known remote branches
svnremote=`git config --list | grep "svn-remote.svn.url" | cut -d '=' -f 2`
branches=$svnremote/`git config --list | grep branches | sed 's/.*branches=//' | sed 's/*:.*//'`
remote_branches=" `svn ls $branches | sed 's/\/$//'` "
local_branches=`git_svn_branches`
# Check each locally known remote branch
for branch in $local_branches; do
found=0
# Search it in the list of real remote branches
for rbranch in $remote_branches; do
if [[ $branch == $rbranch ]]; then
found=1
fi
done
# If not found, remove it
if [[ $found == 0 ]]; then
if [[ "$1" == "-f" ]]; then
git branch -r -D $branch
else
echo "Would remove $branch"
fi
fi
done
# If this was only a dry run, indicate how to actually prune
if [[ "$1" != "-f" && "$1" != "-q" ]]; then
echo "To actually prune branches, use:"
echo " ${FUNCNAME[0]} -f"
fi
}
# Remove tags which no longer exist remotely from the local git references.
function git_svn_prune_tags {
# List the real remote and locally known remote tags
svnremote=`git config --list | grep "svn-remote.svn.url" | cut -d '=' -f 2`
tags=`git config --list | grep tags | sed 's/.*tags=//' | sed 's/*:.*//'`
remote_tags=" `svn ls $svnremote/$tags | sed 's/\/$//'` "
local_tags=`git_svn_tags`
# Check each locally known remote tag
for tag in $local_tags; do
found=0
# Search it in the list of real remote tags
for rtag in $remote_tags; do
if [[ $tag == $rtag ]]; then
found=1
fi
done
# If not found, remove it
if [[ $found == 0 ]]; then
if [[ "$1" == "-f" ]]; then
git branch -r -D tags/$tag
else
echo "Would remove tags/$tag"
fi
fi
done
# If this was only a dry run, indicate how to actually prune
if [[ "$1" != "-f" && "$1" != "-q" ]]; then
echo "To actually prune tags, use:"
echo " ${FUNCNAME[0]} -f"
fi
}
function git_svn_prune_remotes {
git_svn_prune_trunk ${1:--q}
git_svn_prune_branches ${1:--q}
git_svn_prune_tags ${1:--q}
# If this was only a dry run, indicate how to actually prune
if [[ "$1" != "-f" ]]; then
echo "To actually prune dead remotes, use:"
echo " ${FUNCNAME[0]} -f"
fi
}
function git_svn_up {
git stash && git svn rebase && git stash pop
}
function git_svn_convert_tags {
#!/bin/sh
#
# git_svn_convert_tags
# Convert Subversion "tags" into Git tags
for tag in `git branch -r | grep " tags/" | sed 's/ tags\///'`; do
GIT_COMMITTER_DATE="$(git log -1 --pretty=format:"%ad" tags/"$tag")"
GIT_COMMITTER_EMAIL="$(git log -1 --pretty=format:"%ce" tags/"$tag")"
GIT_COMMITTER_NAME="$(git log -1 --pretty=format:"%cn" tags/"$tag")"
GIT_MESSAGE="$(git log -1 --pretty=format:%s%n%b tags/"$tag")"
git tag -m "$GIT_MESSAGE" $tag refs/remotes/tags/$tag
git branch -rd "tags/""$tag"
done
}
# Create a git branch for each remote SVN branch
function git_svn_convert_branches {
for branch in `git_svn_branches`; do
git branch "${branch}" "remotes/${branch}"
git branch -rD "${branch}"
done
}
# Remove tags that match the provided regular expression (Perl syntax).
# The first parameter is mandatory and must be a regular expression of tag names to remove.
# Only do a dry run, printing what would be removed, if the second parameter is missing or is not "-f"
function git_svn_filter_tags {
svn_tags=`git_svn_tags`
git_tags=`git tag`
# Check each remote tag
for tag in $svn_tags ; do
found=`echo $tag | grep -P $1`
# If it matches, remove it
if [[ -n $found ]]; then
if [[ "$2" == "-f" ]]; then
git branch -D -r tags/$tag
else
echo "Would remove remote tags/$tag"
fi
fi
done
# Check each git tag
for tag in $git_tags ; do
found=`echo $tag | grep -P $1`
# If it matches, remove it
if [[ -n $found ]]; then
if [[ "$2" == "-f" ]]; then
git tag -d $tag
else
echo "Would remove tag $tag"
fi
fi
done
# If this was only a dry run, indicate how to actually prune
if [[ "$2" != "-f" && "$2" != "-q" ]]; then
echo "To actually remove tags, use:"
echo " ${FUNCNAME[0]} $1 -f"
fi
}
# Remove branches that match the provided regular expression (Perl syntax).
# The first parameter is mandatory and must be a regular expression of branch names to remove.
# Only do a dry run, printing what would be removed, if the second parameter is missing or is not "-f"
function git_svn_filter_branches {
svn_branches=`git_svn_branches`
git_branches=`git branch`
# Check each remote branch
for branch in $svn_branches ; do
found=`echo $branch | grep -P $1`
# If it matches, remove it
if [[ -n $found ]]; then
if [[ "$2" == "-f" ]]; then
git branch -D -r $branch
else
echo "Would remove remote branch $branch"
fi
fi
done
# Check each git branch
for branch in $git_branches ; do
found=`echo $branch | grep -P $1`
# If it matches, remove it
if [[ -n $found ]]; then
if [[ "$2" == "-f" ]]; then
git branch -D $branch
else
echo "Would remove branch $branch"
fi
fi
done
# If this was only a dry run, indicate how to actually prune
if [[ "$2" != "-f" && "$2" != "-q" ]]; then
echo "To actually remove branches, use:"
echo " ${FUNCNAME[0]} $1 -f"
fi
}
function elementExists() {
if [ -z "$1" ]
then
return
fi
for i in ${excluded[@]}
do
if [ $i == $1 ]
then
return 1
fi
done
return 0
}
function git_check_methods {
# set input field separator $IFS to end-of-line
ORIGIFS=$IFS
IFS=`echo -en "\n\b"`
if [ $1 == '-u' ]
then
unused=1;
file=$2
else
unused=0;
file=$1
fi
excluded=( __construct __destruct initialize select update delete setId getId)
for i in `egrep -o "function [A-Za-z0-9_]+\(" $file | awk '{print $2}' | sed 's/($//'`
do
runGrep=1;
for j in ${excluded[@]}
do
if [ $i == $j ]
then
runGrep=0;
fi
done
lines='';
countLines=0
if [ $runGrep -eq 1 ]
then
for line in `git --no-pager grep -i "$i("`
do
let "countLines += 1";
lines="${lines}\n${line}";
done
if [ $unused -eq 1 -a $countLines -eq 1 -o $unused -eq 0 ]
then
echo; echo; echo $i;
echo "------------------------------------";
echo -e $lines;
fi
fi
done
# reset IFS
IFS=$ORIGIFS
}
function git_search_replace {
for i in `git grep -il "$1"`
do
echo $i;
sed -i "s/$1/$2/g" $i
done
}
function git_pick() {
~/bin/git_pick $1 $2
}