Is there a way in bash/powershell to automatically include a word in a command based on context? - bash

Currently, when inside git repos, I type git status. Is there any way for my shell to understand this is a git repo and automatically append git to relevant commands?
e.g.,
# bash example
# before
git status
# after
status # "status" isn't a registered command, but "git status" is, so bash uses the latter
I'd probably only want this enabled when I'm in a repo, but is there any way to get functionality similar to this in any of the popular shells?
I recognize this isn't always preferred or the best idea, but it could save me from typing a word.

This is what aliases were invented for in bash. You'd add a line to your bashrc that looked like this:
alias status='git status'
If you'd like, you could add one for every git subcommand you ran frequently:
alias commit='git commit'
alias checkout='git checkout'
alias add='git add'
alias push='git push'
alias pull='git pull'
alias config='git config'
Your environment is your own, and if you wanna make a shorthand for git commands, you're free to do so!
Also, these aliases will pass any arguments to the underlying command. So if you write:
commit -m "My message"
This will translate to git commit -m "My message".
These aliases should be added to a file like the .bashrc file in your home directory, if one exists.
See here for a more in-depth explanation of aliases.

Related

Create an alias with more than 1 command as the alias name

I want to create an alias that is composed of 2 commands. Could not find anything online as most questions are about an alias that equals to 2 commands, eg:
alias command="command1 && command2"
What I want:
alias git push="git add . && git commit -m 'auto ups' && git push"
Why using this instead of naming my alias gp (or whatever 1 worded alias)
I want to keep the same git push experience
Want to learn about bash
Is that possible?
As illustrated here, you would need to define a git wrapper.
It should be set in your $PATH before the /usr/local/bin/git itself.
Or you can reference that script through an alias git=git-wrapper in your ~/.bash_profile.
In that wrapper, on push, you can then call a script which would chain any git command you need.

Bash completion for git aliases containing multiple subcommands

I have set up the following alias in my .gitconfig file:
[alias]
ss = stash show
Unfortunately bash completion does not work correctly on this alias. When I type git ss <TAB>, I get:
❯ git ss <TAB>
apply clear drop pop show
branch create list push
Which is obviously the completion for git stash instead of git stash show.
With the original command I get the list of available stashes:
❯ git stash show <TAB>
stash#{0} stash#{1}
Is there a way to get the completion on the alias behave like on the original command?
I am on Ubuntu 20.04 and using the distro's default git completions.
I posted this question on the Git mailing list and got a reply to work around this issue:
It is possible to make completion work for your particular
alias by using our completion script's extension mechanism that allows
users to specify completion functions to their own git commands. If
you type git foo <TAB> and there is a _git_foo() function in your
shell's environment, then the completion script will invoke that
function to perform completion; this works not only for commands but
for aliases as well. So for your alias you only need to "borrow" all
the "show"-subcommand-specific case arms from _git_stash() and place
them in a _git_ss() function, e.g. like this:
_git_ss () {
case "$cur" in
--*)
__gitcomp_builtin stash_show "$__git_diff_common_options"
;;
*)
__gitcomp_nl "$(__git stash list | sed -n -e 's/:.*//p')"
;;
esac
}
Add it to your ~/.bashrc, or to a separate file that you source from
your .bashrc; If you use bash-completion, then you don't even have to
touch you .bashrc: save that function to a file git-ss (dash, not
underscore!) in one of the directories scanned by bash-completion
($BASH_COMPLETION_USER_DIR, ~/.local/share/bash-completion/completions
or its XDG_DATA_HOME-equivalent) and it will be auto-loaded as needed.

How to use a line of hyphen to separate git command results within git alias in git-bash

I've already created a alias called info to display status, branch and log in git-bash. However, all the information was bunched up and somewhat annoying to read, so i wanted to make it easier on myself when reading it by adding a line of hyphens with new line above and below it. After trying many times, I can't get it to work. Therefore i'm seeking help here.
Here's what I tried before, trying to get one to work before copying it in between git branch and git log.
$ git config --global alias.info '!git status && echo && !printf -- '-%.0s' {1..80}; echo "" && echo && git branch && git log'
Below is what the result should look like.
git status result
-----------------------
git branch result
-----------------------
git log result
If the ! syntax doe not give the expected result, try and embed your commands in a shell function within your Git alias:
alias.info !f() { echo begin arg=$1/$2/end; }; f
Or even in a separate script:
git config --global alias.info '!sh info.sh'
The point is: if you can make it work in a regular shell script, you will be able to call it from an alias.
Or you can even name your script git-info (executable, no extension), and simply type:
git info
No alias needed there: any git-xxx script can be called as git xxx (if git-xxx is in your PATH)

Can a git alias be expanded like a bash alias?

If I set the alias alias gf='git fetch --prune'
I can enter it into my command line $ gf and by typing <ESC> <C-e> it will expand into $ git fetch --prune
If I set the git alias git config --global alias.f fetch --prune and type $ git f does git offer a way of expanding this alias?
From what I can tell the only way to know what $ git f will do when executed is by inspecting git's config beforehand.
Not really, considering git aliases can also include shell expansion definition aliases with positional parameters like "!f() { echo \"$1\" >> .gitignore; }; f"..
And that would be tricky to expand on the shell level.

How can I write a shell completion hook for a multi-word prefix?

Let's say I want to write a custom shell completion function that fires only on git checkout <tab>. I can write a custom hook for git completion like this:
complete -f -F _custom_completion_function git # bash
compctl -f -K _custom_completion_function git # zsh
But that will overwrite all of my existing git bash/zsh completion; I only want to change the behavior of git checkout.
What's the best strategy for achieving this?
This largely depends on your existing git completion setup. Chances are this already checks the first word on the command-line when deciding what to do. Can't it just call a separate function if that first word is "checkout".
For zsh, I'd recommend not using the ancient compctl completion system. If you use the newer system (by running autoload -U compinit; compinit), then the git completion included with zsh allows you to define your own _git-checkout function. Define that and it'll take precedence over the one zsh includes.

Resources