【问题标题】:Why is this ZSH function not setting the variables, and outputting a git command instead?为什么这个 ZSH 函数不设置变量,而是输出一个 git 命令?
【发布时间】:2017-02-22 21:15:19
【问题描述】:

尝试创建一个自定义的git 函数来检查一个分支与另一个分支之间的距离。逻辑有效,如果我在终端中逐行复制/粘贴它就有效。

但是,将其放入我的 .zshrc 不会:

function gba() {
  branch="$(git rev-parse --abbrev-ref HEAD)"
  counts_str="$(git rev-list --left-right --count origin/dev...$branch)"
  counts=(${(ps:\t:)${counts_str}})
  behind=$counts[1]
  ahead=$counts[2]

  echo "$branch behind $behind commits, ahead $ahead commits"
}

另外,如果我在脚本中运行,添加#!/bin/zsh 并使用zsh gba.sh 执行它可以工作。

当我将它放在我的.zshrc 中时(并确保我打开了一个新的终端窗口),它会输出所有git 远程分支。

有什么想法吗?我想把它放在我的.zshrc 中,所以我没有单独的脚本文件,我想只用gba 或类似的别名来运行它。

调查结果

根据建议,我运行了一些操作来查看在我的 .zshrc 中直接定义 gba 时如何解释:

15:33:41 ~$ which gba
gba: aliased to git branch -a
15:33:46 ~$ declare -f gba
gba () {
  branch="$(git rev-parse --abbrev-ref HEAD)"
  counts_str="$(git rev-list --left-right --count origin/dev...$branch)"
  counts=(${(ps:\t:)${counts_str}})
  behind=$counts[1]
  ahead=$counts[2]
  echo "$branch behind $behind commits, ahead $ahead commits"
}
15:34:04 ~$ (set -x; gba)
+-zsh:3> git branch -a
fatal: Not a git repository (or any of the parent directories): .git

解决方案

原来我没有意识到我在.zshrc 中启用了git oh-my-zsh 插件:

plugins=(git)

这会加载大量别名(我知道,但我认为我已禁用它。)因此评论该行使我的 gba 函数完美运行。 oh-my-zsh git 别名很好,但我宁愿学习完整的命令,然后如果我想手动添加别名。

【问题讨论】:

  • 请注意,我正在创建一个gba.sh 脚本,并将在我的.zshrc 中创建一个别名
  • 顺便说一句,全大写的变量名并不理想。 POSIX 为 shell 内置变量和对系统有意义的环境变量指定全大写名称,保留至少一个字符的名称以供应用程序使用 - 这意味着如果您使用小写名称,则不会有覆盖重要内容的风险因为失误。 (使用与环境变量匹配的名称设置 shell 变量会自动覆盖后者,因此环境变量命名约定也必然适用于 shell 变量,就避免冲突而言)。
  • BRANCH="$`git ...`" 看起来像是一个错字。 BRANCH=$(git ...) 代替。
  • 所以,如果我可以提出一些建议 - 在您的 .zshrc 中定义脚本;获取它或打开一个新的 shell 窗口;然后提供declare -f gba(set -x; gba) 的输出。
  • 啊,所以你有一个别名来掩盖你的功能!

标签: git shell zsh oh-my-zsh zshrc


【解决方案1】:

问题就在这里:

15:33:41 ~$ which gba
gba: aliased to git branch -a

...还有一个别名gba,所以你的函数没有被调用。运行unalias gba 将其删除。


顺便说一句,set -x 输出是一个重要线索:

15:34:04 ~$ (set -x; gba)
+-zsh:3> git branch -a
fatal: Not a git repository (or any of the parent directories): .git

...因为git branch -a 不存在于函数中的任何地方,所以这个定义必须来自其他地方。

【讨论】: