简体   繁体   中英

What does the exclamation mark mean in git config alias?

I just see a git config command as below:

git config --global alias.out \!"git fetch; git cherry origin/HEAD -v"

what does it mean? Is it equal to this:

git config --global alias.out '!git fetch; git cherry origin/HEAD -v',

I am confused with the exclamation mark,any help will be appreciated.

From the git-config manual :

If the alias expansion is prefixed with an exclamation point, it will be treated as a shell command.

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://stackoverflow.com/a/957978/4561887
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://stackoverflow.com/a/957978/4561887
    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:

  1. Is there a way to get the git root directory in one command?
  2. Git add and commit in one command
  3. ***** https://git-scm.com/book/en/v2/Git-Basics-Git-Aliases

From https://git-scm.com/book/en/v2/Git-Basics-Git-Aliases

However, maybe you want to run an external command, rather than a Git subcommand. In that case, you start the command with a ! character

So if you only want to use git subcommand , you don't need to use ! here.

But if you want to use git command/external command, then you need !.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM