Git-对于单个文件,每行更改的次数 总结
给定一个受Git版本控制的文件,我想使用Git内置或Bash生成一个报告,其中列出每行的更改次数 差异、散列、作者和其他细节将被丢弃,唯一需要的结果是每行的数字,表示自历史开始以来的更改量 该文件保证具有相同的结构和行数,否则该报告将几乎没有用处 理由 我正在训练一个神经网络,将中间状态持久化到文件系统。此导出描述系统中每个神经元的连接和权重 由于文件处于版本控制之下,我想通过查看连接的易变性来衡量连接的强度。这种波动性可能与连接发生变异的次数有关。一个连接就是一条线路 问题 我正在考虑Git-对于单个文件,每行更改的次数 总结,git,bash,Git,Bash,给定一个受Git版本控制的文件,我想使用Git内置或Bash生成一个报告,其中列出每行的更改次数 差异、散列、作者和其他细节将被丢弃,唯一需要的结果是每行的数字,表示自历史开始以来的更改量 该文件保证具有相同的结构和行数,否则该报告将几乎没有用处 理由 我正在训练一个神经网络,将中间状态持久化到文件系统。此导出描述系统中每个神经元的连接和权重 由于文件处于版本控制之下,我想通过查看连接的易变性来衡量连接的强度。这种波动性可能与连接发生变异的次数有关。一个连接就是一条线路 问题 我正在考虑git-
git-log
、git-bull
或两者的精心组合来生成这样的报告
我的实际解决方案使用带有L
标志的git log
,并逐行迭代。虽然这样做有效,但是为一个包含数百次提交的1000+LOC文件生成报告的速度非常慢
请看下面的代码片段以了解我的位置
#!/bin/bash
for (( line=$line_start; line<$line_end; line++ )) ; do
lines=$(git log -L ${line},${line}:${file_input} | grep -c "diff")
echo "${line}:${lines}" >> ${file_output}
done
#/bin/bash
对于((line=$line\u start;line>${file\u output}
完成
问题:
依靠VCS(在本例中为Git)生成报告(列出给定文件中每行的更改次数)的最佳执行时间解决方案是什么?鉴于文件总是k行长,您想知道行Li,0≤ i
read file first or last commit
C = [0 for i in num_lines(file)]
L = [file_line[i] for i in num_lines(file)]
for commit in all_remaining_commits_in_forward_or_reverse_order:
read file from commit
for i in num_lines(file):
if file_line[i] != L[i]:
C[i] += 1
L[i] = file_line[i]
(在伪代码中)。除了从每次提交中提取文件(可能使用,
Git show:
)并获取提交列表(可能使用,Git log--topo order
)之外,使用Git本身几乎没有什么意义.这是一项有趣但非常不平凡的任务。我想到的唯一可行的解决方案是以反向顺序分析差异,这可能很有挑战性,因为不知道在发生更改时删除或添加了哪一行。关于这一点:git diff--shortstat
可以安全地假设文件总是k行长,你的假设也是正确的,A→B、 B→A、 A→B计为3。我只花了时间检查您的git命令,并得出以下结论:git log--format=format:%H--topo order{u file{u124; xargs-I{}git show{}:{u file{/code>。这将生成25MB的输出(文件的所有阶段)不到一秒钟,所以执行时间实际上非常好。我猜您的意思是--pretty=format:%H
或--format=%H
。请注意,您可以使用git rev list
,其含义和参数与git log
基本相同,但必须提供一个起点(git log
默认为HEAD
),如果您总是想要完整的散列ID(git rev list
针对shell脚本,而git log
针对用户可消化的输出)。谢谢您的更正。我将检查git rev list
的功能,并最终实现伪代码。当我结束时,我将接受您的回答,尽管我没有发现任何可能出错的地方。