有没有办法象征性地引用当前分支的名称?

Is there a way to symbolically refer to the NAME of the current branch?

通常,当我在 Git 命令行中 "need" 一个分支名称时,我会重新输入名称(在可用时使用自动完成),或者 select+用鼠标右键单击。这感觉太慢和重复了。

这里有两个使用 NAME 的例子。我不是在寻找 git 别名,除非这样可以推广到所有命令。即使答案是 "no",有关如何改进此类工作流程的提示也被视为次要信息 - 只要确保先回答上述问题即可。

示例 #1

变基到不同的提交。

git checkout -b mybranch                    # on 'mybranch'
touch x; git commit -mx -- x                # on 'mybranch'

# Is is possible to avoid 'mybranch' here?
# Using HEAD will switch from 'mybranch' to a commit.
git rebase --onto otherbranch mybranch^ mybranch

示例 #2

比较本地和远程分支,假定标准同名。

# Standard way..
git diff origin/mybranch

# I often find myself wanting to do something like..
git diff origin/NAME
git log -1 origin/NAME

为了完整起见,我将对其进行编辑以添加:对于特定案例当前分支的上游(origin/NAME 在您的 git log 示例中), 使用 @{u} 是可行的方法。也就是说,如果你在你的分支 xyz 上,并且它的上游是 origin/xyz,你可以 运行:

git diff @{u}

或:

git log @{u}..

(注意:某些 shell 可能需要您引用大括号)。

注意,如果你当前分支xyz的上游是origin/abcxyz@{u}@{u}表示origin/abc,而不是origin/xyz !这通常是您想要的;使用 origin/$(git <em>command</em>) 将会得到另一个答案,即 origin/xyz 而不是 origin/abc 对于这种情况。

一个(本地)分支的上游可以另一个(本地)分支:如果你当前分支xyz的上游是你自己的分支ghi, @{u} 只是一种写法 ghi 不用多想。当然,您当前的分支必须有一个上游集。

你的每个分支名称最多可以有一个上游:你要么有一个,要么你有none。要设置新的上游,请使用 git branch --set-upstream-to=<em>upstream</em>。要完全删除上游(尽管很少有任何原因),请使用 git branch --unset-upstream。这两个命令也可以使用分支名称;默认情况下,两者都在当前分支上运行。

一般情况

What is a 'lazy' way to refer to the expanded NAME of the current branch in git commands?

有办法,但是很糟糕:用HEAD.

这个词

它糟糕的原因是它适用于某些命令而不适用于其他命令:

Is there built-in and consistent support for such, or does it require shell expansion?

要使其适用于 所有 命令,您需要 shell 扩展。

基本上,每当 Git 查找名称 HEAD 时,它都可以通过以下两个问题之一来完成:

  1. HEAD指的是什么分支名称?

    这四个命令几乎都完成相同的工作,只是方式略有不同:1

    git symbolic-ref HEAD
    git symbolic-ref --short HEAD
    git rev-parse --symbolic-full-name HEAD
    git rev-parse --abbrev-ref HEAD
    

    其他 Git 命令有时会在内部使用这些命令之一或等效命令来查找分支名称。

  2. commit(hash ID)HEAD指的是什么?

    命令:

    git rev-parse HEAD
    

    询问并回答这个问题。

    其他 Git 命令有时也会在内部执行此操作。

作为一个相当有趣的例子,git push 命令会询问 两个 个问题:

git push -u origin HEAD

将查找 name,就像 git symbolic-ref HEAD,然后还会查找 hash ID,就像如果按 git rev-parse HEAD,将 运行 相当于 shell-扩展命令:

git push -u origin $(git rev-parse HEAD):$(git symbolic-ref HEAD)

如果您需要控制 发生哪个 扩展,明确地说,您必须在 [=137= 中的正确位置使用您自己的 $(git ...) 命令]命令。


1git symbolic-ref 变体生成完整或缩写的分支名称,但当您处于分离头模式时 失败 . git rev-parse 变体生成完整或缩写的分支名称,但在分离头模式下仅打印 HEAD

这两个简写几乎可以满足您的需求:

@    # this is the same as writing HEAD
@{u} # this is the same writing origin/{your-branch-name}

有了这个,您可以简单地实现示例 2:

git diff @{u}
git log -1 @{u}

示例 1 更难,因为正如您所指出的,HEAD 将在 rebase 期间分离。但如果你分离,这并不是什么大不了的事,因为你可以很容易地恢复:

git rebase --onto otherbranch @^ @ # detached on a new commit
git checkout -B mybranch # reset mybranch to point to the current commit

@ 符号的好处在于它很容易与 ^ 和 ~ 字符一起输入。例如,如果你有 5 个提交,你想移动到另一个分支而不是 1 个,输入 @~5 几乎和输入 @^ 一样容易。