如何确定 post-rewrite hook 中的当前分支

How to determine current branch in post-rewrite hook

背景:我想要 post-rewrite 挂钩,它会自动将更改推送到上游存储库(我是它的唯一用户,我用它在不同机器之间共享我自己的工作)。 post-rewrite 是唯一一次我必须使用强制推送,所以我希望它是这样的:

currentBranch=...
git push [origin] $currentBranch -f

在其他问题中,建议使用 git rev-parse --abbrev-ref HEADgit symbolic-ref --short HEAD。当在 post-rewrite 脚本之外使用时,它们都可以正确确定当前分支,但不能在脚本内部使用。如果我将 post-rewrite 脚本设置为:

#!/bin/bash
git rev-parse --abbrev-ref HEAD
git symbolic-ref --short HEAD

控制台输出将是:

$ git rebase [...]
First, rewinding head to replay your work on top of it...
Applying: [...]
HEAD
fatal: ref HEAD is not a symbolic ref
$ git rev-parse --abbrev-ref HEAD
myBranch
$ git symbolic-ref --short HEAD
myBranch

编辑:

复制我的问题的简短脚本:

# setup the repo
git init test
cd test
echo "git rev-parse --abbrev-ref HEAD" >> .git/hooks/post-rewrite
echo "git symbolic-ref --short HEAD" >> .git/hooks/post-rewrite
chmod a+x .git/hooks/post-rewrite

# create the root branch
git checkout -b root
touch test
git add test
git commit -m "test commit for root" test

# branch out
git checkout -b test1
touch test1
git add test1
git commit -m "test commit 1" test1

# branch out again
git checkout -b test2 root
touch test2
git add test2
git commit -m "test commit 2" test2

# rebase
git rebase test1
git rev-parse --abbrev-ref HEAD
git symbolic-ref --short HEAD

预期输出为(删除之前的消息后):

First, rewinding head to replay your work on top of it...
Applying: test commit 2
test2
test2
test2
test2

相反,我得到

First, rewinding head to replay your work on top of it...
Applying: test commit 2
HEAD
fatal: ref HEAD is not a symbolic ref
test2
test2

根据 Filip Wolski 的附加信息(编辑和评论)和人工调查,我现在认为这是 git 中的一个错误。

当您调用非交互式变基时,git 运行 是它的 git-rebase--am 脚本(在 git --exec-path 目录之外),它与当前分支分离并使用 git am ... --rebasing ... 应用补丁(由 git format-patch 使用各种标志生成)。

这里有一个例外:如果你使用 keep-empty-commits 标志,脚本使用 git cherry-pick 复制提交,包括空提交。

无论如何,在 git-rebase--am 结束时,脚本返回分支并调整分支标签。但是,这是在 git am 脚本完成并返回之后。是 git am 脚本调用了 post-rewrite 挂钩,而且在 "current branch" 概念恢复之前发生得太快了。

这似乎造成 两个 个错误:

  • 如果您使用 -k--keep-empty 标志,post-rewrite 脚本根本不会 运行。
  • 否则你会遇到这种情况,其中 post-rewrite hook 运行s,但处于分离头状态。

在我看来,$(git --exec-path)/git-am 需要保留笔记调整和 post-重写 git-rebase--am 脚本的挂钩。

在错误修复之前,一种解决方法是使用交互式 rebase(您可以将环境变量 GIT_SEQUENCE_EDITOR 设置为 :true 以使其 运行没有编辑会话)。