重要的是要认识到
姓名
其实没什么意思。
分支名称只是指向提交的标签或指针把它们想象成黄色的便签,甚至
sticky arrows
,可以粘贴到提交上是那个
提交
那很重要提交的标识是其哈希ID。提交是永久的
一
不可更改,并且每个提交都记录其直接父级(大多数提交)或父级(合并提交为2个或更多)的哈希ID这就是为什么
提交图
,但你总是可以
添加
对它来说,是永恒不变的。
图形本身决定了存储库的实际“分支度”:
(older commits towards the left, newer ones towards the right)
o--A
/
...--o--o
\
o--o--B
图的这一部分显示了两个分支,以两个结束
提示提交
A
和
B
. 添加新的提交过去
一个
给了我们
C
,它会记住
一个
作为其母公司:
o--A--C
/
...--o--o
\
o--o--B
如果我们现在添加
合并提交
我们称之为
M
对于父母是
二者都
C类
和
乙
,我们得到:
o--A--C
/ \
...--o--o M
\ /
o--o--B
需要两个标签两个粘滞的便条箭头才能记住这两个
一个
和
乙
,或两者都有
C类
和
乙
,但现在我们有了
米
,我们可以丢弃其中一个标签,只需保留一个指向
米
本身:
o--A--C
/ \
...--o--o M <-- branch
\ /
o--o--B
这就是分支名称的作用:它是一个指针,指向
一个
提交,哪个Git将被认为是
提示
一些向后看的提交链的提交当Git向后工作时,从这个tip commit开始,Git将遍历
全部的
合并的分支,以查找通过向后工作可以到达的所有提交自从
米
有两个父母
C类
和
乙
,Git将访问commit
C
然后
一个
等等,还有
乙
然后所有人都向左边承诺
乙
.
当然,我们可以让标签指向
一个
和/或
乙
和/或
C类
:
.... <-- tag: v1.0
.
.
o--A--C
/ \
...--o--o M <-- branch
\ /
o--o--B <-- feature
如图所示,标签不必
分支
名字分支名称的特殊功能是通过“on”分支,使用
git checkout
name
,任何
新的
我们所做的提交将自动更新名称以指向新的提交新的提交将指向上一个提交。
这就是背后的概念
git branch --contains
也是因为承诺
乙
是
可从
犯罪
米
,从
米
向后退一步,
git branch --contains
specifier-for-
B
会把名字打印出来
branch
. 这个名字指向
米
和
米
达到
乙
. 更一般地说,Git反复询问并回答问题:
与
git branch --contains
anything that finds some commit
,Git询问有关每个分支名称的每个分支提示提交的问题:
target=$(git rev-parse $argument) || exit 1
git for-each-ref --format='%(refname)' refs/heads |
while read fullbranchname; do
branchtip=$(git rev-parse $fullbranchname)
if git merge-base --is-ancestor $branchtip $target; then
echo "branch ${fullbranchname#refs/heads/} contains $argument"
fi
done
如果
$argument
分支名称是
分支
,将其转换为哈希ID的操作将选择提交的哈希ID
米
. 然后手术开始
refs/heads/feature
在哈希ID中选择
乙
,和
git merge-base --is-ancestor
回答问题
是承诺
乙
犯罪的始祖
米
(事实确实如此)。
二
你的要求有点复杂:你希望,对于每个分支名称,不仅要确定
此分支的提示提交是否早于某个选定分支的提示提交
(作为
git分支--包含
是的),但是
对于每一个这样的分支名称,哪一个是更多的祖先y,哪一个是更少的祖先y
. 这个问题
可以
得到回答,但是
只是在某些情况下
.
例如,请考虑以下图表:
...--o--o--o--o---M1--M2-o <-- master
\ \ / /
\ o--o / <-- feature1
\ /
o--o--o--o <-- feature2
我想你想要
feature2
被称为“后”
feature1
,因为合并提交会带来
特点2
在合并提交之后出现
特点1
.
三
但合并并不总是带来
二
共同承诺。
四
考虑:
o--o--o <-- feature1
/ \
...--o--o--o--o---M1--o <-- master
\ /
o--o--o <-- feature2
现在没有明显的顺序:
特点1
和
特点2
两人都是同时被带进来的,是一次犯罪。
(当然,如果我们删除其中一个
feature
名字,这就解决了问题如果我们删除
二者都
名字,更容易解决!)
一
你
可以
通过删除所有访问权限来删除提交
到
承诺Git从已知的namesbranch和标记名开始,所有其他形式的referenceandworkbackwardthroughthegraph如果此向后工作到达提交,则必须保留提交如果没有,提交就有资格被删除除了明显的名称之外,还有其他名称,这些名称通常会使提交活动至少延长30天。
二
我们可以消除
git rev-parse
打电话是因为
git merge-base
接受一个分支名称来代替散列ID。当给定一个名称时,它只会找到提交散列,同样的方式
git版本分析
会的我把它们放进去主要是为了说明。
三
要产生这种排序,您必须编写自己的代码注意,这并不像比较不同分支的tip提交那么简单;我们需要知道哪些合并(如果有的话),引入那些tip,并比较合并我们还必须考虑通过将其尖端嵌入非merge-y子图而形成的分支:
..... <-- branch3
.
...--o--o--o--o <-- branch1
.
........ <-- branch2
在这里,我想我们要索赔
branch2 < branch3
.
四
即使在一对一次合并的情况下,您也可以重复地将一些commit与一些主线合并,这会给问题带来麻烦(在
是
可能的顺序,但您必须选择一些图遍历算法来选择此处的总顺序)本质上,记住当你和
DAG
,你正在处理一个
poset
.