我有我的主分支并执行以下操作:
git checkout -b parentBranch
git ... (do some commits)
git checkout -b childOfParentBranch (this is while still on branch parentBranch)
git ... (do some commits)
Run Code Online (Sandbox Code Playgroud)
然后我按照这个确切的顺序合并(重要):
git checkout master
git merge childOfParentBranch --no-ff
Run Code Online (Sandbox Code Playgroud)
现在我如何做一个 git log 来查看两个分支的名称?
沿线的东西:
*
|-Merged parentBranch and childOfParentBranch
Run Code Online (Sandbox Code Playgroud)
或者:
*
|-Merged parentBranch
|-Merged childOfParentBranch
Run Code Online (Sandbox Code Playgroud)
编辑: 我添加了提交语句,因为缺少它们会导致误解。
我试图使用“git log”来显示所有合并到 master 的分支名称。即使只有 childOfParentBranch 合并到 master 中,也包括 parentBranch 的名称。如果我使用 gitk 进行检查,这些值很清楚,但我需要它们与“git log”一起进行一些自动化。
亲切的问候基督徒
关于编辑:
尝试git log --graph --decorate(可能使用--oneline)和其中之一--all(所有分支、标签等),或命名您关心的分支。请注意,分支名称(标签)可以随时删除或移动,因此您不能指望这些名称一直存在。
但是,在移动或删除分支标签之前,您可以看到哪些标签与git branch --contains和“合并”(指向或低于给定的提交 ID)git branch --merged。例如,给定一个提交图形看起来像这样,有四个分支标签如图所示,表示提交G,H,F,和E:
G <-- br1
/ \
A--B--C--D---H <-- br2
\ \ /
\ F--/ <-- br3
\
E <-- br4
Run Code Online (Sandbox Code Playgroud)
你可以运行,例如:
git branch --contains br1^ # br1^ identifies commit `D`
Run Code Online (Sandbox Code Playgroud)
查看“其提示提交是命名提交的后代的分支”。那些是br1和br2。换句话说,从 开始br1,即G,我们可以向后走并到达D;从 开始br2,即 ,H我们可以向后走并到达D。但是,从Fvia开始br3,向后走也达不到D,而从Evia开始br4,向后走也达不到D。)
您还可以运行:
git branch --merged br2 # br2 identifies commit H
Run Code Online (Sandbox Code Playgroud)
它(如文档说明)找到“可以从命名提交访问其提示提交的分支”。这版画br1,br2和br3。我们开始H并走所有向后的路径。 H本身由标签标识br2,因此打印br2. 然后我们走它的父母;H有三个:D、G、 和F(其中一个是“第一个”父级,但此处显示的图形没有告诉我们是哪个,对于git branch --mergedgit 而言,无论如何都不在乎)。CommitG是由名称标识的提交br1,因此打印br1. 提交D没有被任何东西识别。提交F由 标识br3。我们还检查的家长D和F:这些都是C, then B, then A,然后没有更多的父母。在这种情况下,它们都没有标签(但如果我们要添加一个指向,例如 commit A,git branch --merged也会打印该标签)。
(还有git branch --no-merged应用于 commit H,br4在这种情况下会打印。--merged如果它们指向从给定起点无法到达的提交,则打印分支标签正好相反。)
分支实际上没有父/子关系(尽管如果您愿意,您可以将它们读入存在中——但这里的重点是您必须根据图表创建它们)。此外,您建议的命令序列不会发生任何事情。
让我说得更具体一点,因为“分支”可以指两个不同的概念。有由提交有向图形成的提交链,还有分支名称实际上提供了某个分支的“提示”,例如experiment, master, 或feature:
C--D--E <-- experiment
/
A--B--F--G <-- master
\
H--I <-- feature
Run Code Online (Sandbox Code Playgroud)
名称experiment指向的分支以提示 commit 结尾E。该分支由A通过E. 分支命名(单个)提交E。但我们也将“分支”称为A通过E包容性。
同时,名称master指向的分支以提示 commit 结束G。分支由A, B, F, 和G; 但分支只是命名 G. 和以前一样,“分支”意味着两个不同的东西,这取决于我们想要它的含义:尖端,或者从尖端开始向后工作形成的线。
也就是说,如果您在“on”分支master并执行两个git checkout -b命令,则会创建两个新的分支标签。默认情况下,这些标签指向同犯的master。所以如果你从这个开始:
A--B--F--G <-- HEAD=master
Run Code Online (Sandbox Code Playgroud)
然后你运行:
$ git checkout -b br1
Switched to a new branch 'br1'
$ git checkout -b br2
Switched to a new branch 'br2'
Run Code Online (Sandbox Code Playgroud)
那么你现在有:
A--B--F--G <-- master, br1, HEAD=br2
Run Code Online (Sandbox Code Playgroud)
所有三个标签都指向同一个提示提交(G在本例中为 )。使用git log --decorate查看的标签。(我喜欢根据需要使用git log --oneline --graph --decorate, 有或没有--all。另外,我把 放在HEAD=上面的图表中来告诉你你“在”哪个分支。)
如果您然后尝试序列:
$ git checkout master
Switched to branch 'master'
$ git merge br1 --no-ff
Run Code Online (Sandbox Code Playgroud)
你会收到各种各样的投诉:
Already up-to-date.
Run Code Online (Sandbox Code Playgroud)
正因为如此,什么都没有发生。
让我们通过向其添加一个空提交来制作br1您可以合并的内容:
$ git checkout br1
Switched to branch 'br1'
$ git commit --allow-empty -m 'empty commit'
[br1 add230d] empty commit
Run Code Online (Sandbox Code Playgroud)
该图现在看起来是这样(我忽略了experiment和feature这里,和任意绘制br1如下master):
A--B--F--G <-- master, br2
\
J <-- HEAD=br1
Run Code Online (Sandbox Code Playgroud)
(因为新添加的提交导致标签br1移动到指向它)。
现在可以返回master并进行合并:
$ git checkout master
Switched to branch 'master'
Run Code Online (Sandbox Code Playgroud)
第一步只是移动HEAD标签:
A--B--F--G <-- HEAD=master, br2
\
J <-- br1
Run Code Online (Sandbox Code Playgroud)
下一步创建一个合并提交:
$ git merge --no-ff br1 -m 'merge br1'
Already up-to-date!
Merge made by the 'recursive' strategy.
Run Code Online (Sandbox Code Playgroud)
在merge增加了一个新的提交有两个父母,无论分支HEAD点,这是master。master像往常一样,标签移动以指向新的提交。这使得显示br2点的位置有点困难,所以我将绘制一个更长的 ASCII 箭头:
.--------- br2
|
v
A--B--F--G---K <-- HEAD=master
\ /
J <-- HEAD=br1
Run Code Online (Sandbox Code Playgroud)
请注意,分支br2以G. 这是 branch 的提示br2,因此G 是“提示”提交,即使它也是 merge-commit 的父级K。
这里有一堆关键的外卖信息:
分支本身由提交图形成,并在我们解释它们时根据我们的需要运行任意长(或短)。合并某些内容后,您可以将分支视为“伸出”的部分,即之后顶部的内容C:
o--o "branch"
/ \
B--C---o--M--o "main line"
Run Code Online (Sandbox Code Playgroud)
或者您可以将其视为整个过程,包括提交B和C此处。
HEAD命名一个分支,并且该分支标签是向前移动的。(使用“分离的 HEAD”,该HEAD文件给出了原始提交 SHA-1,并且HEAD本身被修改为包含新的原始提交 SHA-1。)M如上所示。不可能将提交与其自身合并,因为合并提交必须至少有两个不同的父提交(这就是合并提交的原因!)。上面没有显示,但也是一个关键概念:合并的“第一个父级”是合并之前“在分支上”的提交(假设HEAD命名为一个分支),所有其他父级是“合并到”中的提交”。Git 本身并不真正关心以哪种方式完成合并——标签可以更改或删除——但这允许您(用户)留下面包屑痕迹,供您自己或稍后进来的任何其他人查看完毕。