代码之家  ›  专栏  ›  技术社区  ›  janos slartidan

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

  •  0
  • janos slartidan  · 技术社区  · 6 年前

    我想 只获取的提交 branchA 不在其底部 branchB .

    例如,考虑以下历史:

    B1 - B2 - B3 - B4 - B5
               \
                A1 - A2 - A3
    

    我想 取来 只有 A1 , A2 A3 . 重要的是要注意,我不知道前面的承诺是什么 A1 ,以及需要获取多少提交。 我的输入只是两个分支的头, 在这个例子中 branchA=A3 branchB=B5 . 基于这些输入,我需要确定 A1 把所有的东西 A1 布兰查 最理想的情况是什么都没有。

    或者,获取包括 A1 , A2 A3 以及足够的信息来识别 A1 也可能很有趣。

    为什么?在我只需要这些承诺的用例中(“在 布兰查 相对 布兰奇 )获取超过必需的提交会减慢我的进程。举个例子,一个拥有数千个提交的大型存储库,以及只有少量提交的功能分支。获取整个历史 布兰查 布兰奇 获取了很多我不需要的提交,并且需要大量的时间和网络带宽。

    我想出了一个丑陋的黑客,通过从浅层克隆开始,逐步获取越来越多的内容,直到找到一个常见的提交:

    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 包括承诺直到 布兰查 它比获取两个分支的完整历史要快。

    有比这更好的方法吗?我正在寻找一个纯粹的Git解决方案,但是如果GitHub API有一些东西可以使这变得更快、更容易,那也会很有趣。

    1 回复  |  直到 6 年前
        1
  •  1
  •   torek    6 年前

    这在今天是不可能的。你周围工作的变化是你能做的最好的。

    协议中没有任何内容会阻止您提供原始哈希ID,而不是 --depth 论点,以 git fetch 那就说明了 吉特取出 假装 对的 --深度 (不管是什么)已经供应了。但是里面也没有 吉特取出 以实现这一点。因此,实现这一点的唯一方法是从每个分支提示开始,一次枚举一个提交,直到找到正确的哈希(es),它还告诉您 --深度 争论应该是你的 吉特取出 命令。

    但是,当您迭代足够多的散列ID以找到正确的深度时,在大多数情况下,您可能已经完成了完整的克隆。所以实现这个特性的压力很小 外部 Git(例如,通过GitHub接口)。而且,用hash id命名提交对于人类来说也毫无乐趣,所以将这个特性添加到 吉特取出 也可以。

    最好的解决方案是,您可以在其中向其他Git存储库A展示 启动 散列(您自己的Git可以通过本地名称到散列的转换提供):如果您上次看到 B 分支,比如说, B4 所以你自己 origin/B 标识提交 B4 ,你可以在本地运行( 注意这一提议 --depth-inferred-from 参数今天不存在 ):

    git fetch --depth-inferred-from=origin/B A
    

    你的Git是:

    1. 运行 git ls-remote 或与之相当的 吉特取出 始终运行
    2. 转换他们 refs/heads/A (您打算获取的)到散列ID中,表示为 H 步骤3
    3. 只让他们的Git列举 <hash-of-B4>..H 阶段
    4. 放入正常获取的其余部分,即获取要获取的对象ID的have/want会话。

    然而,第3步需要fetch协议中的一个新特性,因此非常重要。