【问题标题】:How to use git-filter-branch to test commits如何使用 git-filter-branch 测试提交
【发布时间】:2015-09-30 22:42:48
【问题描述】:

我怀疑我的存储库中最后 150 次提交中的一些已损坏——也就是说,如果我签出其中一个提交,代码将无法编译。我想我可以使用 git-filter-branch 来测试它,但我对参数感到困惑。我想出了这个:

git filter-branch -f --commit-filter 'git commit-tree "$@"; cd ../..;制作默认配置;制作'头^..

但我得到的是这个输出:

$ git filter-branch -f --commit-filter 'git commit-tree "$@"; cd ../..; make defconfig; make' HEAD^..
Rewrite 4c3b2950f53717ba22280a76c211c9eab3135348 (1/1)arch/arm64/kernel/setup.c: In function 'arm64_spcr_setup':
arch/arm64/kernel/setup.c:615:3: error: implicit declaration of function 'acpi_setup_spcr' [-Werror=implicit-function-declaration]
   acpi_setup_spcr();
   ^
cc1: some warnings being treated as errors
make[1]: *** [arch/arm64/kernel/setup.o] Error 1
make: *** [arch/arm64/kernel] Error 2
could not write rewritten commit

这对我来说毫无意义。编译错误与我的 repo 中的最后两次提交不匹配,“无法编写重写提交”是什么意思?我显然做错了什么,但我不知道是什么。

【问题讨论】:

    标签: git git-filter-branch


    【解决方案1】:

    这不是git filter-branch 的设计目的。

    filter-branch 的作用,尽可能简单地描述,是这样的:

    • 对于某些提交集(基于参数),在签出每个提交、应用过滤器并签入结果后,制作这些提交的副本
    • 对于某些分支名称(以及可选的标记名称),使新的分支(和可选的标记)名称指向新的过滤后复制提交。

    您可以(正如您尝试过的那样)在“过滤”阶段检出每个提交时对其进行编译,但是因为 filter-branch 不是为此而设计的,而是针对 avoid 尽可能实际地检查提交,1 这比您想象的要困难得多。

    简单来说,filter-branch 就是wrong tool

    (通常这里正确的工具是git bisect,它在提交之间来回跳转,寻找引入了一些错误的点,而不是线性地通过每个提交来查看哪些提交很好。不过,我并不完全清楚你的意图是什么,所以它可能不是适合你的情况的工具。)


    1过滤过程的签出和重新签入部分往往是最慢的,所以每当 filter-branch 可以避免做“真正的”出入时,确实如此。这就是为什么有--index-filter,以及为什么--commit-filter 实际上并没有提取任何树的原因。 (--tree-filter 强制进行完全签出,但它可能对您的情况不利,除非您的编译过程是只读的。)

    【讨论】:

      【解决方案2】:

      这似乎...

      您要做的就是检查提交,一次一个,编译它们,然后针对它们运行测试,对吧?

      您可以做的是检查这些提交,从 1 到您想要返回的任意多个,运行测试,并将测试结果报告到文件中。

      这会让你开始

      for i in $(seq 1 150);
      do
          git checkout HEAD~$i;
          make defconfig && make;
          git checkout master;
      done
      

      可能有一种更优雅的方法来解决这个问题,但原理是这样的:

      • 您正在经历每个提交,一次一个处于分离的 HEAD 状态。
      • 您正在运行构建分支所需的任何步骤当时
      • 您运行测试(并记录它们;我将此作为练习留给读者)。
      • 然后您恢复分支的状态,使其指向原来的 HEAD。

      一个更优雅的方法是只在完成后将分支移回:

      COUNT=0
      while [ $COUNT -lt 150 ];
      do
          git checkout HEAD~1;
          make defconfig && make;
          let $COUNT=$COUNT + 1;
      done
      git checkout master;
      

      【讨论】:

      • 谢谢。我会试一试。我仍然想知道如何使用 git-filter-branch 来做我想做的事。我很难理解这个功能是如何工作的。
      • @RichardFallon:filter-branch 不适合你想要做的事情。通常,您会使用它来重写大量历史记录,而不是对一些提交进行诊断。
      猜你喜欢
      • 1970-01-01
      • 2013-11-07
      • 1970-01-01
      • 2012-04-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多