Git 在远程和提交之间查找合并基

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

给定一个remote和一个commitsh,我想将它合并到origin上的一个目标分支中,并为它生成一个diff

如果目标分支存在于origin中,则只需调用
合并基
,检查远程提交是否与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
    ;如果存在,请使用该选项
  • 最后一项6-意味着,如果存在
    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