假设我有以下本地存储库,其中包含如下提交树:
master --> a
\
\
develop c --> d
\
\
feature f --> g --> h
Run Code Online (Sandbox Code Playgroud)
master是我的这是最新的稳定版本代码,develop是我的这个'下一个'版本代码,feature是一个正在准备的新功能develop.
我希望能够使用钩子在我的远程仓库上做什么,feature除非提交f是developHEAD 的直接后代,否则推送被拒绝.即提交树看起来像这样,因为功能已经git rebase打开d.
master --> a
\
\
develop c --> d
\
\
feature f --> g --> h
Run Code Online (Sandbox Code Playgroud)
那么有可能:
feature?f是后代的?从那里我将检查父分支的HEAD是什么,并查看f前任是否与父分支HEAD匹配,以确定该特征是否需要重新定位.
Chr*_*sen 331
假设远程存储库有一个develop分支的副本(你的初始描述在本地存储库中描述它,但听起来它也存在于远程),你应该能够实现我想你想要的,但是方法与你想象的有点不同.
Git的历史基于提交的DAG.分支(和"refs"一般)只是瞬态标签,指向不断增长的提交DAG中的特定提交.因此,分支之间的关系可以随时间变化,但提交之间的关系不会.
---o---1 foo
\
2---3---o bar
\
4
\
5---6 baz
Run Code Online (Sandbox Code Playgroud)
它看起来像是baz基于(旧版本)bar?但是如果我们删除bar怎么办?
---o---1 foo
\
2---3
\
4
\
5---6 baz
Run Code Online (Sandbox Code Playgroud)
现在它看起来像是baz基于foo.但是祖先baz并没有改变,我们只是删除了一个标签(以及由此产生的悬空提交).如果我们添加新标签4怎么办?
---o---1 foo
\
2---3
\
4 quux
\
5---6 baz
Run Code Online (Sandbox Code Playgroud)
现在它看起来像是baz基于quux.尽管如此,祖先并没有改变,只有标签改变了.
但是,如果我们问:"是犯6犯的后代3?"(假设3和6充满SHA-1提交的名称),那么答案是"是",是否bar与quux标签存在与否.
那么,您可以提出诸如"被推送的提交是开发分支当前提示的后代吗?"之类的问题,但是您无法可靠地询问"推送提交的父分支是什么?".
一个看似接近你想要的最可靠的问题是:
对于所有被推送的提交的祖先(不包括当前的开发提示及其祖先),其目前的开发方式是作为父级:
- 至少存在一个这样的提交吗?
- 所有这些提交单父提交?
哪个可以实现为:
pushedrev=...
basename=develop
if ! baserev="$(git rev-parse --verify refs/heads/"$basename" 2>/dev/null)"; then
echo "'$basename' is missing, call for help!"
exit 1
fi
parents_of_children_of_base="$(
git rev-list --pretty=tformat:%P "$pushedrev" --not "$baserev" |
grep -F "$baserev"
)"
case ",$parents_of_children_of_base" in
,) echo "must descend from tip of '$basename'"
exit 1 ;;
,*\ *) echo "must not merge tip of '$basename' (rebase instead)"
exit 1 ;;
,*) exit 0 ;;
esac
Run Code Online (Sandbox Code Playgroud)
这将涵盖您想要限制的一些内容,但可能不是所有内容.
作为参考,这是一个扩展的示例历史:
A master
\
\ o-----J
\ / \
\ | o---K---L
\ |/
C--------------D develop
\ |\
F---G---H | F'--G'--H'
| |\
| | o---o---o---N
\ \ \ \
\ \ o---o---P
\ \
R---S
Run Code Online (Sandbox Code Playgroud)
上面的代码可以用来拒绝H并S同时接受H',J,K,或N,但它也接受L和P(它们涉及合并,但他们不合并的尖端发展).
要拒绝L和P,您可以更改问题并询问
对于所有被推送的提交的祖先(不包括当前的开发及其祖先):
- 有两个父母的任何承诺吗?
- 如果没有,至少有一个这样的提交是否有当前的发展其(唯一)父母的提示?
pushedrev=...
basename=develop
if ! baserev="$(git rev-parse --verify refs/heads/"$basename" 2>/dev/null)"; then
echo "'$basename' is missing, call for help!"
exit 1
fi
parents_of_commits_beyond_base="$(
git rev-list --pretty=tformat:%P "$pushedrev" --not "$baserev" |
grep -v '^commit '
)"
case "$parents_of_commits_beyond_base" in
*\ *) echo "must not push merge commits (rebase instead)"
exit 1 ;;
*"$baserev"*) exit 0 ;;
*) echo "must descend from tip of '$basename'"
exit 1 ;;
esac
Run Code Online (Sandbox Code Playgroud)
Joe*_*ler 222
另一种表达问题的方法是"当前分支以外的分支上最近的提交是什么,哪个分支是那个?"
您可以通过一点命令行魔术找到它
git show-branch -a \
| grep '\*' \
| grep -v `git rev-parse --abbrev-ref HEAD` \
| head -n1 \
| sed 's/.*\[\(.*\)\].*/\1/' \
| sed 's/[\^~].*//'
Run Code Online (Sandbox Code Playgroud)
运行上面的代码
A---B---D <-master
\
\
C---E---I <-develop
\
\
F---G---H <-topic
Run Code Online (Sandbox Code Playgroud)
develop如果你从H运行它,master如果你从我运行它会给你.
rcd*_*de0 99
你也可以尝试:
git log --graph --decorate
Run Code Online (Sandbox Code Playgroud)
NIK*_*C M 92
您只需运行该命令即可
git parent
找到分支的父级,如果你把@Joe Chrysler的答案添加为git别名.它将简化使用.
使用任何文本编辑器打开位于"〜/ .gitconfig"的gitconfig文件.
vim ~/.gitconfig
Run Code Online (Sandbox Code Playgroud)
在文件中添加以下别名命令:
[alias]
parent = "!git show-branch | grep '*' | grep -v \"$(git rev-parse --abbrev-ref HEAD)\" | head -n1 | sed 's/.*\\[\\(.*\\)\\].*/\\1/' | sed 's/[\\^~].*//' #"
Run Code Online (Sandbox Code Playgroud)
保存并退出编辑器.
运行命令 "~/.gitconfig"
而已!
Dan*_*ach 52
我有一个解决你的整体问题的方法(确定是否feature来自尖端develop),但它不能使用你概述的方法.
您可以使用git branch --contains列出从尖端下降的所有分支develop,然后使用grep以确保feature它们之中.
git branch --contains develop | grep "^ *feature$"
Run Code Online (Sandbox Code Playgroud)
如果它是其中之一,它将打印" feature"到标准输出并返回代码为0.否则,它将不打印任何内容并返回代码为1.
Mur*_*uru 43
这对我来说很好.
git show-branch | grep '*' | grep -v "$(git rev-parse --abbrev-ref HEAD)" | head -n1 | sed 's/.*\[\(.*\)\].*/\1/' | sed 's/[\^~].*//'
Run Code Online (Sandbox Code Playgroud)
礼貌答案来自:@droidbot和@Jistanidiot
Ric*_*tze 42
要点:
为什么有人想阅读这篇长文章?因为虽然之前的答案清楚地理解了原始问题的问题,但它们缺乏正确/有意义的结果;或准确地解决不同的问题。
请随意回顾第一部分;它解决了“找到某些东西”的问题,并且应该突出问题的范围。对于某些人来说,这可能就足够了。
这将向您展示一种从 git 中提取正确且有意义的结果的方法(您可能不喜欢它们),并演示一种将您对约定的知识应用到这些结果中以提取您真正想要的内容的方法。
以下各节涵盖:
git show-branch.git show-branch正如已经提到的,git 不跟踪分支之间的关系;而是跟踪分支之间的关系。分支只是引用提交的名称。在官方 git 文档和其他来源中,我们经常会遇到一些误导性的图表,例如:
A---B---C---D <- master branch
\
E---F <- work branch
Run Code Online (Sandbox Code Playgroud)
让我们更改图表的形式和分层暗示名称以显示等效图表:
E---F <- jack
/
A---B
\
C---D <- jill
Run Code Online (Sandbox Code Playgroud)
图表(以及 git)完全没有告诉我们哪个分支首先被创建(因此,哪个分支是从另一个分支分支出来的)。
master第一张图中的父项是work惯例问题。
所以
首先,我必须首先感谢乔·克莱斯勒的回应、这里的其他回应以及周围的许多评论/建议;他们启发了我,为我指明了道路!
请允许我重新措辞乔的措辞,考虑与最近的提交相关的多个分支(它发生了!):
“当前分支之外的分支上最近的提交是什么?那是哪个分支?”
或者,换句话说:
给定一个分支:考虑最接近 (可能是)由其他分支共享的
B提交:除了 之外,还有哪些分支在其提交历史记录中?CB'HEADCB'HEADBC
预先道歉;人们似乎更喜欢俏皮话。请随意提出(可读/可维护的)改进建议!
#!/usr/local/bin/bash
# git show-branch supports 29 branches; reserve 1 for current branch
GIT_SHOW_BRANCH_MAX=28
CURRENT_BRANCH="$(git rev-parse --abbrev-ref HEAD)"
if (( $? != 0 )); then
echo "Failed to determine git branch; is this a git repo?" >&2
exit 1
fi
##
# Given Params:
# EXCEPT : $1
# VALUES : $2..N
#
# Return all values except EXCEPT, in order.
#
function valuesExcept() {
local except=$1 ; shift
for value in "$@"; do
if [[ "$value" != "$except" ]]; then
echo $value
fi
done
}
##
# Given Params:
# BASE_BRANCH : $1 : base branch; default is current branch
# BRANCHES : [ $2 .. $N ] : list of unique branch names (no duplicates);
# perhaps possible parents.
# Default is all branches except base branch.
#
# For the most recent commit in the commit history for BASE_BRANCH that is
# also in the commit history of at least one branch in BRANCHES: output all
# BRANCHES that share that commit in their commit history.
#
function nearestCommonBranches() {
local BASE_BRANCH
if [[ -z "${1+x}" || "$1" == '.' ]]; then
BASE_BRANCH="$CURRENT_BRANCH"
else
BASE_BRANCH="$1"
fi
shift
local -a CANDIDATES
if [[ -z "${1+x}" ]]; then
CANDIDATES=( $(git rev-parse --symbolic --branches) )
else
CANDIDATES=("$@")
fi
local BRANCHES=( $(valuesExcept "$BASE_BRANCH" "${CANDIDATES[@]}") )
local BRANCH_COUNT=${#BRANCHES[@]}
if (( $BRANCH_COUNT > $GIT_SHOW_BRANCH_MAX )); then
echo "Too many branches: limit $GIT_SHOW_BRANCH_MAX" >&2
exit 1
fi
local MAP=( $(git show-branch --topo-order "${BRANCHES[@]}" "$BASE_BRANCH" \
| tail -n +$(($BRANCH_COUNT+3)) \
| sed "s/ \[.*$//" \
| sed "s/ /_/g" \
| sed "s/*/+/g" \
| egrep '^_*[^_].*[^_]$' \
| head -n1 \
| sed 's/\(.\)/\1\n/g'
) )
for idx in "${!BRANCHES[@]}"; do
## to include "merge", symbolized by '-', use
## ALT: if [[ "${MAP[$idx]}" != "_" ]]
if [[ "${MAP[$idx]}" == "+" ]]; then
echo "${BRANCHES[$idx]}"
fi
done
}
# Usage: gitr [ baseBranch [branchToConsider]* ]
# baseBranch: '.' (no quotes needed) corresponds to default current branch
# branchToConsider* : list of unique branch names (no duplicates);
# perhaps possible (bias?) parents.
# Default is all branches except base branch.
nearestCommonBranches "${@}"
Run Code Online (Sandbox Code Playgroud)
git show-branch对于git show-branch --topo-order feature/g hotfix master release/2 release/3 feature/d,输出将类似于:
! [feature/g] TEAM-12345: create X
* [hotfix] TEAM-12345: create G
! [master] TEAM-12345: create E
! [release/2] TEAM-12345: create C
! [release/3] TEAM-12345: create C
! [feature/d] TEAM-12345: create S
------
+ [feature/g] TEAM-12345: create X
+ [feature/g^] TEAM-12345: create W
+ [feature/d] TEAM-12345: create S
+ [feature/d^] TEAM-12345: create R
+ [feature/d~2] TEAM-12345: create Q
...
+ [master] TEAM-12345: create E
* [hotfix] TEAM-12345: create G
* [hotfix^] TEAM-12345: create F
*+ [master^] TEAM-12345: create D
+*+++ [release/2] TEAM-12345: create C
+*++++ [feature/d~8] TEAM-12345: create B
Run Code Online (Sandbox Code Playgroud)
几点:
X之间的关系(或缺乏) 。XBASE_BRANCHBRANCHES其中不包括BASE_BRANCHN为BRANCH_COUNT,其大小为BRANCHES; 它不包括BASE_BRANCHgit show-branch --topo-order $BRANCHES $BASE_BRANCH:
BRANCHES仅包含唯一名称(假定有效),因此名称将与输出的标题行进行 1-1 映射,并对应于分支/提交矩阵的前 N 列。BASE_BRANCH不在其中,BRANCHES
因此它将是标题行的最后一个,并且对应于最后一列分支/提交矩阵。tail:从行开始N+3;扔掉第一N+2行:N 个分支 + 基本分支 + 分隔行---..。sed:这些可以合并为一个......但为了清楚起见分开
*用。。。来代替+; 基本分支始终位于最后一列,这就足够了。另外,如果不管它,它会经历bash
路径名扩展,这总是很有趣*egrep: grep 用于映射到至少一个分支 ( [^_]) 和 BASE_BRANCH ( [^_]$) 的提交。也许基本分支模式应该是\+$?head -n1:获取第一个剩余提交sed:将分支/提交矩阵的每个字符分隔为单独的行。MAP,此时我们有两个数组:
BRANCHES: 长度NMAP:length N+1:第一个N元素1-1与BRANCHES,最后一个元素对应于BASE_BRANCH。BRANCHES(这就是我们想要的,而且更短)并检查MAP: output BRANCH[$idx]if MAP[$idx]is中的相应元素+。考虑以下有点做作的示例图:
master是,当我完成这件事后,它就脱颖而出了。 J <- feature/b
/
H
/ \
/ I <- feature/a
/
D---E <- master
/ \
/ F---G <- hotfix
/
A---B---C <- feature/f, release/2, release/3
\ \
\ W--X <- feature/g
\
\ M <- support/1
\ /
K---L <- release/4
\
\ T---U---V <- feature/e
\ /
N---O
\
P <- feature/c
\
Q---R---S <- feature/d
Run Code Online (Sandbox Code Playgroud)
假设脚本在可执行文件中gitr,然后运行:
gitr <baseBranch>
Run Code Online (Sandbox Code Playgroud)
对于不同的分支,B我们得到以下结果:
| 给定B | 共享提交 C | 历史上有 C 的分支 !B? |
|---|---|---|
| 特征/一个 | H | 特征/b |
| 特征/b | H | 特征/一个 |
| 特征/c | 磷 | 特征/d |
| 特征/d | 磷 | 特征/c |
| 特征/e | 氧 | 特征/c,特征/d |
| 特征/f | C | 功能/a、功能/b、功能/g、修补程序、主版本、版本/2、版本/3 |
| 特征/克 | C | 功能/a、功能/b、功能/f、修补程序、主版本、版本/2、版本/3 |
| 修补程序 | D | 功能/a、功能/b、主控 |
| 掌握 | D | 功能/a、功能/b、修补程序 |
| 发布/2 | C | 功能/a、功能/b、功能/f、功能/g、修补程序、主版本、发行版/3 |
| 发布/3 | C | 功能/a、功能/b、功能/f、功能/g、修补程序、主版本、发行版/2 |
| 发布/4 | L | 功能/c、功能/d、功能/e、支持/1 |
| 支持/1 | L | 功能/c、功能/d、功能/e、发布/4 |
[在此阶段呈现,因为它最适合此时的最终脚本。 本节不是必需的,请随意跳到后面。]
git show-branch其分支机构数量仅限于 29 个。这对某些人来说可能是一个障碍(没有判断力,只是说!)。
在某些情况下,我们可以通过将分支分组为批次来改进结果。
这种机制并不完美,因为结果大小接近最大值 (29),预计它会失败。详情如下
#
# Remove/comment-out the function call at the end of script,
# and append this to the end.
##
##
# Given:
# BASE_BRANCH : $1 : first param on every batch
# BRANCHES : [ $2 .. $N ] : list of unique branch names (no duplicates);
# perhaps possible parents
# Default is all branches except base branch.
#
# Output all BRANCHES that share that commit in their commit history.
#
function repeatBatchingUntilStableResults() {
local BASE_BRANCH="$1"
shift
local -a CANDIDATES
if [[ -z "${1+x}" ]]; then
CANDIDATES=( $(git rev-parse --symbolic --branches) )
else
CANDIDATES=("$@")
fi
local BRANCHES=( $(valuesExcept "$BASE_BRANCH" "${CANDIDATES[@]}") )
local SIZE=$GIT_SHOW_BRANCH_MAX
local COUNT=${#BRANCHES[@]}
local LAST_COUNT=$(( $COUNT + 1 ))
local NOT_DONE=1
while (( $NOT_DONE && $COUNT < $LAST_COUNT )); do
NOT_DONE=$(( $SIZE < $COUNT ))
LAST_COUNT=$COUNT
local -a BRANCHES_TO_BATCH=( "${BRANCHES[@]}" )
local -a AGGREGATE=()
while (( ${#BRANCHES_TO_BATCH[@]} > 0 )); do
local -a BATCH=( "${BRANCHES_TO_BATCH[@]:0:$SIZE}" )
AGGREGATE+=( $(nearestCommonBranches "$BASE_BRANCH" "${BATCH[@]}") )
BRANCHES_TO_BATCH=( "${BRANCHES_TO_BATCH[@]:$SIZE}" )
done
BRANCHES=( "${AGGREGATE[@]}" )
COUNT=${#BRANCHES[@]}
done
if (( ${#BRANCHES[@]} > $SIZE )); then
echo "Unable to reduce candidate branches below MAX for git-show-branch" >&2
echo " Base Branch : $BASE_BRANCH" >&2
echo " MAX Branches: $SIZE" >&2
echo " Candidates : ${BRANCHES[@]}" >&2
exit 1
fi
echo "${BRANCHES[@]}"
}
repeatBatchingUntilStableResults "$@"
exit 0
Run Code Online (Sandbox Code Playgroud)
重复直到结果稳定
BRANCHES批次
GIT_SHOW_BRANCH_MAX(又名SIZE)元素nearestCommonBranches BASE_BRANCH BATCH如果聚合分支的数量超过最大值SIZE
并且进一步的批处理/处理无法减少该数量,则:
git show-branch或将基础分支与每个其他感兴趣的分支单独配对,为每对确定一个提交节点(合并基础);按提交历史顺序对合并基集进行排序,采用最近的节点,确定与该节点关联的所有分支。
我从事后的角度提出这一点。这可能确实是正确的方法。我正在前进;也许在当前主题之外还有价值。
nearestCommonBranches
您可能已经注意到,早期脚本中的核心函数回答的问题比问题 1 提出的要多。事实上,该函数回答了一个更普遍的问题:
给定一个分支和分支的
B有序集(无重复) (不在 中):考虑最接近(可能是)的提交,该提交由 中的分支共享:按照 P 的顺序,P 中的哪些分支有 C他们的提交历史?PBPCB'HEADCB'HEADP
选择P提供了偏见,或描述了(有限的)惯例。为了匹配您的偏见/惯例的所有特征可能需要额外的工具,这超出了本次讨论的范围。
不同的组织和实践的偏差有所不同,以下内容可能不适合您的组织。如果不出意外的话,也许这里的一些想法可以帮助您找到满足您需求的解决方案。
也许可以将偏差映射到正在使用的命名约定中,并从中提取出来。
P(那些其他分支名称)的偏见我们将在下一步中需要它,所以让我们看看通过正则表达式过滤分支名称可以做什么。
合并之前的代码和下面的新代码可作为要点:gitr
#
# Remove/comment-out the function call at the end of script,
# and append this to the end.
##
##
# Given Params:
# BASE_BRANCH : $1 : base branch
# REGEXs : $2 [ .. $N ] : regex(s)
#
# Output:
# - git branches matching at least one of the regex params
# - base branch is excluded from result
# - order: branches matching the Nth regex will appear before
# branches matching the (N+1)th regex.
# - no duplicates in output
#
function expandUniqGitBranches() {
local -A BSET[$1]=1
shift
local ALL_BRANCHES=$(git rev-parse --symbolic --branches)
for regex in "$@"; do
for branch in $ALL_BRANCHES; do
## RE: -z ${BSET[$branch]+x ... ; presumes ENV 'x' is not defined
if [[ $branch =~ $regex && -z "${BSET[$branch]+x}" ]]; then
echo "$branch"
BSET[$branch]=1
fi
done
done
}
##
# Params:
# BASE_BRANCH: $1 : "." equates to the current branch;
# REGEXS : $2..N : regex(es) corresponding to other to include
#
function findBranchesSharingFirstCommonCommit() {
if [[ -z "$1" ]]; then
echo "Usage: findBranchesSharingFirstCommonCommit ( . | baseBranch ) [ regex [ ... ] ]" >&2
exit 1
fi
local BASE_BRANCH
if [[ -z "${1+x}" || "$1" == '.' ]]; then
BASE_BRANCH="$CURRENT_BRANCH"
else
BASE_BRANCH="$1"
fi
shift
local REGEXS
if [[ -z "$1" ]]; then
REGEXS=(".*")
else
REGEXS=("$@")
fi
local BRANCHES=( $(expandUniqGitBranches "$BASE_BRANCH" "${REGEXS[@]}") )
## nearestCommonBranches can also be used here, if batching not used.
repeatBatchingUntilStableResults "$BASE_BRANCH" "${BRANCHES[@]}"
}
findBranchesSharingFirstCommonCommit "$@"
Run Code Online (Sandbox Code Playgroud)
让我们考虑一下有序集
P = { ^release/.*$ ^support/.*$ ^master$ }
假设脚本(所有部分)位于可执行文件中gitr,然后运行:
gitr <baseBranch> '^release/.*$' '^support/.*$' '^master$'
Run Code Online (Sandbox Code Playgroud)
对于不同的分支,B我们得到以下结果:
| 给定B | 共享提交 C | 历史上有 P 和 C 的分支(按顺序) |
|---|---|---|
| 特征/一个 | D | 掌握 |
| 特征/b | D | 掌握 |
| 特征/c | L | 发布/4,支持/1 |
| 特征/d | L | 发布/4,支持/1 |
| 特征/e | L | 发布/4,支持/1 |
| 特征/f | C | 发布/2、发布/3、主控 |
| 特征/克 | C | 发布/2、发布/3、主控 |
| 修补程序 | D | 掌握 |
| 掌握 | C | 发布/2、发布/3 |
| 发布/2 | C | 发布/3,主控 |
| 发布/3 | C | 发布/2,主控 |
| 发布/4 | L | 支持/1 |
| 支持/1 | L | 发布/4 |
这已经越来越接近确定的答案了;发布分支的响应并不理想。让我们更进一步。
BASE_NAME和P采取这种方法的一个方向可能是对P不同的基本名称使用不同的名称。让我们为此制定一个设计。
免责声明:我不是 git flow 纯粹主义者,请体谅我
让我们看看我们能git做到什么程度:
| 基础分支模式 | 父分支,已订购 | 评论) |
|---|---|---|
| ^大师$ | 不适用 | 没有父母 |
| ^支持/.*$ | ^大师$ | |
| ^修补程序/.*$ | ^支持/.*$ ^大师$ | 优先支持支持分支而不是主分支(排序) |
| ^发布/.*$ | ^支持/.*$ ^大师$ | 优先支持支持分支而不是主分支(排序) |
| ^错误修复/.*$ | ^发布/.*$ | |
| ^功能/.*$ | ^发布/.*$ ^支持/.*$ ^master$ | |
| ^.*$ | ^发布/.*$ ^支持/.*$ ^master$ | 冗余,但将设计问题分开 |
合并的先前代码和下面的新代码可作为要点:gitp
#
# Remove/comment-out the function call at the end of script,
# and append this to the end.
##
# bash associative arrays maintain key/entry order.
# So, use two maps, values correlated by index:
declare -a MAP_BASE_BRANCH_REGEX=( "^master$" \
"^support/.*$" \
"^hotfix/.*$" \
"^release/.*$" \
"^bugfix/.*$" \
"^feature/.*$" \
"^.*$" )
declare -a MAP_BRANCHES_REGEXS=("" \
"^master$" \
"^support/.*$ ^master$" \
"^support/.*$ ^master$" \
"^release/.*$" \
"^release/.*$ ^support/.*$ ^master$" \
"^release/.*$ ^support/.*$ ^master$" )
function findBranchesByBaseBranch() {
local BASE_BRANCH
if [[ -z "${1+x}" || "$1" == '.' ]]; then
BASE_BRANCH="$CURRENT_BRANCH"
else
BASE_BRANCH="$1"
fi
for idx in "${!MAP_BASE_BRANCH_REGEX[@]}"; do
local BASE_BRANCH_REGEX=${MAP_BASE_BRANCH_REGEX[$idx]}
if [[ "$BASE_BRANCH" =~ $BASE_BRANCH_REGEX ]]; then
local BRANCHES_REGEXS=( ${MAP_BRANCHES_REGEXS[$idx]} )
if (( ${#BRANCHES_REGEXS[@]} > 0 )); then
findBranchesSharingFirstCommonCommit $BASE_BRANCH "${BRANCHES_REGEXS[@]}"
fi
break
fi
done
}
findBranchesByBaseBranch "$1"
Run Code Online (Sandbox Code Playgroud)
假设脚本(所有部分)位于可执行文件中gitr,然后运行:
gitr <baseBranch>
Run Code Online (Sandbox Code Playgroud)
对于不同的分支,B我们得到以下结果:
| 给定B | 共享提交 C | 历史上有 P 和 C 的分支(按顺序) |
|---|---|---|
| 特征/一个 | D | 掌握 |
| 特征/b | D | 掌握 |
| 特征/c | L | 发布/4,支持/1 |
特征/d
小智 14 一个办法该解决方案基于 Run Code Online (Sandbox Code Playgroud)
限制和注意事项
结果Run Code Online (Sandbox Code Playgroud)
尽管存在本地分支(例如,仅
* - 或者 为什么 show-branch 对我不起作用在以下情况下,基于
sae*_*gnu 11 由于上述答案都没有在我们的存储库中运行,我想以自己的方式分享,使用最新的合并 Run Code Online (Sandbox Code Playgroud)
将它放在一个名为的脚本中 从输出中,我们可以根据自己的分支约定和每个分支的合并次数手动检测父分支. 编辑:
如果您 Run Code Online (Sandbox Code Playgroud)
请记住,正如"Git:查找提交来自哪个分支"中所述,您无法轻松查明已提交提交的分支(分支可以重命名,移动,删除...),即使它
如果两个提交id匹配,那么你就好了(这意味着 小智 8 git log -2 --pretty=format:'%d' --abbrev-commit | 尾-n 1 | sed 's/\s(//g; s/,/\n/g';
git log -2 --pretty=format:'%d' --abbrev-commit | 尾-n 1 | sed 's/\s(//g; s/,/\n/g';
git log -2 --pretty=format:'%d' --abbrev-commit | 尾-n 1 | sed 's/(.*,//g; s/)//';
这是Mark Reed 解决方案的 PowerShell 实现: Run Code Online (Sandbox Code Playgroud)
JoeChrysler的命令行魔法可以简化.这是写的逻辑: Run Code Online (Sandbox Code Playgroud)
我们可以在一个相对简单的 Run Code Online (Sandbox Code Playgroud)
这样就崩溃了: Run Code Online (Sandbox Code Playgroud)
分割线成字段 Run Code Online (Sandbox Code Playgroud)
查找包含星号的行 Run Code Online (Sandbox Code Playgroud)
...但不是当前的分支名称 Run Code Online (Sandbox Code Playgroud)
当您找到这样的行时,打印其第二个字段(即,我们的字段分隔符字符的第一次和第二次出现之间的部分).对于简单的分支名称,这将是括号之间的内容; 对于具有相对跳转的refs,它将只是没有修饰符的名称.所以我们的字段分隔符集处理两个 Run Code Online (Sandbox Code Playgroud)
然后立即退出.这意味着它只处理第一个匹配行,因此我们不需要通过管道输出
我并不是说这是解决此问题的好方法,但是这似乎对我有用。
|