仅获取基本分支中不存在的提交范围

Sto*_*ica 5 git github

我只想获取其 base 中不存在的提交branchAbranchB

例如,考虑一下这段历史:

B1 - B2 - B3 - B4 - B5
           \
            A1 - A2 - A3
Run Code Online (Sandbox Code Playgroud)

我只想获取A1,A2A3。需要注意的是,我事先并不知道哪个提交是什么A1,以及我需要获取多少个提交。我的输入只是两个分支的头,在本例中branchA=A3为 和branchB=B5。基于这样的输入,我需要识别A1并获取A1和之间的所有内容branchA,理想情况下仅此而已。

A1或者,获取包含、A2A3以及足够的信息来识别 的最小提交集A1也可能很有趣。

为什么?branchA在我只需要这些提交(“相对于 发生的变化”)的用例中branchB,获取超过必要提交的内容会减慢我的流程。例如,一个包含数千次提交的大型存储库,以及只有几个提交的功能分支。获取整个历史记录branchAbranchB获取大量我不需要的提交,并且需要大量时间和网络带宽。

我想出了一个丑陋的黑客方法,通过从浅克隆开始,逐步获取越来越多的内容,直到找到共同的提交,来避免获取完整的历史记录:

git clone --depth 1 "$repo" --branch "$branchA" shallow
cd shallow

for ((depth = 8; depth <= 1024; depth *= 2)); do
    echo "trying depth $depth ..."
    git fetch --depth $depth
    git fetch --depth $depth origin "$branchB:$branchB"
    lastrev=$(git rev-list --reverse "$branchB" | head -n1)
    if git merge-base --is-ancestor "$lastrev" HEAD; then
        echo "found with depth=$depth"
        break
    fi
done
Run Code Online (Sandbox Code Playgroud)

这适用于我的用例:它获取足够大的提交子集来识别A1并包含提交,直到 的头部branchA,并且它比获取两个分支的完整历史记录更快。

还有比这更好的方法吗?我正在寻找一个纯粹的 Git 解决方案,但如果 GitHub API 能够让这个过程变得更快、更容易,那也会很有趣。

tor*_*rek 4

今天这是不可能的。您的解决方法的变体是您能做的最好的事情。

\n\n

协议中没有任何内容可以阻止您向 提供原始哈希 ID,而不是参数--depthgit fetch这会告诉您git fetch假装提供了正确 --depth(无论是什么)。但也没有什么可以git fetch实现这一点。因此,执行此操作的唯一方法是从每个分支提示向后枚举提交,一次一个,直到找到正确的哈希值,这也告诉您命令--depth的参数应该是什么git fetch

\n\n

然而,在大多数情况下,当您迭代足够的哈希 ID 以找到正确的深度时,您可能已经完成了完整克隆。因此,在 Git之外(例如,通过 GitHub 界面)实现此功能的压力很小。而且,通过哈希 ID 命名提交对于人类来说一点也不有趣\xe2\x80\x94,因此将这个功能添加到 中也没有什么压力(或感觉)git fetch

\n\n

最好的解决方案是您可以向其他 Git 存储库提供一个起始哈希(您自己的 Git 可以通过本地名称到哈希转换来提供):如果您最后看到他们分支的提示B是,比如说,B4,以便您自己origin/B识别 commit B4,您可以在本地运行(请注意,这个提议的--depth-inferred-from参数今天不存在):

\n\n
git fetch --depth-inferred-from=origin/B A\n
Run Code Online (Sandbox Code Playgroud)\n\n

其中会有你的 Git:

\n\n
    \n
  1. run ,或始终运行git ls-remote的等效项git fetch
  2. \n
  3. 将它们refs/heads/A(您想要获取的)转换为哈希 ID,如H步骤 3 中所示
  4. \n
  5. 要求他们的 Git 仅<hash-of-B4>..H会话期间呈现提交时进行枚举
  6. \n
  7. 放入正常获取的其余部分,即用于获取要获取的对象 ID 的 has/want 会话
  8. \n
\n\n

然而,第 3 步需要获取协议中的新功能,因此非常重要。

\n