gitcmd-abbrev¹ provides a small set of Bash² functions and commands that greatly shorten the amount of typing you have to do for common Git operations (even if you already use command-line completion). For example:
com # git commit -v
cam # git commit -v --amend
logm # LESS=-aeFimsXR -j.15 -SR git log --graph --abbrev-commit --pretty=oneline --decorate=short --pretty=tformat:%C(auto)%h %C(green)%<(12,trunc)%ar%C(auto) %C(black)%<(20,trunc)%ae%C(auto)%C(auto)% D%n%C(blue)%s
The same command-line completions are available as for the long Git commands.
¹ This is not named git-abbrev because that is the name that would be
used for the script supporting a git abbrev subcommand.
² Bash is required; this uses Bash features that do not exist in POSIX shells.
Contents:
Ensure the files under bin/ are in your $PATH, e.g. by doing one of the
following:
- Add
…/gitcmd-abbrev/bin/to your $PATH. - Add links to those files in an existing directory in your $PATH.
- Copy the files to an existing directory in your $PATH.
Then add source gitcmd-abbrev.bash to your ~/.bashrc.
mkdir -p ~/.home
cd ~/.home
git clone https://github.com/dot-home/_dot-home.git # Core system
git clone https://github.com/dot-home/gitcmd-abbrev.git # This repo
~/.home/_dot-home/bin/dot-home-setup
Sadly, testing is mostly manual at the moment, with some assistance from
the (admittedly crappy) Test script. That script also has notes on manual
testing in the comments.
Most of these commands are shell functions defined by
bin/gitcmd-abbrev.bash. Those that are instead programs under bin/ are
noted with a subscript beta, 'ᵦ', at the end of the command name.
Almost all commands take the same additional options as the underlying Git
command, and command line completion is the same as the underlying Git
command. However, some commands (mostly those that run git log) can
take "comma-options" as the first argument on the command line. This is
a comma followed by one or more characters, e.g., ,rd will log in
reverse and suppress decoration. The available comma options are:
d --no-decorate
g --graph
r --reverse
All commands will tweak the $LESS variable where necessary to produce prettier output.
Where the documentation below does not suffice, you can examine the actual
functions in bin/gitcmd-abbrev.bash or set -x to turn on tracing before
running the command. (set +x will undo the tracing).
- A branch is a sequence of commits. It may or may not be pointed to by a ref, (though it can be garbage-collected if not), and multiple refs may point to the same branch, or different commits on the same branch.
- A ref is any named pointer to a commit, e.g., as created with the
git branch REFNAMEcommand. Note that this does not create a new branch as that term is used here:@andREFNAMEare two refs poining to the same branch. - A head is any ref pointing to a commit that has no children pointed to by any any other head. (I.e., a head points to the tip of a branch, not the middle of a branch.)
st: Similar togit status -bs, except:- Within a Git repo it will recursively display status of submodules up
to a given level n specified with the
-noption (default-1). - Outside of a Git repo, given arguments that are directories, will display a brief status for each directory, including whether it's a plain directory, a Git repo, etc., the number of changed and untracked files, and the current branch and latest commit message summary.
- Within a CVS checkout it will display the status of that. It should be extended to give basic information about other VCS checkouts as well.
- Within a Git repo it will recursively display status of submodules up
to a given level n specified with the
st0,st9: Same asst -0andst -999, respectively.
-
log: Same asgit log. -
logs: Aslogwith the list of files changed in each commit. This always gives the full path for each file, even if this causes wrapping; use-Sinlessif you want horizontal scrolling instead of wrapping. It minimizes the the size of the histogram for adds/deletes (5 max) because that provides minimal information anyway. It also shows a specific indication on new and deleted ("gone") files. -
logp,logp1,slp1,logpr: Aslogswith the diff from the previous commit (--patch) as well.logp1does this for a single commit, rather than all commits down that branch of the graph.slp1does the same with a few blank lines prefixed to clearly separate the commit from previous output in the terminal. (This is useful mainly on tall terminal windows.)logprprints the commits in reverse order, which is useful for doing a "walk forward through the commits" review of code. (To review a dev branch, for example, you could uselogpr main@{u}..origin/dev/joe/bugfix. -
logb: Brief (one line per commit) log of current or specified refs. (,gor,ris particularly useful here.) The $LESS variable will have-RSappended to enable proper display of colour and turn off line wrapping so that all commits take up one line. (You can scroll left and right to see more of the commit summary line.) -
logab: Aslogbbut graph output for all heads in the repo. -
logd: Aslogb, but for the following refs:- All of the following that exist:
main,main@{upstream},master,master@{upstream}. - The current HEAD and, if it has a tracking ref, its tracking ref.
- All local and remote tracking refs matching
dev/*/DESCwhereDESCis the last component of the current branch name. E.g., if you are ondev/cjs/24g31/new-feature, it will match all other refsdev/*/new-featurelocal and remote.
- All of the following that exist:
-
logh: Show "recent" (within a week) changes on all heads. (The implementation of this needs to be improved.) -
logm: Brief log with commit metadata, using two lines per commit. The first line gives the abbreviated commit ID, age of the commit, author, and ref information. The second line is the commit summary line. -
logmn: Aslogmwithout single-parent merge commits.
gauthors: Show all authors and their commit counts for the commit range given (default@, i.e., all commits from HEAD back to the first commit).
-
br: Asgit branch. -
lr,lrg,lrh,lra: List refs, asgit branch -l. As well as some standard git-branch arguments, these also accept a list of string fragments that will limit the output to refs matching any of them. (E.g., you might uselra dev/cjs/to see only development branches made by usercjs.)lr: local heads only.lrglocal heads whose upstream is "gone" (remember tofetch -pfirst)lrhall heads (local and remote),lraall refs, even if not a head (i.e., unknown togit branch).
This automatically uses the most verbose format (giving short commit ID, tracking branch and ahead/behind status, and a bit of the most recent commit summary message). Output is sent through
lessby default limiting the line length to the terminal width; you may add-nto avoid less quitting immediately at EOF so you can scroll horizontally or turn on line wrap by typing-S.This name conflicts with the with the
lrfile listing program. This is not normally an issue in script files, since they will not inherit this function, but if you need to get around it locally, consider adding anlrrfunction that calls/usr/bin/lr. -
co: Asgit checkout -
cond: Checkout new development branch. Typicaly used ascond footo start a new branchdev/user/date/fooatmain@{upstream}. Seecond -hand experiment withcond -nfor full details. -
mbase: Display the base whence the current branch diverged frommaster. (This needs considerable fixing.)
See also above logp, logp1, slp1.
blame: Asgit blame.dif: Asgit diff.difs: Diff staged files, asdif --cached.dift: Asgit difftool -y
gre: Asgit reset.grehard: Asgit reset --hard.greupstream: Asgit reset --hard @{upstream}clean: With no arguments, asgit clean --dry-run. Supplying-fwill suppress the-n/--dry-runargument.iclean: Clean ignored files and directories too, asclean -dX.stash: With no arguments, lists stash entries. With any arguments, asgit stash.
add: Asgit add.com: Asgit commit -v.coma: Ascom --allcam: Ascom --amendgsub: Asgit submodule.gctrᵦ: Git commit trailer line generation.gctr co fredwill generate a Co-authored-by: line with the value from the most recent Author: line matching "fred". Rungctr -horgctr --helpfor more details.
-
gr: Asgit rebase -
grmu: Asgit rebase … master@{upstream}. (XXX this needs to be fixed to use the default head, so it works withmainas well.) -
grabort: Asgit rebase --abort. -
grcontinue: Asgit rebase --continue. -
grskip: Asgit rebase --skip. -
gri,grim: Do agit rebase -i.gridefaults to the last ten commits; you may give it a number for a different number of commits, or any ref and it will start at that ref.grimstarts at the first commit that diverges frommain@{upstream}(i.e., your entire current development branch.) -
grwhere -
cpick: Asgit cherry-pick. -
cpcontinue: Ascpcick --continue. -
mergeff: Asgit merge --ff-only.
gurl [REPO-DIR …]: Show fetch URLs for the repo(s) at or above REPO-DIR, (default: current working directory), one per line.rem:- With no arguments, display a line for each remote giving the name and fetch URL. If the push URL is different, a second line with the name and the push URL will be displayed.
- With arguments other than below, as
git remote. - With
-Has the first argument, check for remote HEAD branch updates and update local refs to match. This changes the local {remote}/HEAD ref to be the same as the remote and, if there is a local branch of the same name tracking the old {remote}/HEAD, makes it track the new {remote}/HEAD and renames it to the new branch name.
fetch,pfetch- With no arguments, fetch from
remotes.defaultor, if that's not set, all remotes. Then show the current status of the working copy (asgit status -bs). - With any argument that's a path to a directory containing a .git/ subdirectory, assume all args are paths to repos to be fetched as above or paths to be ignored. The user is informed for each one whether it's being feched or ignored.
- With arguments, as
git fetch. pfetchisfetch --prune(It has the p at the start, rather than at the end, to improve command-line completion.) Note that this does not prune tags by default, for reasons described in the comment on that function; you may add--prune-tagsif you want to do this.
- With no arguments, fetch from
pull: Asgit pull --ff-only. (This keeps you from accidentally getting stuck in a complicated merge.)push: Asgit push, but does not accept the-f/--forceoptions.pushf: Asgit push --force-with-lease. This also does not accept the-f/--forceoptions; to do that (which is quite dangerous) usegit push.pushu [-f] REMOTE [REMOTE-REF]: Push the current branch to a branch of the same name on remote, or to a branch named remote-ref if given, and set the upstream of the current branch to that. This will refuse to operate if the current branch already has an upstream configured. The-foption will override this, removing any currently configured upstream before pushing and configuring the new upstream.
ggrep: Asgit grep.gfgrep: Asggrep -F(i.e., without interpreting the pattern as a regex).gk [START-COMMITISH]: Runsgitk --all, with the commit at START-COMMITISH selected if supplied.
gpack: Do a garbage collection (git gc) and then pack the repo down to the minimum number of files, removing all loose object files and similar. Any arguments are passed on togit gcso you may use, e.g.,--aggressiveto collect down to a smaller size before the pack.
- dustin/bindir contains quite a few useful git tools, written mainly in Python.