Git 在远程和提交之间查找合并基
给定一个remote和一个commitsh,我想将它合并到origin上的一个目标分支中,并为它生成一个diff 如果目标分支存在于origin中,则只需调用Git 在远程和提交之间查找合并基,git,version-control,merge,Git,Version Control,Merge,给定一个remote和一个commitsh,我想将它合并到origin上的一个目标分支中,并为它生成一个diff 如果目标分支存在于origin中,则只需调用合并基,检查远程提交是否与origin的树相关,并获取从合并基到远程提交的差异 如果它不存在,盲目创建新分支可能会有风险,因为我想确保引入的历史与起源相关 现在,我正在使用revlist确定提交是否与origin共享历史记录。具体地说,我使用git rev list--max parents=0--remotes=origin和git re
合并基
,检查远程提交是否与origin的树相关,并获取从合并基到远程提交的差异
如果它不存在,盲目创建新分支可能会有风险,因为我想确保引入的历史与起源相关
现在,我正在使用revlist
确定提交是否与origin共享历史记录。具体地说,我使用git rev list--max parents=0--remotes=origin
和git rev list--max parents=0 committish
来获取origin和remote commit的根提交,并检查它们是否至少有一个共享根(rev list
可以生成提交/远程之间的联合或差异,但不能生成看起来的交叉点)
现在我知道远程提交是相关的,但我仍然需要生成一个差异。现在,我只知道从新提交可以访问源中的哪些根提交。如果我不知道哪个分支与我要引入的提交关系最密切,我如何在源中找到最佳的合并基础?我是不是完全错了
换句话说,给定origin和commitish,如果不知道origin的层次结构,如何识别合并基X?git merge base origin commitish
无效,因为origin没有指定单个提交
o----o----o master \
\ }-- everything reachable from origin
o---X---o branch2 /
\
o---o----o---o----o---o commitish }-- new data from remote
我是不是完全错了
我想是的。让我们回顾一下。我相信你已经看到了其中的一些,但是关于这一点的许多解释……都不太好。(另外,在我回答的时候,你一直在修改你的问题,所以我们可能会跨越一些线…)
远程、远程跟踪分支、git修订版
和git修订版列表
像origin
这样的遥控器只是一个名字。“什么的名字”是一个好问题(不是你的,至少不是直接的,而是你应该问的问题)。主要的“什么的名字”非常简单:对于URL。名称origin
存储类似ssh://git@github.com/path/to/repo
。通常每个遥控器都有一个URL。(如果愿意,您可以设置第二个不同的推送URL。在一些很少有用的情况下,您也可以有多个推送URL。但大多数情况下,它只是一个URL的简称。)这里要记住的关键点不仅是它是URL的名称,而且在URL的另一端还有另一个Git。另一个Git存储库有自己的分支和标记名
像origin
这样的远程名称不是分支或标记。它本身并不标识提交。按名称标识提交的内容是您自己的(本地)分支名称,如master
;您拥有的任何标记名称,如v1.3
,如果您有这样的标记;远程跟踪分支名称,如origin/master
。每个这样的名称标识一个特定的提交。对于远程跟踪分支名称,如origin/master
,它标识Git saw的提交,即上次你的Git通过URL联系另一个Git时。换句话说,远程跟踪分支会记住你的Git上次与另一个Git对话时看到的内容。它们只与你的Git最近的完整对话一样最新。(您的Git将对成功的Git push
操作执行部分更新,但仅对未限制提取的Git fetch
操作执行完全更新。如果您使用Git pull
,它将执行限制的提取
,这将导致至少一些远程跟踪分支过期。)
然而,有点令人困惑的是,作为非限定名称X的解析路径是:
.git/X
是否存在;如果存在,请使用它。(这确保了HEAD
始终意味着HEAD提交。作为一种副作用,它意味着您不应该命名分支MERGE\u HEAD
、ORIG\u HEAD
、CHERRY\u PICK\u HEAD
,或者FETCH\u HEAD
,因为各种Git操作都会留下带有该名称的文件。)refs/X
;如果存在,请使用该选项refs/tags/X
;如果存在,请使用它refs/heads/X
;如果存在,请使用它refs/remotes/X
;如果存在,请使用该选项refs/remotes/X/HEAD
;如果存在,请使用该选项refs/remotes/origin/HEAD
,那么单独使用远程名称origin
将尝试……而Git现在通常会设置一个refs/remotes/origin/HEAD
间接引用,指向您进行原始Git克隆时Git选择的引用通常是refs/remotes/origin/master
,因此origin
本身可以但不一定“表示”origin/master
,这是一个远程跟踪分支名称
同时,它有自己的特殊标志,包括--remotes
。要完全理解这些Git标志,您可能也想参考它们,但它们与我们在上面看到的GitRevisions
中的搜索相同,并且参考名称空间是分层的
源站的所有远程跟踪分支都位于refs/remotes/origin/
中,这使得我们很容易找到它们。事实上,它们是通过将其他Git分支(与远程和sim相关的URL的另一端的Git本地分支)作为Git的分支来构建的ply重命名它们。当您运行git fetch origin
时,使您的git具有
$ git config --get branch.master.remote
origin
$ git config --get branch.master.merge
refs/heads/master
$ git rev-parse --abbrev-ref master@{u}
origin/master
$ git merge # look up the upstream; merge with that
$ git merge 1234567 # merge with commit 1234567