如何在pygit2的diff中为每个文件更改行

  • 本文关键字:文件 pygit2 diff python pygit2
  • 更新时间 :
  • 英文 :


使用pygit2,我可以获得被更改的文件总数、插入总数、删除总数以及文件的相对路径。参见下面的代码。但是,我找不到一种方法来获得git diff --stats显示的每个修改文件的行更改统计信息。我能用pygit2写吗?

def get_diff_stats(repo_path, commit_a, commit_b):
repo = Repository("{}/.git".format(repo_path))
diff = repo.diff(commit_a, commit_b)
print(diff.stats.files_changed)
print(diff.stats.insertions)
print(diff.stats.deletions)
for delta in diff.deltas:
print(delta.new_file.path, delta.status_char())

不完全确定你是否仍然关心,但我发现你的问题,需要自己的答案。最后通过阅读一些相当枯燥的文档来解决这个问题。

from pygit2 import init_repository, Patch
from colorama import Fore

git_repo = init_repository(repo_path)
diff = git_repo.diff(commit_a, commit_b, context_lines=0, interhunk_lines=0)
# A diff contains Patches or Diffs. We care about patches (changes in a file)
for obj in diff:
if type(obj) == Patch:
print(f"Found a patch for file {obj.delta.new_file.path}")

# A hunk is the change in a file, plus some lines surounding the change. This allows merging etc. in Git. 
# https://www.gnu.org/software/diffutils/manual/html_node/Hunks.html
for hunk in obj.hunks:
for line in hunk.lines:
# The new_lineno represents the new location of the line after the patch. If it's -1, the line has been deleted.
if line.new_lineno == -1: 
print(f"[{Fore.RED}removal line {line.old_lineno}{Fore.RESET}] {line.content.strip()}")
# Similarly, if a line did not previously have a place in the file, it's been added fresh. 
if line.old_lineno == -1: 
print(f"[{Fore.GREEN}addition line {line.new_lineno}{Fore.RESET}] {line.content.strip()}")  

可以看到,一个diff可以包含多个patch和diff。因此,我们需要循环遍历它们。Diff对象的行为就像一个集合(从文档中看不太清楚)。补丁包含我们需要的信息。实际改变的线条可以在Hunks中找到。这是一个来自GNU diff utils文档的术语,描述了这些变化和一些上下文。

最新更新