【问题标题】:Searching and Handling git objects搜索和处理 git 对象
【发布时间】:2019-05-25 20:38:26
【问题描述】:

我正在尝试过滤我的 git 存储库中文件的历史内容。某些文件中有一行包含字符串“BEAM:A_BOOK”,并且在该行的第 7 个逗号分隔值中是我要检索以进行进一步处理的值。我认为,理想情况下,我最终会得到类似字典的东西,其中包含提交的 SHA-1 哈希,以及该文件过去版本的 A_BOOK 值。

文件前几行的示例。请注意,我希望从此版本的文件中检索的值是“56.0”:

# Date: 2018-12-21 01:49:16.888 PV,SELECTED,TIMESTAMP,STATUS,SEVERITY,VALUE_TYPE,VALUE,READBACK,READBACK_VALUE,DELTA,READ_ONLY

REA_EXP:LINE,0,1544047322.881066957,NO_ALARM,NONE,enum,"JENSA~[UDF;AT-TPC;GPL;JENSA]",,"---",,true

REA_BTS19:BEAM:OPTICSFILE,0,1541798820.065952460,NO_ALARM,NONE,string,"BTS19_test3.data",,"---",,true

REA_BTS19:BEAM:A_BOOK,0,1545322510.562031883,NO_ALARM,NONE,double,"56.0",,"---",,true

最终,我将扩展它以检索几个值并进行一些数学运算以执行更复杂的过滤。更多背景信息:我们将用于核物理实验的离子束的原子质量和电荷值存储在版本控制下的文本文件中。这些文本文件充当我们的“保存集”,并充满了更多的质量和电荷信息,因为它们还包括如果我们想再次运行该光束,我们将恢复的机器值。我的目标是通过我们运行的光束的电荷:质量比过滤这些文件。

到目前为止,这似乎获得了我的大部分信息:

git grep 'BTS19:BEAM:A_BOOK' $(git rev-list --all) | grep RFQ-JENSA_Setpoint.snp

吐出这样的东西:

16eca44985214b790eb6ca8241ad86728b4fd3ae:RFQ-JENSA_Setpoints.snp:REA_BTS19:BEAM:A_BOOK,0,1531323944.085330133,NO_ALARM,NONE,double,"2.0",,"---",,true

6e585c905444f25e18edfe1eeb32ced2de72ed7c:RFQ-JENSA_Setpoints.snp:REA_BTS19:BEAM:A_BOOK,0,1531323944.085330133,NO_ALARM,NONE,double,"2.0",,"---",,true

bc202d5f21f9829fa3701ca636657ee1b0a73e25:RFQ-JENSA_Setpoints.snp:REA_BTS19:BEAM:A_BOOK,0,1531323944.085330133,NO_ALARM,NONE,double,"2.0",,"---",,true

etc...

但是,我希望看到类似的内容:

<hash>:<Retrieved A_BOOK Value>

或者,根据我刚刚展示的输出,我希望看到这样的结果:

16eca44985214b790eb6ca8241ad86728b4fd3ae:2.0

6e585c905444f25e18edfe1eeb32ced2de72ed7c:2.0

bc202d5f21f9829fa3701ca636657ee1b0a73e25:2.0

etc...

并最终包含一些数学以显示更有意义的内容:

<hash>:<Retrieved Q_BOOK Value>/<Retrieved A_BOOK Value>

有没有更好的方法来解决这个问题? 检索此信息的好方法是什么?

谢谢!

【问题讨论】:

    标签: git git-bash


    【解决方案1】:

    鉴于您对每个修订版中的特定文件感兴趣,请考虑将-- <pathspec> 添加到git grep 调用中。也就是说,而不是:

    git grep 'BTS19:BEAM:A_BOOK' $(git rev-list --all) | grep RFQ-JENSA_Setpoint.snp
    

    你可以从:

    git grep 'BTS19:BEAM:A_BOOK' $(git rev-list --all) -- RFQ-JENSA_Setpoint.snp
    

    您仍然会得到这些行,但速度更快,因为git grep 可以跳过所有没有名称中包含RFQ-JENSA_Setpoint.snp 的文件。 (注意<pathspec> 与正则表达式不同:如果你真的想允许任何字符,例如RFQ-JENSA_SetpointXsnpRFQ-JENSA_SetpointYsnp 作为文件名,你必须在这里使用-- 'RFQ-JENSA_Setpoint?snp'。我我猜你的第二个 grep 过于宽容了。RE 通常比路径 glob 更具表现力,但对于这种特殊情况,即使你确实是指“任何字符”,glob 也有 ? 允许这样做。)

    更复杂的是,您可能会发现在大型存储库中,$(git rev-list --all) 生成的字符串足以超出 argv 限制。 (我无法猜测您系统上的 argv 限制。)在这种情况下,您可能需要通过 xargs 管道传输 git rev-list --all

    git rev-list --all | xargs -I % git grep 'BTS19:BEAM:A_BOOK' % -- RFQ-JENSA_Setpoint.snp
    

    令人讨厌的是,这会为每个修订版生成一个单独的 git grep,这会让你马上慢下来。 (如果你有 BSD 风格的 xargs,你可以使用 -J 而不是 -I;或者考虑使用 GNU parallel 命令。)

    要将这些分解并提取第 7 个逗号分隔值,请考虑将 : 替换为 , 并使用 awk

    ... | sed 's/:/,/' | awk -F, '{print $1 ":" $8}'
    

    虽然如果您需要适当的 CSV 报价处理,单独的工具可能更合适。 (根据您的示例,这也将打印<hash>:"2.0",并带有引号。)

    【讨论】:

    • 感谢您的回复!!
    • 我会尽快尝试您的建议,并再次回复。
    • 这太酷了!但是,我无法让 xargs 正常工作。这是我用的:git grep 'BTS19:BEAM:A_BOOK' $(git rev-list --all) -- RFQ-JENSA_Setpoint.snp | sed 's/:/,/' | awk -F, '{print $1 ":" $8}'
    • 我承认我没有用git grep 测试过 xargs 变体,但它似乎应该可以工作。但是,如果您在使用 $(git rev-list --all) 时没有用完参数空间,则不需要 xargs,它只会减慢一切,因此您可以等到发现需要它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-01-03
    • 1970-01-01
    • 1970-01-01
    • 2012-05-22
    • 2012-01-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多