New Command git-bulk initial commit

This commit is contained in:
Niklas Schlimm 2017-03-08 19:50:36 +01:00
parent b00aacee00
commit 57c0eb776c
6 changed files with 400 additions and 0 deletions

View file

@ -4,6 +4,7 @@
- [`git authors`](#git-authors)
- [`git back`](#git-back)
- [`git bug`](#git-featurerefactorbugchore)
- [`git bulk`](#git-bulk)
- [`git changelog`](#git-changelog)
- [`git chore`](#git-featurerefactorbugchore)
- [`git clear`](#git-clear)
@ -234,6 +235,73 @@ $ git effort --above 5
$ git effort bin/* lib/*
```
## git bulk
`git bulk` adds covenien support for operations that you want to execute on multiple git repositories.
* simply register workspaces that contain multiple git repos in their directory structure
* run any git command on the repositories of the registered workspaces in one command to `git bulk`
* use the "guarded mode" to check on each execution
```bash
usage: git bulk [-g] [-w <ws-name>] <git command>
git bulk --addworkspace <ws-name> <ws-root-directory>
git bulk --removeworkspace <ws-name>
git bulk --addcurrent <ws-name>
git bulk --purge
git bulk --listall
```
Register a workspace so that `git bulk` knows about it:
```bash
$ git bulk --addworkspace personal ~/workspaces/personal
```
Register the current directory as a workspace to `git bulk`
```bash
$ git bulk --addcurrent personal
```
List all registered workspaces:
```bash
$ git bulk --listall
bulkworkspaces.personal /Users/niklasschlimm/workspaces/personal
```
Run a git command on the repositories:
```bash
$ git bulk fetch
```
![fetchdemo](https://cloud.githubusercontent.com/assets/876604/23709805/e8178406-041a-11e7-9a0c-01de5fbf8944.png)
Run a git command on only one workspace ans its repositories:
```bash
$ git bulk -w personal fetch
```
Run a git command but ask user for confirmation on every execution (guarded mode):
```bash
$ git bulk -g fetch
```
Remove a registered workspace:
```bash
$ git bulk --removeworkspace personal
```
Remove all registered workspaces:
```bash
$ git bulk --purge
```
## git repl
Git read-eval-print-loop. Let's you run `git` commands without typing 'git'.

232
bin/git-bulk Executable file
View file

@ -0,0 +1,232 @@
#!/usr/bin/env bash
# reset environment variables that could interfere with normal usage
export GREP_OPTIONS=
# put all utility functions here
# make a temporary file
git_extra_mktemp() {
mktemp -t "$(basename "$0")".XXX
}
#
# check whether current directory is inside a git repository
#
is_git_repo() {
git rev-parse --show-toplevel > /dev/null 2>&1
result=$?
if test $result != 0; then
>&2 echo 'Not a git repo!'
exit $result
fi
}
is_git_repo
invers=`tput rev`
reset=`tput sgr0`
txtbld=$(tput bold) # Bold
bldred=${txtbld}$(tput setaf 1) # red
shopt -s extglob
guarded=false
singlemode=false
#
# print usage message
#
usage() {
echo 1>&2 "usage: git bulk [-g] [-w <ws-name>] <git command>"
echo 1>&2 " git bulk --addworkspace <ws-name> <ws-root-directory>"
echo 1>&2 " git bulk --removeworkspace <ws-name> <ws-root-directory>"
echo 1>&2 " git bulk --addcurrent <ws-name>"
echo 1>&2 " git bulk --purge"
echo 1>&2 " git bulk --listall"
}
# add another workspace to global git config
function addWSDir () {
git config --global bulkworkspaces.$wsname "$wsdir"
}
# add current directory
function addCurrWSDir () {
git config --global bulkworkspaces.$wsname "$PWD"
}
# remove workspace from global git config
function remWSDir () {
git config --global --unset bulkworkspaces.$wsname
}
# remove workspace from global git config
function purgeWS () {
git config --global --remove-section bulkworkspaces
}
# list all current workspace locations defined
function listWSDir () {
git config --global --get-regexp bulkworkspaces
}
# atomic execution of a git command in one specific repository
function guardedExecution () {
if $guarded; then
echo -n "${invers}git $gitcommand${reset} -> execute here (y/n)? "
read -n 1 -r </dev/tty; echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
atomicExecution
fi
else
atomicExecution
fi
}
# execute a git command with log
function atomicExecution () {
echo "${bldred}->${reset} executing ${invers}git $gitcommand${reset}"
git $gitcommand
}
# check if the passed command is known as a core git command
function checkGitCommand () {
if git help -a | cat | grep -o -q "$corecommand"; then
echo "Core command \"$corecommand\" accepted."
else
usage
echo "error: unknown GIT command: $corecommand"
exit 1
fi
}
# check if workspace name is registered
function checkWSName () {
found=0
while read workspace; do
cwsname=$(echo $workspace | cut -f1 -d' ' | cut -f2 -d'.')
if [[ $cwsname == $wsname ]]; then return; fi
done <<< "$(echo $(listWSDir))"
# when here the ws name was not found
echo "error: unknown workspace name: $wsname"
exit 1
}
# execute the bulk operation
function executBulkOp () {
if $singlemode; then
echo "Selected single workspace mode in workspace: $wsname"
fi
listWSDir | while read workspacespec; do
cwsname=$(echo $workspacespec | cut -f1 -d' ' | cut -f2 -d'.')
if $singlemode && $cwsname != $wsname ]]; then continue; fi
wslocation=$(echo $workspacespec | cut -f2 -d' ')
eval cd "$wslocation"
actual=$(pwd)
echo "Executing bulk operation in workspace ${invers}$actual${reset}"
eval find . -name ".git" | while read line; do
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
curdir=$(pwd)
echo "Current repository: ${curdir%/*}/${bldred}${curdir##*/}${reset}"
guardedExecution
eval cd "$wslocation" # back to origin location of last find command
done
done
}
initialcount="${#}"
initialarguments="${@}"
# if no arguments show registered workspaces
if [[ $initialcount -le 0 ]]; then
listWSDir
fi
# parse command parameters
while [ "${#}" -ge 1 ] ; do
case "$1" in
--listall)
butilcommand="listWSDir"
break
;;
--purge)
butilcommand="purgeWS"
break
;;
--removeworkspace)
shift
wsname="$1"
butilcommand="remWSDir"
break
;;
--addcurrent)
shift
wsname="$1"
butilcommand="addCurrWSDir"
break
;;
--addworkspace)
shift
wsname="$1"
shift
wsdir="$1"
butilcommand="addWSDir"
break
;;
-g)
guarded=true
;;
-w)
singlemode=true
shift
wsname="$1"
checkWSName
;;
-*)
usage
echo 1>&2 "error: unknown argument $1"
exit 1
;;
--*)
usage
echo 1>&2 "error: unknown argument $1"
exit 1
;;
*)
butilcommand="executBulkOp"
corecommand="$1"
gitcommand="$@"
checkGitCommand
butilcommand="executBulkOp"
break
;;
esac
shift
done
# check right number of arguments
case $butilcommand in
@(listWSDir|purgeWS) )
if [[ $initialcount -ne 1 ]]; then
usage
echo 1>&2 "error: wrong number of arguments"
exit 1
fi
;;
@(addCurrWSDir|remWSDir))
if [[ $initialcount -ne 2 ]]; then
usage
echo 1>&2 "error: wrong number of arguments"
exit 1
fi
;;
addWSDir)
if [[ $initialcount -ne 3 ]]; then
usage
echo 1>&2 "error: wrong number of arguments"
exit 1
fi
;;
esac
$butilcommand # run user command

