我只想获取其 base 中不存在的提交branchAbranchB。
例如,考虑一下这段历史:
B1 - B2 - B3 - B4 - B5
\
A1 - A2 - A3
Run Code Online (Sandbox Code Playgroud)
我只想获取A1,A2和A3。需要注意的是,我事先并不知道哪个提交是什么A1,以及我需要获取多少个提交。我的输入只是两个分支的头,在本例中branchA=A3为 和branchB=B5。基于这样的输入,我需要识别A1并获取A1和之间的所有内容branchA,理想情况下仅此而已。
A1或者,获取包含、A2和A3以及足够的信息来识别 的最小提交集A1也可能很有趣。
为什么?branchA在我只需要这些提交(“相对于 发生的变化”)的用例中branchB,获取超过必要提交的内容会减慢我的流程。例如,一个包含数千次提交的大型存储库,以及只有几个提交的功能分支。获取整个历史记录branchA并branchB获取大量我不需要的提交,并且需要大量时间和网络带宽。
我想出了一个丑陋的黑客方法,通过从浅克隆开始,逐步获取越来越多的内容,直到找到共同的提交,来避免获取完整的历史记录:
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 能够让这个过程变得更快、更容易,那也会很有趣。
今天这是不可能的。您的解决方法的变体是您能做的最好的事情。
\n\n协议中没有任何内容可以阻止您向 提供原始哈希 ID,而不是参数--depth,git fetch这会告诉您git fetch假装提供了正确的 --depth(无论是什么)。但也没有什么可以git fetch实现这一点。因此,执行此操作的唯一方法是从每个分支提示向后枚举提交,一次一个,直到找到正确的哈希值,这也告诉您命令--depth的参数应该是什么git fetch。
然而,在大多数情况下,当您迭代足够的哈希 ID 以找到正确的深度时,您可能已经完成了完整克隆。因此,在 Git之外(例如,通过 GitHub 界面)实现此功能的压力很小。而且,通过哈希 ID 命名提交对于人类来说一点也不有趣\xe2\x80\x94,因此将这个功能添加到 中也没有什么压力(或感觉)git fetch。
最好的解决方案是您可以向其他 Git 存储库提供一个起始哈希(您自己的 Git 可以通过本地名称到哈希转换来提供):如果您最后看到他们分支的提示B是,比如说,B4,以便您自己origin/B识别 commit B4,您可以在本地运行(请注意,这个提议的--depth-inferred-from参数今天不存在):
git fetch --depth-inferred-from=origin/B A\nRun Code Online (Sandbox Code Playgroud)\n\n其中会有你的 Git:
\n\ngit ls-remote的等效项git fetchrefs/heads/A(您想要获取的)转换为哈希 ID,如H步骤 3 中所示<hash-of-B4>..H在有会话期间呈现提交时进行枚举然而,第 3 步需要获取协议中的新功能,因此非常重要。
\n