我只想仅提取在其基础branchA
中不存在的branchB
提交。
例如,考虑以下历史记录:
B1 - B2 - B3 - B4 - B5
\
A1 - A2 - A3
我只想获取 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
这适用于我的用例:它获取足够大的提交子集以标识A1
并包含提交,直到branchA
的开头,并且比获取两个分支的完整历史记录要快
有没有比这更好的方法了?我正在寻找一个纯粹的Git解决方案,但是如果GitHub API可以使它变得更快,更容易,那也很有趣。
答案 0 :(得分:1)
今天这不可能。变通办法的变种是您所能做的最好的。
协议中没有什么可以阻止您向--depth
提供原始哈希ID而不是git fetch
参数,而不会告诉git fetch
假装< / em>提供了正确 --depth
(无论是什么)。但是git fetch
中也没有任何东西可以实现这一点。因此,执行此操作的唯一方法是从每个分支提示中一次枚举一次提交,直到找到正确的哈希为止,该哈希还告诉您--depth
参数应为{ {1}}命令。
但是,在大多数情况下,当您遍历足够的哈希ID以找到正确的深度时,您可能已经完成了完整克隆。因此,在外部 Git中实现此功能的压力很小(例如,通过GitHub接口)。而且,通过哈希ID命名提交对于人类来说根本不是一件有趣的事,因此(或感觉)将此功能添加到git fetch
的压力也很小。
最好的解决方案是,您可以向另一个Git存储库提供起始哈希(您自己的Git可以通过本地名称到哈希的转换提供):他们的git fetch
分支的尖端是B
,以便您自己的B4
标识提交origin/B
,您可以在本地运行(请注意,拟议的B4
参数今天不存在):
--depth-inferred-from
拥有您的Git:
git fetch --depth-inferred-from=origin/B A
,或与之等效的git ls-remote
始终运行git fetch
(您打算提取)转换为哈希ID,在步骤3中表示为refs/heads/A
H
但是,第3步在获取协议中需要一个新功能,因此非常简单。