Reputation: 25872
Background: we've currently got a project, which requires cloning multiple git
repositories into a single parent folder. I'm attempting to write a script, so that I can run git
operations, across all subdirectories, to make it easier to manage (e.g. ./gitall.sh status
/ add
/ reset
/ commit -m "Foobar"
/ push
/ etc.
The script is working well for all operations, until I attempt to perform a ./gitall.sh push
I receive the error fatal: remote part of refspec is not a valid name in
for each directory, because the effective command is git -C somedir push "" "" "" ""
(git
borks at the trailing double quotes). N.B. the parameters need to be double quoted, so that it captures parameters with spaces.
gitall.sh
find ./repo-* -type d -depth 0 -exec bash -c "git -C {} \"$1\" \"$2\" \"$3\" \"$4\" \"$5\"" \;
Is there anyway to double quote a parameter, ONLY if it exists? (or anyway to tell git
to ignore the trailing double quotes?)
Upvotes: 1
Views: 79
Reputation: 9877
The right way to pass an unknown number of parameters in bash is to use "$@"
. Further, you don't need to explicitly call bash
, because it will complicate the way you need to quote the parameters.
This will automatically quote all parameters:
#!/bin/bash
find ./repo-* -type d -depth 0 -exec git -C {} "$@" ';'
Going one more step, there is no need to call find
if all you want is directory entries in the current level. The /
at the end of the matching pattern will select only directories:
#!/bin/bash
for d in repo-*/; do
[ -d "$d" ] && git -C "$d" "$@"
done
(Note that if you don't have any directories that match the pattern, the loop will execute once with the literal argument repo-*/
; the [ -d "$d" ]
will guard against git being called in this case).
Lastly, you may want to consider using Google's repo
tool instead of your own solution for managing multiple git repos. It's very powerful and easy to use.
Upvotes: 3
Reputation: 164859
The problem is you're passing in extra arguments to git push
. Each ""
is passed by the shell to git
which then thinks its getting 7 arguments, but the last 4 are empty strings.
What you're looking for is "$@"
. "$@"
is equivalent to "$1" "$2" ...
There's no need for all the extra quoting, nor the bash -c
. "$@"
will be expanded in the shell script.
Also note that invocation of find won't work with GNU find, so use the full path to BSD find.
#/bin/sh
/usr/bin/find ./repo-* -type d -depth 0 -exec git -C {} "$@" \;
Upvotes: 2
Reputation: 60295
You're after "$@"
, and there's better ways to do what you're doing:
find -name .git -prune -execdir git "$@" \;
and you can add -maxdepth 1
or whatever to limit the find command's spelunking further.
Upvotes: 1