我从哪个分支开始的?

87

我回到了一个旧项目,运行了优秀的git status命令以弄清楚情况,发现有太多的分支!在重新开始工作之前,我想做一些整理,但我不确定哪个分支来自哪里...

例如,“branchA”是从“develop”派生的吗?“branchB”是从“master”还是“branchA”派生的?

如何回答上面的样本问题?


可能是重复的问题:Git:查找提交来自哪个分支 - Cascabel
可能的重复内容有些脆弱 - 它可能是您某些分支所需的内容,但可能并不涵盖所有内容。也许应该只是链接到它,抱歉。 - Cascabel
1
这是不可能的。如果你想了解关于你的分支的任何信息,git 不是正确的工具。分支(在 git 中)是短暂的,因此非常不可靠。图形化工具可以给你提示,但不能给你答案。 - Thomas
9个回答

52

git merge-base 显示两个分支的共同祖先提交。

简单用法: git merge-base <branch> <branch> 显示两个分支的共同提交。


请参考http://git-scm.com/docs/git-merge-base。正如其所述,您需要提供两个提交ID进行比较。因此,如果您在某个项目中有主分支和开发分支,则“git merge-base master devel”将告诉您这两个分支的共同祖先提交。 - patthoyts
1
这个命令只返回一个提交哈希值。 更多信息,请参考: git log -1 commit-hash - grenix

28

对于这个问题没有一个确定的答案,因为分支只是指向DAG中某些提交的指针。例如,masterfoo 可能指向相同的提交;如果你从 foo 创建一个分支,那么它实际上等同于从 master 创建一个分支。

话虽如此,如果你通过 gitk 或其他一些图形化历史工具来可视化提交图,你可以大致了解分支点在提交图中的位置,以及各个分支指针所指的位置。


如果您使用git的“grafts”,则可以创建循环,使其不再是DAG。 显然这很糟糕。 :-) (毫不奇怪...尽管它应该大多数情况下“只需工作”,但我还没有尝试过。)我怀疑您也可以使用filter-branch创建循环,但我也没有尝试过。 直接合并似乎会拒绝尝试创建循环,至少是这样。 - torek

28

如果您已经在一个分支上,您可以像这样获得它从另一个分支(比如master)派生的提交点:

git merge-base your-branch-name master
git merge-base --fork-point master

使用git show <commit-id>命令获取提交消息。如果您没有提交ID,则该分支不是从那个分支派生的。

例如,我不确定我是否从devmaster分支派生:

$ git checkout my-branch
$ git merge-base --fork-point master
$ git merge-base --fork-point dev
1770f75fa178df89a40ddc5f13ecd6bc597c17df
$ git show 1770f75fa178df89a40ddc5f13ecd6bc597c17df
commit 1770f75fa178df89a40ddc5f13ecd6bc597c17df (origin/popup-stack-12, dev)
Merge: 37f79cf f8a9795
Author: Superman <super@example.com>
Date:   Sun Mar 29 23:14:40 2020 +0000
...

我从dev分支fork了这个branch。


10
命令行中的git可执行文件还具有显示分支和合并的基本树形结构的功能,使用--graph选项来进行git日志。您可以通过其他选项对其进行各种美化。尝试以下选项以适应您的需求:
最简单的:
git log --graph

不错:

git log --graph --decorate --simplify-by-decoration --color --oneline --date=local

全套服务:

git log --graph --decorate --simplify-by-decoration --color --oneline --date=local --pretty=format:'%C(auto) %h %d %C(reset)%s (%C(cyan)%ad %ae%C(reset))'

7

正如其他人提到的那样,没有标准答案,但是git reflog在某些情况下可以通过显示本地git历史记录来帮助解决问题:

a1b2c3d4 (HEAD -> my_current_working_branch) HEAD@{0}: pull origin master: Merge made by the 'recursive' strategy.
aaaa1111 (origin/my_current_working_branch) HEAD@{1}: commit: Added bar
def123aa (forgotten_branch) HEAD@{2}: checkout: moving from forgotten_branch to my_current_working_branch

在这种情况下,我可以看到我从forgotten_branch分支分支,合并了master,并切换到了my_current_working_branch分支。

它并不总是能提供你所需要的信息,但在某些情况下会有所帮助。


这对我很有用 - Cuong Vo

2

坚持使用命名规范,避免所有混淆。

当从 master 创建分支时 - 比如说,为了实现电子邮件功能 - 可以将其命名为 master_emailfeature。然后,如果需要从此分支创建子分支来实现电子邮件的 SSL,则可以将其命名为 master_emailfeature_sslandtls

这样,仅通过查看分支名称就可以清楚地知道是从哪个分支创建的。


2
您可以使用图形化的树状图查看器,我使用gitg查看分支和差异,虽然大部分时间我都在使用命令行进行真正的工作。

2

1
如果你想找出本地分支派生自哪个远程分支,这个命令可以帮助你。
git remote show origin

向下滚动,直到您看到“为'git pull'配置的本地分支:”并在其下方显示所有本地分支及其将合并的远程分支的列表。


问题是关于分支点,而不是从哪里推送和拉取更改。 - Clintm
1
它帮助了我 :) - Hayden Thring
它帮助了我;我看到了“HEAD分支:whatIAmLookingFor”。 - Neil Gatenby

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接