fix(git-bulk): fix workspace selection when cd fails (#1197)

* fix(git-bulk): fix workspace selection when cd fails

`cd` may fails for multiple reasons:
- mistake when editing `.gitconfig` manually
- previously existing workspace that have been removed
- ...

Currently, if `cd` fails, the `BulkOp` continue its execution ... in the
workspace defined in a higher directory that where the user, despite the
user specified a specific workspace (`-w`).

The user should be noticed of a failed `cd` (this is really not expected
for a valid configuration) and the operations should stop to not execute
something unexpected.

* fix(git-bulk): replace weak eval for better variable substitution

Get rid of poor `eval` syntax because they are vulnerable to command
injection, which may have unexpected side effects.

However, they enabled a useful feature: using environment variable
(*e.g.*, defined in a `.bashrc`) inside the `.gitconfig` to use dynamic
paths as  `bulk` workspaces.

As such, I keep this feature possible by using the Bash's ${!VAR}
syntax, which allows to get the value of one variable using the name of
a another variable. However, arbitrary command injection is not possible
anymore.

* fix(git-bulk): missing check about empty environnement variable

* style(git-bulk): typo

* docs(Commands.md): git-bulk env var feature

* docs(man/git-bulk): git-bulk env var feature

* docs(man/git-bulk): mention .gitconfig for config storage

* style(man/git-bulk): typo

* docs(man/git-bulk): run make/ronn for .1 and .html
This commit is contained in:
Pierre Ayoub 2025-02-26 05:33:16 +01:00 committed by GitHub
parent 1a9b0c2ab4
commit 8ce63003c0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 57 additions and 10 deletions

View file

@ -280,11 +280,20 @@ usage: git bulk [-g] ([-a]|[-w <ws-name>]) <git command>
git bulk --listall
```
Register a workspace so that `git bulk` knows about it (notice that <ws-root-directory> must be absolute path):
Register a workspace so that `git bulk` knows about it (it will be registered in your `.gitconfig`):
```bash
$ git bulk --addworkspace personal ~/workspaces/personal
```
Notice that `<ws-root-directory>` must be an absolute path (or an environment variable pointing to an absolute path).
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`).
As an illustration:
```bash
$ git bulk --addworkspace personal '$PERSONAL_WORKSPACE'
```
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.
```bash

View file

@ -111,7 +111,17 @@ function checkWSName () {
# parse out wsname from workspacespec
function parseWsName () {
local wsspec="$1"
# Get the workspace value from its specification in the `.gitconfig`.
# May be an absolute path or a variable name of the form: `$VARNAME`
rwsdir=${wsspec#* }
if [[ ${rwsdir:0:1} == '$' ]]; then
# Dereference the `rwsdir` value which is a variable name.
rwsdir_varname=${rwsdir:1}
rwsdir=${!rwsdir_varname}
if [[ -z "${rwsdir}" ]]; then
echo 1>&2 "error: bad environment variable: $rwsdir_varname" && exit 1
fi
fi
rwsname=${wsspec#*.} && rwsname=${rwsname%% *}
}
@ -142,7 +152,7 @@ function executBulkOp () {
listall | while read -r workspacespec; do
parseWsName "$workspacespec"
if [[ -n $wsname ]] && [[ $rwsname != "$wsname" ]]; then continue; fi
eval cd "\"$rwsdir\""
cd "$rwsdir" || exit 1
local actual=$PWD
[ "${quiet?}" != "true" ] && echo 1>&2 "Executing bulk operation in workspace ${inverse}$actual${reset}"
@ -150,11 +160,11 @@ function executBulkOp () {
for line in "${allGitFolders[@]}"; do
local gitrepodir=${line::${#line}-5} # cut the .git part of find results to have the root git directory of that repository
eval cd "\"$gitrepodir\"" # into git repo location
cd "$gitrepodir" || exit 1 # into git repo location
local curdir=$PWD
local leadingpath=${curdir#"${actual}"}
guardedExecution "$@"
eval cd "\"$rwsdir\"" # back to origin location of last find command
cd "$rwsdir" || exit 1 # back to origin location of last find command
done
done
}

View file

@ -1,6 +1,6 @@
.\" generated with Ronn-NG/v0.9.1
.\" http://github.com/apjanke/ronn-ng/tree/0.9.1
.TH "GIT\-BULK" "1" "September 2024" "" "Git Extras"
.TH "GIT\-BULK" "1" "February 2025" "" "Git Extras"
.SH "NAME"
\fBgit\-bulk\fR \- Run git commands on multiple repositories
.SH "SYNOPSIS"
@ -64,10 +64,14 @@ git bulk \-\-listall
List all registered repositories\.
.SH "EXAMPLES"
.nf
Register a workspace so that git bulk knows about it:
Register a workspace so that git bulk knows about it using an absolute path:
$ git bulk \-\-addworkspace personal ~/workspaces/personal
Or register a workspace using an environment variable pointing to an absolute path:
$ git bulk \-\-addworkspace personal '$PERSONAL_WORKSPACE'
Use option \-\-from in order to directly clone a repository or multiple repositories
$ git bulk \-\-addworkspace personal ~/workspaces/personal \-\-from https://github\.com/tj/git\-extras\.git
@ -108,6 +112,10 @@ Remove all registered workspaces:
$ git bulk \-\-purge
.fi
.SH "FILES"
.IP "\[ci]" 4
\fB\.gitconfig\fR: Store the \fBgit\-bulk\fR registered workspaces under the \fBbulkworkspaces\fR key\.
.IP "" 0
.SH "AUTHOR"
Written by Niklas Schlimm <\fIns103@hotmail\.de\fR>
.SH "REPORTING BUGS"

View file

@ -58,6 +58,7 @@
<a href="#DESCRIPTION">DESCRIPTION</a>
<a href="#OPTIONS">OPTIONS</a>
<a href="#EXAMPLES">EXAMPLES</a>
<a href="#FILES">FILES</a>
<a href="#AUTHOR">AUTHOR</a>
<a href="#REPORTING-BUGS">REPORTING BUGS</a>
<a href="#SEE-ALSO">SEE ALSO</a>
@ -137,10 +138,14 @@
<h2 id="EXAMPLES">EXAMPLES</h2>
<pre><code>Register a workspace so that git bulk knows about it:
<pre><code>Register a workspace so that git bulk knows about it using an absolute path:
$ git bulk --addworkspace personal ~/workspaces/personal
Or register a workspace using an environment variable pointing to an absolute path:
$ git bulk --addworkspace personal '$PERSONAL_WORKSPACE'
Use option --from in order to directly clone a repository or multiple repositories
$ git bulk --addworkspace personal ~/workspaces/personal --from https://github.com/tj/git-extras.git
@ -182,6 +187,13 @@ Remove all registered workspaces:
$ git bulk --purge
</code></pre>
<h2 id="FILES">FILES</h2>
<ul>
<li>
<code>.gitconfig</code>: Store the <code>git-bulk</code> registered workspaces under the <code>bulkworkspaces</code> key.</li>
</ul>
<h2 id="AUTHOR">AUTHOR</h2>
<p>Written by Niklas Schlimm &lt;<a href="mailto:ns103@hotmail.de" data-bare-link="true">ns103@hotmail.de</a>&gt;</p>
@ -196,7 +208,7 @@ $ git bulk --purge
<ol class='man-decor man-foot man foot'>
<li class='tl'></li>
<li class='tc'>September 2024</li>
<li class='tc'>February 2025</li>
<li class='tr'>git-bulk(1)</li>
</ol>

View file

@ -60,10 +60,14 @@ git bulk adds convenient support for operations that you want to execute on mult
## EXAMPLES
Register a workspace so that git bulk knows about it:
Register a workspace so that git bulk knows about it using an absolute path:
$ git bulk --addworkspace personal ~/workspaces/personal
Or register a workspace using an environment variable pointing to an absolute path:
$ git bulk --addworkspace personal '$PERSONAL_WORKSPACE'
Use option --from in order to directly clone a repository or multiple repositories
$ git bulk --addworkspace personal ~/workspaces/personal --from https://github.com/tj/git-extras.git
@ -104,6 +108,10 @@ git bulk adds convenient support for operations that you want to execute on mult
$ git bulk --purge
## FILES
- `.gitconfig`: Store the `git-bulk` registered workspaces under the `bulkworkspaces` key.
## AUTHOR
Written by Niklas Schlimm &lt;<ns103@hotmail.de>&gt;

View file

@ -12,8 +12,8 @@ git-clear-soft(1) git-clear-soft
git-clear(1) git-clear
git-coauthor(1) git-coauthor
git-commits-since(1) git-commits-since
git-contrib(1) git-contrib
git-continue(1) git-continue
git-contrib(1) git-contrib
git-count(1) git-count
git-cp(1) git-cp
git-create-branch(1) git-create-branch