代码之家  ›  专栏  ›  技术社区  ›  Michal Čihař

查找源从git分支的位置

  •  8
  • Michal Čihař  · 技术社区  · 15 年前

    我有一个git存储库(或多或少地涵盖了项目历史)和独立的源代码(只是一个包含很少文件的tarball),它们在一段时间前(实际上是在2004年或2005年的某个地方)就已经分叉了。

    来自tarball的源代码已经经历了很多变化,我想从中加入一些。现在的问题是-如何找出改变了的源的分支点,以获得那里发生的最小差异。

    所以我基本上是想在git历史中找到一个地方,那里的代码与我的tarball源代码最为相似。我不想手动操作。

    还值得一提的是,更改后的源代码只包含文件的子集,并将一些文件拆分为更多的文件。然而,其中的代码似乎只得到了一些小的修改和补充。

    here Git托管在 Gitorious git://gitorious.org/gammu/mainline.git

    6 回复  |  直到 12 年前
        1
  •  4
  •   Community CDub    8 年前

    你最好的办法可能是把自己限制在特定的文件里。如果您只考虑一个文件,那么迭代该文件的所有版本不需要太长时间(使用 git rev-list <path> 以获得一个列表,这样就不必测试每个提交)。对于修改文件的每个提交,可以检查差异的大小,并相当快地找到最小值。对少数文件这样做,希望他们会同意!

    tarball 与…相比。这样,你就可以做到:

    git rev-list path/to/file | while read hash; do echo -n "$hash "; git diff --numstat tarball $hash path/to/file; done
    

    以获得所有提交及其差异大小的良好列表(前三列将是SHA1、添加的行数和删除的行数)。然后你就可以用管道把它输送到 awk '{print $1,$2+$3}' | sort -n -k 2 ,您将有一个提交及其差异大小的排序列表!

    如果您不能将自己限制在一小部分要测试的文件中,我可能会尝试手动实现类似于 git-bisect -只是试着把你的方法缩小到一个小的差异,假设在所有可能的情况下,接近你的最佳情况的提交也会有较小的差异,而远离它的提交会有较大的差异(可能介于牛顿方法和完全的二进制/网格搜索之间?)

    编辑:另一种可能性,在 Douglas' answer ,如果您认为某些文件可能 对于那些在某个提交中的人来说,就是使用 git-hash-object ,然后查看您的历史记录中有哪些提交了该blob。有一个 question with some excellent answers

        2
  •  2
  •   Douglas    15 年前

    这不是一个很好的解决方案,但是要猜测它可能是哪一个修订版:假设tar ball中的一些文件在分支之后没有被更改。跑 git hash object 对tar ball中的每个文件,然后使用 git show git whatchanged . 然后,您的问题的答案可能是提交最常见的文件,但仍然会有点碰运气。

        3
  •  1
  •   Spudd86    15 年前

    根据araqnid所说的,我想出了9c6c864426bf88429e77c7e22b5aa78e9295b97a(只要求在0.61.0和HEAD之间的东西),这可能不是最好的)你可能会做得更好,像这样的东西

    git rev-list --no-merges --all | while read rev; do patchsize=$(git diff $rev | wc -c); echo $patchsize $rev; done | sort -n | less
    

    假设您已经将tarball导入git并签出了该修订版(我是通过解构然后

    git init
    git add .
    git commit -m "import tarball"
    git remote add origin git://gitorious.org/gammu/mainline.git
    

        4
  •  0
  •   Derick Bailey    15 年前

    叉子是怎么做的?是别人做的克隆然后自己做的吗?如果是这样,那么这真的很容易。您所需要做的就是创建一个从fork中提取代码的本地分支。git将看到分叉分支的祖先指向原始存储库中的一个提交,可以说,它将“连接点”。。。它将把历史从原始存储库重新连接到fork。

    您应该能够做到:

    git remote add thefork git://wherever.it.lives/thefork.git
    
    git fetch thefork
    
    git branch -f thefork-branch thefork/branchname
    
    git checkout thefork-branch
    

    这时,你可以跑了 gitk 并查看分叉分支和本地存储库的完整历史,以及它们是否连接。

        5
  •  0
  •   araqnid    15 年前

    现在,对于master中的每个修订,只需与树/修订('imported')进行diff,并输出diff的大小。比如:

    git rev-list master | while read rev; do patchsize=$(git diff $rev imported | wc -c); echo $rev $patchsize; done
    

    因此,根据一个非常粗略的经验法则,补丁大小最小的版本将是“最接近的”(一个相同的修订将产生一个补丁大小为0的补丁,其他任何东西都肯定是非零的,而且更改的越多,越大)。

        6
  •  0
  •   Community CDub    8 年前

    git meld . (另请参见: View differences of branches with meld?

    为此,将tarball内容添加到您的存储库中(您无论如何都要这样做)。安装Meld和 git-meld ,运行

    git meld branch_from_tarball commit_to_check &
    

    在不同的提交上,直到找到差异最小的一个。此命令将打开 meld

    Meld显示两个非常不同的提交:
    Very different

    显示两个类似的提交: Similar

    推荐文章