Skip to content

Commit f2195e6

Browse files
committed
Merge branch 'main' into hyperupcall-stale-bot
2 parents 9610199 + 18d1017 commit f2195e6

File tree

18 files changed

+176
-36
lines changed

18 files changed

+176
-36
lines changed

.github/workflows/ci.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,10 @@ jobs:
3636
env:
3737
# NOTE: use env to pass the output in order to avoid possible injection attacks
3838
FILES: "${{ steps.files.outputs.added_modified }}"
39+
- name: Shellcheck
40+
run: shellcheck --severity=error bin/* ./*.sh
3941
- name: Lint and format Python with Ruff
40-
uses: astral-sh/ruff-action@v1
42+
uses: astral-sh/ruff-action@v3
4143

4244
typo:
4345
runs-on: ubuntu-latest

Commands.md

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -280,11 +280,20 @@ usage: git bulk [-g] ([-a]|[-w <ws-name>]) <git command>
280280
git bulk --listall
281281
```
282282

283-
Register a workspace so that `git bulk` knows about it (notice that <ws-root-directory> must be absolute path):
283+
Register a workspace so that `git bulk` knows about it (it will be registered in your `.gitconfig`):
284284

285285
```bash
286286
$ git bulk --addworkspace personal ~/workspaces/personal
287287
```
288+
289+
Notice that `<ws-root-directory>` must be an absolute path (or an environment variable pointing to an absolute path).
290+
In the case of a **single quoted environment variable**, it will be dereferenced at `git-bulk` runtime, suitable for dynamic workspaces (*e.g.*, defined in your `.bashrc`).
291+
As an illustration:
292+
293+
```bash
294+
$ git bulk --addworkspace personal '$PERSONAL_WORKSPACE'
295+
```
296+
288297
With option `--from` the URL to a single repository or a file containing multiple URLs can be added and they will be cloned directly into the workspace. Suitable for the initial setup of a multi-repo project.
289298

290299
```bash

bin/git-bulk

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,14 @@ guardedmode=false
99
singlemode=false
1010
allwsmode=false
1111
quiet=false
12+
no_follow_symlinks=false
13+
no_follow_hidden=false
1214

1315
#
1416
# print usage message
1517
#
1618
usage() {
17-
echo 1>&2 "usage: git bulk [-q|--quiet] [-g] ([-a]|[-w <ws-name>]) <git command>"
19+
echo 1>&2 "usage: git bulk [--no-follow-symlinks] [--no-follow-hidden] [-q|--quiet] [-g] ([-a]|[-w <ws-name>]) <git command>"
1820
echo 1>&2 " git bulk --addworkspace <ws-name> <ws-root-directory> (--from <URL or file>)"
1921
echo 1>&2 " git bulk --removeworkspace <ws-name>"
2022
echo 1>&2 " git bulk --addcurrent <ws-name>"
@@ -111,7 +113,17 @@ function checkWSName () {
111113
# parse out wsname from workspacespec
112114
function parseWsName () {
113115
local wsspec="$1"
116+
# Get the workspace value from its specification in the `.gitconfig`.
117+
# May be an absolute path or a variable name of the form: `$VARNAME`
114118
rwsdir=${wsspec#* }
119+
if [[ ${rwsdir:0:1} == '$' ]]; then
120+
# Dereference the `rwsdir` value which is a variable name.
121+
rwsdir_varname=${rwsdir:1}
122+
rwsdir=${!rwsdir_varname}
123+
if [[ -z "${rwsdir}" ]]; then
124+
echo 1>&2 "error: bad environment variable: $rwsdir_varname" && exit 1
125+
fi
126+
fi
115127
rwsname=${wsspec#*.} && rwsname=${rwsname%% *}
116128
}
117129

@@ -129,7 +141,7 @@ function wsnameToCurrent () {
129141

130142
# helper to check number of arguments.
131143
function allowedargcount () {
132-
if [ "$paramcount" -ne "$1" ] && [ "$paramcount" -ne "$2" ]; then
144+
if [ "$paramcount" -ne "${1:-0}" ] && [ "$paramcount" -ne "${2:-0}" ]; then
133145
echo 1>&2 "error: wrong number of arguments" && usage;
134146
exit 1;
135147
fi
@@ -142,19 +154,30 @@ function executBulkOp () {
142154
listall | while read -r workspacespec; do
143155
parseWsName "$workspacespec"
144156
if [[ -n $wsname ]] && [[ $rwsname != "$wsname" ]]; then continue; fi
145-
eval cd "\"$rwsdir\""
157+
cd "$rwsdir" || exit 1
146158
local actual=$PWD
147159
[ "${quiet?}" != "true" ] && echo 1>&2 "Executing bulk operation in workspace ${inverse}$actual${reset}"
148160

149-
allGitFolders=( $(eval find -L . -name ".git") )
161+
# build `find` flags depending on command-line options
162+
local find_flags=()
163+
if [[ "$no_follow_symlinks" == true ]]; then
164+
find_flags+=(-P)
165+
else
166+
find_flags+=(-L)
167+
fi
168+
# find all git repositories under the workspace on which we want to operate
169+
readarray allGitFolders < <(find "${find_flags[@]}" . -name ".git" 2>/dev/null)
150170

151171
for line in "${allGitFolders[@]}"; do
152172
local gitrepodir=${line::${#line}-5} # cut the .git part of find results to have the root git directory of that repository
153-
eval cd "\"$gitrepodir\"" # into git repo location
173+
cd "$gitrepodir" || exit 1 # into git repo location
154174
local curdir=$PWD
155175
local leadingpath=${curdir#"${actual}"}
156-
guardedExecution "$@"
157-
eval cd "\"$rwsdir\"" # back to origin location of last find command
176+
# do not execute if we do not want to consider a ".git" directory under a hidden directory
177+
if [ $no_follow_hidden = false ] || ! [[ "$leadingpath" =~ "/." ]]; then
178+
guardedExecution "$@"
179+
fi
180+
cd "$rwsdir" || exit 1 # back to origin location of last find command
158181
done
159182
done
160183
}
@@ -172,6 +195,10 @@ while [ "${#}" -ge 1 ] ; do
172195
butilcommand="${1:2}" && break ;;
173196
--removeworkspace|--addcurrent|--addworkspace)
174197
butilcommand="${1:2}" && wsname="$2" && wsdir="$3" && if [ "$4" == "--from" ]; then source="$5"; fi && break ;;
198+
--no-follow-symlinks)
199+
no_follow_symlinks=true ;;
200+
--no-follow-hidden)
201+
no_follow_hidden=true ;;
175202
-a)
176203
allwsmode=true ;;
177204
-g)

bin/git-create-branch

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ then
3939
REMOTE=origin
4040
fi
4141

42-
test -z $BRANCH && echo "branch argument required." 1>&2 && exit 1
42+
test -z "$BRANCH" && echo "branch argument required." 1>&2 && exit 1
4343

4444
if [[ -n $REMOTE ]]
4545
then

bin/git-fork

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ else
6161
# clone forked repo into current dir
6262
git clone "${remote_prefix}${user}/${project}.git" "$project"
6363
# add reference to origin fork so can merge in upstream changes
64-
cd "$project"
64+
cd "$project" || exit
6565
git remote add upstream "${remote_prefix}${owner}/${project}.git"
6666
git fetch upstream
6767
fi

bin/git-guilt

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ do
3131
esac
3232
done
3333

34-
cd "$(git-root)" # cd for git blame
34+
cd "$(git-root)" || exit # cd for git blame
3535
MERGED_LOG=$(git_extra_mktemp)
3636
if [[ $EMAIL == '-e' ]]
3737
then
@@ -44,9 +44,11 @@ for file in $(git diff --name-only "$@")
4444
do
4545
test -n "$DEBUG" && echo "git blame $file"
4646
# $1 - since $2 - until
47+
# shellcheck disable=SC2086
4748
git blame $NOT_WHITESPACE --line-porcelain "$1" -- "$file" 2> /dev/null |
4849
LC_ALL=C sed -n "$PATTERN" | sort | uniq -c | LC_ALL=C sed 's/^\(.\)/- \1/' >> "$MERGED_LOG"
4950
# if $2 not given, use current commit as "until"
51+
# shellcheck disable=SC2086
5052
git blame $NOT_WHITESPACE --line-porcelain "${2-@}" -- "$file" 2> /dev/null |
5153
LC_ALL=C sed -n "$PATTERN" | sort | uniq -c | LC_ALL=C sed 's/^\(.\)/+ \1/' >> "$MERGED_LOG"
5254
done
@@ -71,7 +73,7 @@ END {
7173
printf("%d %s\n", contributors[people], people)
7274
}
7375
}
74-
}' $MERGED_LOG | sort -nr | # only gawk supports built-in sort function
76+
}' "$MERGED_LOG" | sort -nr | # only gawk supports built-in sort function
7577
while read -r line
7678
do
7779
people=${line#* }
@@ -103,7 +105,7 @@ do
103105
do
104106
printf "-"
105107
done
106-
printf "(%s)" $num
108+
printf "(%s)" "$num"
107109
else
108110
for (( i = 0; i > num; i-- ))
109111
do

bin/git-obliterate

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,15 @@ do
99
file="$file"' '"$i"
1010
shift
1111
done
12-
test -n "$*" && range="$*"
12+
test -n "$*" && range=("$@")
1313

1414
test -z "$file" && echo "file required." 1>&2 && exit 1
15-
if [ -z "$range" ]
15+
if [ -z "${range[*]}" ]
1616
then
1717
git filter-branch -f --index-filter "git rm -r --cached ""$file"" --ignore-unmatch" \
1818
--prune-empty --tag-name-filter cat -- --all
1919
else
20-
# don't quote $range so that we can forward multiple rev-list arguments
20+
# $range is an array so that we can forward multiple rev-list arguments
2121
git filter-branch -f --index-filter "git rm -r --cached ""$file"" --ignore-unmatch" \
22-
--prune-empty --tag-name-filter cat -- $range
22+
--prune-empty --tag-name-filter cat -- "${range[@]}"
2323
fi

bin/git-repl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,10 @@ while true; do
4444
esac
4545

4646
if [[ $cmd == !* ]]; then
47+
# shellcheck disable=SC2086
4748
eval ${cmd:1}
4849
elif [[ $cmd == git* ]]; then
50+
# shellcheck disable=SC2086
4951
eval $cmd
5052
else
5153
eval git "$cmd"

bin/git-scp

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ function php_lint()
5959

6060
function _dos2unix()
6161
{
62-
command -v dos2unix > /dev/null && dos2unix $@
62+
command -v dos2unix > /dev/null && dos2unix "$@"
6363
return 0
6464
}
6565

@@ -68,8 +68,8 @@ function _sanitize()
6868
git config --get-all extras.scp.sanitize | while read -r i
6969
do
7070
case $i in
71-
php_lint) php_lint $@;; # git config --global --add extras.scp.sanitize php_lint
72-
dos2unix) _dos2unix $@;; # git config --global --add extras.scp.sanitize dos2unix
71+
php_lint) php_lint "$@";; # git config --global --add extras.scp.sanitize php_lint
72+
dos2unix) _dos2unix "$@";; # git config --global --add extras.scp.sanitize dos2unix
7373
esac
7474
done
7575
return $?
@@ -107,6 +107,7 @@ function scp_and_stage
107107
if [ -n "$list" ]
108108
then
109109
local _TMP=${0///}
110+
# shellcheck disable=SC2086
110111
echo "$list" > "$_TMP" &&
111112
_sanitize $list &&
112113
_info "Pushing to $remote ($(git config "remote.$remote.url"))" &&
@@ -131,7 +132,7 @@ function reverse_scp()
131132
shift
132133

133134
local _TMP=${0///}
134-
echo $@ > "$_TMP" &&
135+
echo "$@" > "$_TMP" &&
135136
rsync -rlDv --files-from="$_TMP" "$(git config "remote.$remote.url")/" ./ &&
136137
rm "$_TMP"
137138
}
@@ -173,8 +174,8 @@ case $(basename "$0") in
173174
git-scp)
174175
case $1 in
175176
''|-h|'?'|help|--help) shift; _test_git_scp; _usage "$@";;
176-
*) scp_and_stage $@;;
177+
*) scp_and_stage "$@";;
177178
esac
178179
;;
179-
git-rscp) reverse_scp $@;;
180+
git-rscp) reverse_scp "$@";;
180181
esac

bin/git-summary

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,16 @@
33

44
cd "$(git root)" || { echo "Can't cd to top level directory";exit 1; }
55

6+
PROJECT_FULL_PATH=
67
SUMMARY_BY_LINE=
78
DEDUP_BY_EMAIL=
89
MERGES_ARG=
910
OUTPUT_STYLE=
1011
for arg in "$@"; do
1112
case "$arg" in
13+
--full-path)
14+
PROJECT_FULL_PATH=1
15+
;;
1216
--line)
1317
SUMMARY_BY_LINE=1
1418
;;
@@ -51,7 +55,12 @@ if [ -n "$SUMMARY_BY_LINE" ]; then
5155
else
5256
[ $# -ne 0 ] && commit=$*
5357
fi
54-
project=${PWD##*/}
58+
59+
if [[ -n "$PROJECT_FULL_PATH" ]]; then
60+
project=${PWD/${HOME}/\~}
61+
else
62+
project=${PWD##*/}
63+
fi
5564

5665
#
5766
# get date for the given <commit>

0 commit comments

Comments
 (0)