【发布时间】:2019-01-03 10:39:47
【问题描述】:
我正在尝试从 git 存储库中的文件的历史版本中检索和处理数据。我想要一个字典之类的东西,其中包含每个条目的<hash>, <time of commit>, <value retrieved from contents of a file revision>, <commit message>。
我认为我从每个文件修订中检索到的数据以及使用它们完成的任何计算都最好使用 python 处理。 subprocess 模块似乎最适合集成我的 git 命令。
下面我展示了我如何定义一个函数 getval(key, filename),我希望将 <SHA-1 hash>:<Value> 输出到控制台,但希望有一个包含更多信息的 dict... 还有 <time> 和 @987654325 @。
我帮助操作离子加速器,我们使用 git 在其中存储“保存集”——或与给定加速器调谐相关的值。这些文件中的值包括电荷(Q)和质量(A)。最终,我想检索这两个值,获取比率 (Q/A),并显示一个文件修订哈希列表,按我们提供的离子的电荷:质量比排序,以及该文件修订中的设置。
文件样本(56Fe17+):
# 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 REA_BTS19:BEAM:Z_BOOK,0,1545322567.544226340,NO_ALARM,NONE,double,"26.0",,"---",,true REA_BTS19:BEAM:Q_BOOK,0,1545322512.701768974,NO_ALARM,NONE,double,"17.0",,"---",,true
到目前为止——在其他人的帮助下——我已经找到了一个 git one-liner,它可以 greps 给定文件的修订历史以获取键 [a string] 并使用 sed 和 awk 输出 @ 987654327@.
我开始使用 Git Oneliner:
git grep 'BTS19:BEAM:A_BOOK' $(git rev-list --all) -- ReAccelerator/Snapshots/RFQ-JENSA_Setpoints.snp | sed 's/:/,/' | awk -F, '{print $1 ":" $8}'
Oneliner 的输出
e78f73fe6f90e93d5b3ccf90975b0e540d12ce09:"56.0" 4b94745bd0a6594bb42a774c95b5fc0847ef2d82:"56.0" f2d5e263deac1d9112be791b39f4ce1b1b34e55d:"56.0" c03800de52143ddb2abfab51fcc665ff5470e363:"56.0" 4a3a564a6d87bc6ff5f3dc7fec7670aeecfe6a79:"58.0" d591941e51c4eab1237ce726a2a49448114b8f26:"58.0" a9c8f5cdf224ff4fd94514c33888796760afd792:"58.0" 2f221492beea1663216dcfb27da89343817b11fd:"58.0"
我也开始使用 subprocess python 模块。但我正在努力弄清楚如何处理我更复杂的 git 命令。一般来说,我希望能够传递一个密钥和一个文件......类似于getval(key, filename)。
当我的 cmd 字符串是 ['git', 'grep', str, '$(git rev-list --all)', '--', pathspec] 时,它返回错误,指出 '$(git rev -list --all)' 模棱两可。认为它没有被扩展,我添加了一个单独的进程来执行嵌套命令,但我不确定我这样做是否正确。
我的 Python 文件 (gitfun.py):我目前正在从中运行函数
import sys, os
import subprocess
def getval(str, pathspec, repoDir='/mnt/d/stash.projects/rea'):
p1 = subprocess.Popen(["git", "rev-list", "--all"], stdout=subprocess.PIPE)
output, err = p1.communicate()
cmd = ['git', 'grep', str, output, '--', pathspec]
p2 = subprocess.Popen(cmd, cwd=repoDir)
p2.wait()
cwd = '/mnt/d/stash.projects/rea'
filename = 'ReAccelerator/Snapshots/RFQ-JENSA_Setpoints.snp'
os.chdir(cwd)
getval('BTS19:BEAM:A_BOOK', filename)
目前它正在返回 'file name too long' 所以(即使我不相信它真的太长了)我尝试将 git config 中的 core.longpaths 更改为 true,但这没有效果。再次说明为什么我怀疑我没有正确处理 $(git rev-list --all) 扩展的替换。
对于 this 代码,我希望看起来像这样:
522628b8d3db01ac330240b28935933b0448649c:ReAccelerator/Snapshots/RFQ-JENSA_Setpoints.snp:REA_BTS19:BEAM:A_BOOK,0,1545240215.74320185 5,NO_ALARM,NONE,double,"58.0",,"---",,true 2557c599d2dc67d80ffc5b9be3f79899e0c15a10:ReAccelerator/Snapshots/RFQ-JENSA_Setpoints.snp:REA_BTS19:BEAM:A_BOOK,0,1545240215.74320185 5,NO_ALARM,NONE,double,"58.0",,"---",,true 7fc97ec2aa76f32265196c42dbcd289c49f0ad93:ReAccelerator/Snapshots/RFQ-JENSA_Setpoints.snp:REA_BTS19:BEAM:A_BOOK,0,1545240215.74320185 5,NO_ALARM,NONE,double,"58.0",,"---",,true...
但我最终希望控制台的输出看起来与上面的 git one-liner 相同,或者更好的是,我可以打印到控制台或做其他事情的 dict。
【问题讨论】:
标签: python-3.x git subprocess