Install git-functions
to improve your git user experience with gitshell
Every comfortable command-line UI should be verbose enough to be descriptive
and self-explanatory and IMHO git
achieved this goal very well. However, for
intensive use - after having learned the command-line UI - verbosity impairs
productivity and there is no way to avoid writing git
in front of every
command unless a functions-set wrap layer is used. This is the point in which
git-functions
arrives and aims to help those whose hands wish to be faster
than their minds.
Have fun <3
The dash
which is the standard by default shell in GNU/Debian Linux is about
2x faster than bash
to execute commands and probably bash
is the slowest
shell of all. However, bashism are somewhat powerful shell-scripting tricks and
moreover, the user interaction with small functions does not require any
particular performance to be acceptable and in any case git
is the real
bottle-neck in performances especially when it queries a remote host.
After the v0.4-rc1
the development went towards allowing the function to wrap
git
only into a restricted shell which is the bare minimum requirement to
offer these shortcuts as a remote service. However, the limitations of the
restricted shell could be easily by-passed leveraging a PATH. In fact, usually
bash is in the PATH so it can be executed in interactive mode bash -i
without
limitations.
This shows clearly that rbash
is not sufficient to restrict the user but also
the environment should be controlled and usually the easy way to achieve this
goal is to let the users play into a chroot-ed-environment specifically prepared
Just to give it a try, source the git.shell
in your environment and call them
in your git local repository
GFRELOAD=1 source git.shell
this file also source the colors.shell
in order to produce a color full output
while functions will be loaded when gitshell
will be lauched.
To install in your system in a way they will be loaded by ~/.bashrc
use this
script without any argument
git clone https://github.com/robang74/git-functions.git
cd git-functions
./install.sh [ uninstall | update | reinstall | help ]
then follow the instructions, in particular source the git.shell
in your
current bash environment. To install the development version switch the branch
with git switch devel
and then run the installer from that branch.
Alternatively, you can do a remote installation with these commands
branch=main
repo=https://raw.githubusercontent.com/robang74/git-functions
wget $repo/$branch/install.sh -O - | bash
You might want to change the branch in devel
but that branch, from time to
time, could be totally broken. Other branches might have the same problem.
However, also for the main
branch, it is not assured of the lack of bugs.
After installation your .bashrc
will be modified in such a way the gitshell
will be defined as a function. Calling it - in your git repository - will give
you the access to the wrap layer:
cd my-repo.git
gitshell
gfhelp
This command will display the functions available which are reported and briefly described here below. If you need more functions, feel free to add to the source code and share the change with the author. Or ask for an addition.
ff
,sw
: in git use -w (ignore blank spaces) as default, opt:-r addedlsrmt
: was a replica ofrmt
now is a short forrmt -v
gfreload
: opt:-f added to reload a single function
The following list is divided for class of usage and roles. Only the main
functions are loaded by ~/.bashrc
in the user bash environment while all the
others are available inside the gitshell
environment.
gitshell
: spawns a restricted shell with the git-funtcions environmentgfupdate
: update the installation and reload the git-functionsgfhelp
: likegflist
but in a fancier waygflist
: list the functions availablegfreloadafunc
: reload a single functiongfreload
: reload the functions, opt:-f reload a single function
-
cdtop
: change directory to the top level of the repository and prints the full path -
redef_git
: redefine the function_git()
which is used internally -
reset_git
: reset_git()
to the default commandgit
-
noopts
: print every arg that does not start with minus -
ps1p
: print a custom PS1 for git users -
ps1s
: set the custom PS1 for git users -
egnc
: function alias foregrep --color=never
-
less
: function alias forcommand less -Fr
-
ugit
: unbuffered version ofgit -P
-
ll
: short for 'ls -al' with colors -
eg
: short for 'egrep` with colors
Example of redef_git
and reset_git
usage:
redef_git -u # every functions of this wrapper will use `ugit` instead of `git`
redef_git 'git -P "$@"' # of this wrapper will use `git` with no pager
reset_git # every functions of this wrapper will use `git` as default
pcache
: set the password cache for 1h of inactivity, deal with.gitpasswd
editorset
: set your default editor
opst
: shows the current operation pending: merge, rebase or cherry-picktodo
: short forgit --edit-todo
, arg: c,m,r or current operationcont
: short forgit --continue
, arg: c,m,r,ce or current operationabrt
: short forgit --abort
, arg: c,m,r,ce or current operationskip
: short forgit --skip
, arg: c,m,r or current operation
push
: short forgit pull
fpush
: short forgit push --force
repshrink
: clean the reflog and shrink the repositorytagmv
: move a tag to hash (as args) and push the changestagadd
: add a tag to a commit (sha as arg) and push tagstagdel
: del a tag (as arg) and push the changetagren
: rename a tag and push the changermtadd
: add a remote repository to the localrmtdel
: delete a remote repositoryrmt
: short forgit remote
forig
: short forgit fetch origin
frmt
: short forgit fetch
, default the first inrmt
or args with opt -a:--allsearch
: search for a string in all the commits and report the first found, arg stringirb
,irebase
: rebase starting from the hash passed or ~n/-n forHEAD~n
amd
, amend: shorts for
git amendbut with opt:-a does
add -m`add
: short forgit add
but opt:-m add all the modified itemspa
: format patch apply and create signed commitce
: commit edit within a restricted shellcr
: commit reword, a single SHA as argren
: short forgit mv
cm
: short forgit commit --signoff
co
: short forgit checkout
pull
: short forgit pull
rpull
: short forgit pull --rebase
rcont
: short forgit rebase --continue
stash
: short forgit stash
pop
: short forgit stash pop
chpk
: short forgit cherry-pick
rst()
: short forgit reset
, opt -h:--hardres()
: short forgit restore
, opt -s:--staged, -h:hres()hrst()
: short forgit reset --hard
, opt -r:remotesres()
: short forgit restore --staged
hres()
: it performs sres() and then co()ampatch()
: short forgit amend
a patch/setamff()
: short forgit am --show-current-patch=diff
hconv
: convert the hash reference into a standard 7-chars hashlg
: show the log in a compact and fancy way, SHAs or files as argslgnc
: the same oflg
but without colors, for scriptinglgrpnc
: the same oflgrp
but without colors, for scriptingslt
: likelg
but with all branches shown, files as argslg1
: likelg
but just the first linerl
,reflog
: shorts forgit reflog
sf
: show the file involved in a commit, SHAs as argsst
: short forgit status
, opt:-m shows whatadd -m
usessw
: short forgit show
withsf
after, opt:-P for no pagerff
: short forgit diff -w
, opts -s:staged -o:origin -r:remotefpatch
: do agit format-patch
for the commit, SHA and opts in argbsw
: short forgit switch
, the branch name as arg or-
for the lastlgrp
: find a string into thelg
output, opts -s:SHAs-only -1:first onlylsbr
: show the list of branches, arg branch name, opt: -r:remotes, -a:alllsrmt
: short forrmt -v
, it shows the verbose list of remotes sourcesmgrp
: search a'string'
intost -m
changed file or from hash, defaultHEAD
or ~n/-n forHEAD~n
rcur
: remote origin which the current branch is tracking, opt:-c --show-current onlyrbcur
: remote branch which the current brach is trackinghcur
: short forgit rev-parse --short HEAD
bcur
: short forgit branch --show-current
lstag
,tagl
: shorts forgit tag -l
This is a special function used to execute commands (cmds) on multiple branches:
for-all-other-branches
: execute the args as commands for the branches--
: per default runs over all the branches but not the current one-a
: all the branches included the current-p
:git pull
before cmds-r
:git pull --rebase
before cmds-n
: not fail despite the last command failure-s
:git stash
before go andgit stash pop
when returns-f
: fetch all the remotes before starting otherwise run only on locals
A custom branches selection could be specified in this way:
BRANCHES="uno due tre" for-all-other-branches 'cmds ${branch}'
The branch
variable is defined in the loop and its value is the branch name
on which commands are currently executing. The single quotes around the
commands string are necessary to avoid that the variable is expanded before
starting the loop.
In case the last command fails then the loop stops and spawns an emergency bash
in that shell - which is restricted - the operator can handle the issue and
then decide to proceed further with exit
or definitely stop with exit 1
.
Switch to branch 'devel'
Your branch is up-to-date with 'origin/devel'.
branch: devel, KO
fix the problem and then enter 'exit'
or enter 'exit 1' to abort completely
+git:devel> exit 1
The use of the password cache function pcache
could undermine your git remote
repository security especially if used in combination with .gitpasswd
.
Moreover the use of the password cache or saving your git password in plain
text in a file of your workstation disk could go against your company security
policies. For extra security you can disable this function with
unset pcache
You might also want to add after the source git.function
in your ~/.bashrc
to make this choice as the default one. However, gfreload
and gfupdate
will
load again into your current bash environment. To avoid this risk, then use:
unset pcache gfreload gfupdate
So, no one of these functions will be able to interfere with your security
policy but you will need to use install.sh update
to update your
git-functions installation.
The alternative is to store the password in your home git global config or in the current git local config and pcache will retrieve your password from there.
The first time that pcache
runs, it would be better setting the git username:
pcache --user $git_my_user_name
Otherwise the username will be asked by the cache manager but will be lost when the cache will expire. Setting the user works on https remote repositories.
To improve dramatically the fancy coloured output combined with some features
like grepping and lessing, it has been used the trick to override isatty()
using a small piece of code isatty_override.c
which produces .so
library:
LD_PRELOAD="${path}/isatty_override.so" git -P "$@"
This is an example of usage which resembles the core of the 'ugit' function.
Almost all the files are under one of many FOSS licenses and the others are in the public domain. Instead, the composition of these files is protected by the GPLv3 license under the effects of the Copyright Act, title 17. USC §101:
Under the Copyright Act, a compilation [EdN: "composition" is used here as synonym because compilation might confuse the technical reader about code compiling] is defined as a "collection and assembling of preexisting materials or of data [EdN: data includes source code, as well] that are selected in such a way that the resulting work as a whole constitutes an original work of authorship."
This means, for example, that everyone can use a single MIT licensed file or a part of it under the MIT license terms. Instead, using two of them or two parts of them implies that you are using a subset of this collection which is a derived work of this collection which is licensed under the GPLv3, also.
The GPLv3 license applies to the composition unless you are the original author of a specific unmodified file. This means that every one that can legally claim rights about the original files maintains its rights, obviously. Therefore the original authors do not need to undergo the GPLv3 license applied to the composition and they maintains their original right in full. Unless, they use the entire composition or a part of it for which they had not the rights, before.
Some files, documents, software or firmware components can make an exception to the above general approach due to their specific copyright and license restrictions. In doubt, follow the thumb rule of fair-use.
In this project, the copyright notice, the license and the author is reported in each file header and here just listed:
colors.shell
: MITisatty_override.c
: MITgit-commit-edit
: public domaingit-isar-send-patch
: GPLv3git.functions
: GPLv3cr-editor.sh
: GPLv3install.sh
: GPLv3git.shell
: GPLv3
For further information or requests about licensing and how to obtain a fork suitable for your own business, please write to the project maintainer and copyleft owner.
- Roberto A. Foglietta roberto.foglietta@gmail.com