zoukankan      html  css  js  c++  java
  • 通过 python 获取一个 git commit 的改动行信息

    前置知识

    • git diff 命令可以用来查看某个 commit 的改动信息。具体详细的用法可以参考 git-diff 中的介绍。有一个命令 git diff HEAD^ HEAD 可以输出当前的 commit 的改动内容。
      • 其中输出的改动内容是有一定的格式的。对本次改动影响的文件,会包含如下信息:
        • 本次改动之前的的文件名
        • 本次改动之后的文件名
        • 本次改动的
    • python 可以同步执行一个 shell 命令,并获得命令的输出。

    代码

    直接贴代码了,可以通过下面的 python 方法获取到(执行 prepareInfomation 方法,返回的):

    import os
    import re
    from typing import *
    import subprocess
    
    class ChangedLineInfo:
        def __init__(self):
            self.changedLineNumbers = set()
    
        def addChangeInfo(self, startLine: int, lineCount: int):
            """
            补充改变的行号信息,
            startLine : 表示从该行起始有改变。
            lineCount : 表示从改行起,有多少行被改变了。
            """
            endLine = startLine + lineCount
            if (endLine < startLine):
                return
            for i in range(startLine, endLine):
                self.changedLineNumbers.add(i)
    
        def isLineChanged(self, line: int) -> bool:
            return line in self.changedLineNumbers
    
    def getChangedLineInfoFromDiffLines(lines: List[str]) -> ChangedLineInfo:
        """
        该方法计算出 ,返回一个 ChangedLineInfo 对象
        参数 : lines , git-diff 命令输出的,对一个文件的描述
        返回 : 返回一个ChangedLineInfo, 表示从 lines 中解析出来的 改变了的行 的信息。
        """
        changedLineInfo = ChangedLineInfo()
        # 根据 "@@ @@" 获取改变行信息
        # 匹配到的 [0] : ","+从此处起始的删除行数; [1] : 从此处新增的行数起始行; [2] : ","+从此处新增的行数数量
        reg = re.compile("^@@ -[0-9]+(,[0-9]+)? +([0-9]+)(,[0-9]+)? @@")
        for line in lines:
            r = reg.findall(line)
            if len(r) > 0:
                changedLineStart = int(r[0][1])
                caughtLineCountStr = r[0][2]
                if len(caughtLineCountStr) > 0:
                    changedLineCount = int(caughtLineCountStr[1:])
                else:
                    changedLineCount = 1
                changedLineInfo.addChangeInfo(changedLineStart, changedLineCount)
        return changedLineInfo
    
    
    
    def prepareInfomation():
        """
        执行一些操作,准备好数据并且返回:
        :return: 一个 map, key 为本次 commit 导致的"非删除文件"的路径(相对于 git 仓库的路径); value 为 ChangedInfo 对象,表示该文件的改动行信息.
        """
        gitCmd = "git diff --unified=0 --diff-filter=d HEAD~1 HEAD"
        gitDiffOutputRaw = subprocess.check_output(gitCmd.split(" "))
        outputStr = gitDiffOutputRaw.decode('utf-8')
        diffOutputLines = outputStr.splitlines()
    
        map = {}
        # 匹配到这个的一行表示开始结果开始展示 一个新的文件的 diff 信息,匹配到的信息 [0] 表示文件名
        # !!!!!!!!!! 忽略带有空格的文件名的处理, 对于带有空格的文件名,该检测会出错.但是暂时忽略
        separateLineReg = re.compile("^diff --git a/S+ b/(S+)")
        currentCheckFileName = ""
        diffLinesForCurrentCheckFile = []
        for i in range(len(diffOutputLines)):
            l = diffOutputLines[i]
            # 如果当前匹配到了 separateLine ,则
            # 1. 解析 diffLinesForCurrentCheckFile,并且将 { currentCheckFileName : 解析后的信息} 加入到 map 中;
            # 2. 更新当前的 currentCheckFileName ; 清空 diffLinesForCurrentCheckFile
            # 如果未匹配到,加入 diffLinesForCurrentCheckFile , 继续下一行
            separateLineMatchResult = separateLineReg.findall(l)
            if len(separateLineMatchResult) > 0:
                if len(diffLinesForCurrentCheckFile) > 0:
                    a = getChangedLineInfoFromDiffLines(diffLinesForCurrentCheckFile)
                    map[currentCheckFileName] = a
                    diffLinesForCurrentCheckFile.clear()
                # 只匹配了一个项,所以不需要使用 separateLineMatchResult[0][0]
                currentCheckFileName = separateLineMatchResult[0]
            else:
                diffLinesForCurrentCheckFile.append(l)
            # 已经是最后一行
            if i == len(diffOutputLines) - 1:
                a = getChangedLineInfoFromDiffLines(diffLinesForCurrentCheckFile)
                map[currentCheckFileName] = a
        return map
    
    
    
  • 相关阅读:
    C# sqlhelp
    vs2015 C#打包程序为exe
    python3.6安装docx模块
    python 第八天
    python 第七天
    python 选课系统
    python 第六天
    python 模拟实现一个ATM + 购物商城程序
    python 计算器
    python 第五天
  • 原文地址:https://www.cnblogs.com/wkmcyz/p/14716288.html
Copyright © 2011-2022 走看看