感叹号在git配置别名中的含义是什么?

Vin*_*tge 25 git

我只看到一个git config命令如下:

git config --global alias.out \!"git fetch; git cherry origin/HEAD -v"
Run Code Online (Sandbox Code Playgroud)

这是什么意思?它等于这个:

git config --global alias.out '!git fetch; git cherry origin/HEAD -v',
Run Code Online (Sandbox Code Playgroud)

我对感叹号感到困惑,任何帮助将不胜感激.

小智 27

git-config手册:

如果别名扩展以感叹号为前缀,则将其视为shell命令.

  • “请注意,shell 命令将从存储库的顶级目录执行,该目录不一定是当前目录。” → 有用,即(例如) `git config --global alias.conf "!cat .git/config"` (4认同)

Gab*_*les 8

获得最多支持的答案只是说!git 别名成为“shell 命令”。那么……这是什么意思!?这直接引出了我的后续问题:

将 git 别名作为“shell 命令”执行是什么意思和作用?

@Frank Nocke在他的评论中慷慨地回答了这个问题。他的评论确实应该是另一个答案(所以我可以投票赞成),所以这是我尝试使其成为一个答案:

让我们再引用一下手册中的一些内容man git commit(我添加了重点):

如果别名扩展以感叹号为前缀,它将被视为 shell 命令。例如定义alias.new = !gitk --all --not ORIG_HEAD,调用git new相当于运行shell命令gitk --all --not ORIG_HEAD。请注意,shell 命令将从存储库的顶级目录执行,该目录不一定是当前目录。 GIT_PREFIX设置为git rev-parse --show-prefix从原始当前目录运行返回。看git-rev-parse(1)

另请参阅(感谢@Martin C. 指出这一点!): https: //git-scm.com/book/en/v2/Git-Basics-Git-Aliases,其中写着(添加了强调):

正如您所知,Git 只是将新命令替换为您为其指定的任何别名。但是,也许您想运行外部命令,而不是 Git 子命令。在这种情况下,您可以使用一个字符来启动该命令!如果您编写自己的与 Git 存储库一起使用的工具,这非常有用。我们可以通过别名 git Visual 来运行来演示gitk

$ git config --global alias.visual '!gitk'
Run Code Online (Sandbox Code Playgroud)

因此,!表示 git 别名正在访问常规 shell 命令而不是git 子命令,并且它还会导致 git在 git 存储库的根目录而不是您当前所在的目录中执行此 shell 命令。

因此,如果您运行此命令来为您提供一个 git 别名,git add并且git commit在一个git add-commit命令(source)中:

$ git config --global alias.visual '!gitk'
Run Code Online (Sandbox Code Playgroud)

...然后你会在你的~/.gitconfig文件中得到这个:

git config --global alias.add-commit '!git add -A && git commit'
Run Code Online (Sandbox Code Playgroud)

现在您可以像这样使用该别名:

[alias]
    add-commit = !git add -A && git commit
Run Code Online (Sandbox Code Playgroud)

该别名的运行方式就好像它是在 git 存储库的根目录中运行的常规 shell 命令一样,所以这看起来就像这样做:

git add-commit -m 'My commit message'
Run Code Online (Sandbox Code Playgroud)

因此,如果您不是 git 别名的忠实粉丝,而只想将其设为 bash 函数,则可以通过将以下内容添加到文件底部来实现~/.bashrc

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"
Run Code Online (Sandbox Code Playgroud)

然后像这样运行它(注意后面的额外破折号git):

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"
}
Run Code Online (Sandbox Code Playgroud)

或者,在您的文件夹(例如 at )git-add-commit内调用的文件中将其作为独立的可执行 bash 脚本,并在顶部使用 shebang 行,然后您可以运行与 git 别名相同的命令,而无需使用 OUT “git”后面的连字符,如下所示:PATH~/bin/git-add-commit#!/usr/bin/env bash

git-add-commit -m 'My commit message'
Run Code Online (Sandbox Code Playgroud)

这是有效的,因为git可执行文件显然会扫描变量中的所有目录PATH以查找所有名为的可执行文件git-ANYTHING,并允许它们作为git ANYTHING.

也可以看看:

  1. 有没有一种方法可以通过一个命令获取 git 根目录?
  2. Git 在一个命令中添加和提交
  3. ***** https://git-scm.com/book/en/v2/Git-Basics-Git-Aliases


Duc*_*Chi 5

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

但是,也许您想运行外部命令,而不是 Git 子命令。在这种情况下,您可以使用 ! 来启动命令。特点

所以如果你只想使用 git子命令,则不需要使用!这里。

但如果你想使用 git 命令/外部命令,那么你需要 !。