让我们假设我有以下本地存储库和一个像这样的提交树:
master --> a
\
\
develop c --> d
\
\
feature f --> g --> h
Master是我的,这是最新的稳定发布代码,develop是我的,这是“下一个”发布代码,feature是一个正在准备开发的新功能。
使用钩子,我希望能够拒绝推送功能到我的远程存储库,除非commit f是develop HEAD的直接后代。也就是说,提交树看起来是这样的,因为feature已经基于d。
master --> a
\
\
develop c --> d
\
\
feature f --> g --> h
那么是否有可能:
识别特征的父分支?
确定父分支中的提交f是哪个分支的后代?
从那里,我将检查父分支的HEAD是什么,并查看f前任是否匹配父分支HEAD,以确定该特性是否需要重基。
一个rephrasal
这个问题的另一种表达方式是“驻留在当前分支以外的分支上的最近的提交是什么?是哪个分支?”
一个解决方案
您可以使用一点命令行魔法找到它
git show-branch \
| sed "s/].*//" \
| grep "\*" \
| grep -v "$(git rev-parse --abbrev-ref HEAD)" \
| head -n1 \
| sed "s/^.*\[//"
AWK:
git show-branch -a \
| grep '\*' \
| grep -v `git rev-parse --abbrev-ref HEAD` \
| head -n1 \
| sed 's/[^\[]*//' \
| awk 'match($0, /\[[a-zA-Z0-9\/.-]+\]/) { print substr( $0, RSTART+1, RLENGTH-2 )}'
下面是它的工作原理:
Display a textual history of all commits, including remote branches.
Ancestors of the current commit are indicated by a star. Filter out everything else.
Ignore all the commits in the current branch.
The first result will be the nearest ancestor branch. Ignore the other results.
Branch names are displayed [in brackets]. Ignore everything outside the brackets, and the brackets.
Sometimes the branch name will include a ~# or ^# to indicate how many commits are between the referenced commit and the branch tip. We don't care. Ignore them.
结果是
运行上面的代码
A---B---D <-master
\
\
C---E---I <-develop
\
\
F---G---H <-topic
如果你从H运行它会给你发展,如果你从I运行它会给你掌握。
代码可以作为要点提供。
Mark Reed的解决方案基本上是正确的。但是,请注意,提交行不仅应该包含星号,而且应该以星号开头!否则,包含星号的提交消息也包含在匹配的行中。所以它应该是:
git show-branch——| awk - f '[]^~[]' '/^\*/ && !/'"$ current_branch”/{打印2美元;退出}'
或者是更长的版本:
git show-branch -a |
awk '^\*' | # we want only lines that contain an asterisk
awk -v "$current_branch" | # but also don't contain the current branch
head -n1 | # and only the first such line
sed 's/.*\[\(.*\)\].*/\1/' | # really, just the part of the line between []
sed 's/[\^~].*//' # and with any relative refs (^, ~n) removed`