The most-upvoted answer says only that the !
makes the git alias a "shell command". So...what does that mean!? That simply begs my immediate follow-up question:
What does executing a git alias as a "shell command" mean and do?
@Frank Nocke graciously answers that question in his comment here. His comment really should be another answer (so I could have upvoted it), so here is my attempt at making it an answer:
Let's quote some more of the manual from man git commit
(my emphasis added):
If the alias expansion is prefixed with an exclamation point, it will be treated as a shell command. For example, defining alias.new = !gitk --all --not ORIG_HEAD
, the invocation git new
is equivalent to running the shell command gitk --all --not ORIG_HEAD
. Note that shell commands will be executed from the top-level directory of a repository, which may not necessarily be the current directory. GIT_PREFIX
is set as returned by running git rev-parse --show-prefix
from the original current directory. See git-rev-parse(1)
.
See also (thank you @Martin C. for pointing this out!): https://git-scm.com/book/en/v2/Git-Basics-Git-Aliases, which says (emphasis added):
As you can tell, Git simply replaces the new command with whatever you alias it for. However, maybe you want to run an external command, rather than a Git subcommand. In that case, you start the command with a !
character. This is useful if you write your own tools that work with a Git repository. We can demonstrate by aliasing git visual to run gitk
:
$ git config --global alias.visual '!gitk'
So, the !
indicates that the git alias is accessing a regular shell command instead of a git subcommand, and it also causes git to execute this shell command in the root directory of the git repository instead of in the directory you are currently in.
So, if you run this command to give you a git alias to git add
and git commit
in one git add-commit
command (source):
git config --global alias.add-commit '!git add -A && git commit'
...then you'll get this in your ~/.gitconfig
file:
[alias]
add-commit = !git add -A && git commit
Now you can use that alias like this:
git add-commit -m 'My commit message'
And that alias is run as though it was a regular shell command run at the root dir of the git repo, so it's kind of like doing this apparently:
starting_dir="$PWD"
# see: https://mcmap.net/q/13693/-is-there-a-way-to-get-the-git-root-directory-in-one-command
repo_root_dir="$(git rev-parse --show-toplevel)"
cd "$repo_root_dir"
git add -A && git commit -m 'My commit message'
cd "$starting_dir"
So, if you're not a big fan of git aliases, and just want to make it a bash function instead, you could do that by adding the following to the bottom of your ~/.bashrc
file instead:
git-add-commit() {
starting_dir="$PWD"
# See: https://mcmap.net/q/13693/-is-there-a-way-to-get-the-git-root-directory-in-one-command
repo_root_dir="$(git rev-parse --show-toplevel)"
cd "$repo_root_dir"
git add -A
git commit "$@"
cd "starting_dir"
}
Then run it like this (notice the extra dash after git
):
git-add-commit -m 'My commit message'
OR, make that a stand-alone executable bash script in a file called git-add-commit
inside a folder in your PATH
(such as at ~/bin/git-add-commit
), and with the #!/usr/bin/env bash
shebang line at the top, and then you can run the command the same as the git alias, withOUT the hyphen after "git", like this:
git add-commit -m 'My commit message'
This works because the git
executable apparently scans all directories in your PATH
variable for all executables named git-ANYTHING
and allows them to be run as git ANYTHING
.
See also:
- Is there a way to get the git root directory in one command?
- Git add and commit in one command
- *****https://git-scm.com/book/en/v2/Git-Basics-Git-Aliases
lg1 = log --graph --format...
you can't alias that as though it's a subcommand (lg = lg1
will not work), but you need to use!
as inlg = !"git lg1"
– Md