如何解析 git diff 的输出并获取行信息(即已添加/修改了哪些行)?
我想要类似的东西
raw = `git diff`
parsed = Git.Diff.parse(raw)
parsed.each do |file|
file.each do |line|
puts "#{file.name} - #{line.number} - #{line.type}"
end
end
编辑:
示例输出
[
{
"file": "path/to/file1",
"lines": [
{ number: "1", type: "modified"},
{ number: "4", type: "deleted"},
{ number: "9", type: "added"}
]
},
{
"file": "path/to/file2",
"lines": [
{ number: "4", type: "modified"},
{ number: "5", type: "added"}
]
}
]
最佳答案
您需要的是将输出正确分组到文件 block 中并保留所需的内容。
获取差异
您只需运行即可获取它
`git --diff`
需要什么线路?
- 以
'diff --git'
开头的行,您可以从中获取文件名 - 以
'+ '
开头的行是添加的行 - 以
'- '
开头的行是已删除的行
如何对它们进行分组?
对于这些事情Enumerable#slice_before我想到了。
将其放在一起
我最终得到了这个原型(prototype):
raw_data = `git diff`.split("\n")
# Keep what is needed
clean_data = raw_data.select { |li|
li.starts_with?('diff --git') ||
li.starts_with?('- ') ||
li.starts_with?('+ ')
}
# Group the by file
# [[file_1, line1, line2, line3], [file_2, line1]]
file_data = clean_data.slice_before { |li| li.starts_with?('diff --git') }
# This is the output format
output = Hash.new {|h,k| h[k] = { added: 0, removed: 0 } }
# Populate the output
file_data.each_with_object(output) do |f_data, memo|
file, *file_info = f_data
file = file.split(' b/').first.gsub('diff --git a/', '')
file_info.each { |f_info|
memo[file][f_info[0] == '+' ? :added : :removed] += 1
}
end
输出示例
{
"file_1" => { added: 1, removed: 12 },
"file_2" => { added: 0, removed: 1 }
}
我相信它会变得更好:-)
关于Ruby Git Diff 行信息解析器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55164840/