View file

@ -360,6 +360,7 @@ zstyle ':completion:*:*:git:*' user-commands \
authors:'generate authors report' \
back:'undo and stage latest commits' \
bug:'create bug branch' \
bulk:'run bulk commands' \
changelog:'generate a changelog report' \
chore:'create chore branch' \
clear-soft:'soft clean up a repository' \

0
man/git-bulk.1 Normal file
View file

0
man/git-bulk.html Normal file
View file

99
man/git-bulk.md Normal file
View file

@ -0,0 +1,99 @@
git-bulk(1) -- Run git commands on multiple repositories
========================================================
## SYNOPSIS
usage: git bulk [-g] [-w &lt;ws-name&gt;] &lt;git command&gt;
git bulk --addworkspace &lt;ws-name&gt; &lt;ws-root-directory&gt;
git bulk --removeworkspace &lt;ws-name&gt;
git bulk --addcurrent &lt;ws-name&gt;
git bulk --purge
git bulk --listall
## DESCRIPTION
git bulk adds covenien support for operations that you want to execute on multiple git repositories.
- simply register workspaces that contain multiple git repos in their directory structure
- run any git command on the repositories of the registered workspaces in one command to `git bulk`
- use the "guarded mode" to check on each execution
## OPTIONS
-g
Ask the user for confitmation on every execution.
-w <ws-name>
Run the GIT command only on the specified workspace. The workspace must be registered.
&lt;git command&gt;
Any GIT Command you wish to execute on all the Repositories.
--addworkspace &lt;ws-name&gt; &lt;ws-root-directory&gt;
Register a workspace for bulk operations. All repositories in the diretories below &lt;ws-root-directory&gt; get registered under this workspace with the name &lt;ws-name&gt;.
--removeworkspace &lt;ws-name&gt;
Remove the workspace with the logical name &lt;ws-name&gt;.
--addcurrent &lt;ws-name&gt;
Adds the current difrectory as workspace to git bulk operations. The workspace is referenced wioth ist logical name &lt;ws-name&gt;.
git bulk --purge
Removes all defined repository locations.
git bulk --listall
List all registered repositories.
## EXAMPLES
Register a workspace so that git bulk knows about it:
$ git bulk --addworkspace personal ~/workspaces/personal
Register the current directory as a workspace to git bulk:
$ git bulk --addcurrent personal
List all registered workspaces:
$ git bulk --listall
Run a git command on the repositories:
$ git bulk fetch
Run a git command on only one workspace and its repositories:
$ git bulk -w personal fetch
Run a git command but ask user for confirmation on every execution (guarded mode):
$ git bulk -g fetch
Remove a registered workspace:
$ git bulk --removeworkspace personal
Remove all registered workspaces:
$ git bulk --purge
## AUTHOR
Written by Niklas Schlimm &lt;<ns103@hotmail.de>&gt;
## REPORTING BUGS
&lt;https://github.com/nschlimm/git-bulk&gt;
## SEE ALSO
&lt;<https://github.com/tj/git-extras>&gt;