编写一个python脚本,用于为每一条git记录增加行号

2023-02-27  本文已影响0人  _我和你一样

之所以有这个想法是,每一次发提测邮件时,都要附上提交记录,git log 在输出时,本身可以做到格式化的输出,但是没有序号不知道多少条,整体显得比较凌乱,尤其是 git 提交时,不仅有subject还有body时,邮件显得就更乱了,为了自动化加工git日志,想着编写一个python脚本来处理,将结果直接输出到剪切版

  1. 本脚本在设计时,希望可以灵活使用,既可以直接使用命令行获取,也可以作为模块导入到其他模块中,比如导入到自动化打包机中
  2. 本脚本在设计时,希望可以提供灵活的使用,定义了很多自定义参数,为了方便使用,每个参数都有默认值,需要哪个参数就传递哪个参数
  3. 尽可能可以在Mac、Linux、Windows平台都能使用

算法原理什么的就不说了,注释写的很详细,直接上干货

#!/usr/bin/python3
# -*- coding: utf-8 -*-

'为git日志输出增加序号'

__author__ = 'Huang Jiashu'

import os
import sys
import getopt # 用于获取命令行输入
import pathlib as plb # 用于跨平台路径
import clipboard as cboard # 用于剪切板


# 用途:通过对git log 的处理 ,为每一个commit 添加 序号 1、2、3、 等
# 说明:本脚本使用python3编写,使用此脚步您需要pyhton3的环境,并且需要安装clipboard模块用于将处理后的结果copy到剪切板
# 提供默认参数,默认工作路径workspace,默认 git log 命令

short_opt = "h:w:s:e:a:n:f:g:b:"
long_opt = ["help"
        "workspace=",
        "start_date=",
        "end_date=",
        "author=",
        "number=",
        "format=",
        "git_log_cmd=",
        "branch="]
workspace = "xxx.git"#默认的工作目录,即git仓库目录,您可以在此修改一次永久使用,也可以通过参数传入
git_log_cmd = ''#可以传入整个git 命令,其他参数失效
start_date = ''#开始时间
end_date = ''#结束时间 可以不传
author = ''#作者 可以不传
number = '1000' #获取个数 默认最多输出1000个可以不传
format = "%an%s%n%b"#可以不传
branch = ''#分支名

def handleArgInCmd():
      #0 获取命令行输入
    argv = sys.argv[1:]
    opts = []
    # print(f"命令行输入内容为:{argv}")
    global workspace,start_date,end_date,author,number,format,git_log_cmd,branch;
    try:
        opts, args = getopt.getopt(argv,short_opt,long_opt)
        print(f"opts:{opts},args:{args}")

        for opt, arg in opts:
            if opt in ['-w','--workaspce']:
                workspace = arg
            elif opt in ['-s','--start_date']:
                start_date = arg
            elif opt in ['-e','--end_date']:
                end_date = arg
            elif opt in ['-a','--author']:
                author = arg
            elif opt in ['-n',"--number"]:
                number = arg
            elif opt in ['-f','--format']:
                format = arg
            elif opt in ['-g','--git_log_cmd']:
                git_log_cmd = arg
            elif opt in ['-b','--branch']:
                branch = arg
            # print(f'opt:{opt},arg:{arg}')
    except Exception as e:
        print(f"Error:{e.args}")

def handleLog(workspace=workspace,branch=branch,start_date=start_date,end_date=end_date,author=author,number=number,format=format,git_log_cmd=git_log_cmd):
    print(f'worksapce:{workspace},branch:{branch},start_date:{start_date},end_date:{end_date},author:{author},number:{number},format:{format},cmd:{git_log_cmd}')
    if not plb.Path(workspace).exists():
        print("工作路径不存在,请确认")
        sys.exit()
        
    # 1. 切换工作路径 到 git仓库所在位置
    log_path = plb.PurePath(plb.Path.home(),'commit-log.txt') # 适配 Linux系统 和 Windows系统 在不同平台表示不同,中间过度使用,不作为最终输出
    os.chdir(workspace)
    print("1. 搜集日志,已切换到工作目录")
    # 如果使用自己git-log-cmd命令,则直接使用,将结果导入我们预备好的文件
    if len(git_log_cmd) <= 0:
        # 使用自定义
        git_log_cmd = f'git log --no-merges'
        if len(branch):
            git_log_cmd += f' {branch}'
        if len(author):
            git_log_cmd += f' --author={author}'
        if len(start_date):
            git_log_cmd += f' --after={start_date}'
        if len(end_date):
            git_log_cmd += f' --until={end_date}'
        git_log_cmd += f' -n {number}'
        git_log_cmd += f' --format=###{format}###'# 增加开始结束标记
        git_log_cmd += f'>{log_path}'
    # 执行git命令,将结果写入临时文件
    print(f'执行命令为:{git_log_cmd}')
    os.system(git_log_cmd)
    # 2. 获取日志 格式您可以自定义 这里是 名字提交信息头换行提交信息体 前后添加了每一条到开始和结束标记 用于后续拎出来每一次的提交
    print("2. 已获取日志文件,正在处理...")
    # 3. 处理日志,添加 序号
    logContent = ""
    index = 1
    with open(log_path,'r') as f:
        for line in f.readlines():
            # 结束标记
            if line == os.linesep or line == f"###{os.linesep}":
                continue
            handledLine = line
            # 获取###是每一条日志的开始
            if handledLine.startswith("###"):
                #   添加序号,删除 前缀标记
                handledLine = f"{index}、" + line[3:]
                index += 1;
            logContent += handledLine
    f.close()

    # 4. 复制到剪贴板
    cboard.copy(logContent)
    print("3. 日志处理完毕,已copy到粘贴板")
    return logContent


def main():
    try:
        argv = sys.argv[1:]
        print(f"命令行输入内容为:{argv}")
        opts, args = getopt.getopt(argv, short_opt, long_opt)
    except getopt.GetoptError as err:
        # print help information and exit:
        print(err)  # will print something like "option -a not recognized"
        usage()
        sys.exit(2)

    for o, a in opts:
        if o in ("-h", "--help"):
            usage()
            sys.exit()
        else:
            handleArgInCmd()
            handleLog(
                workspace,
                branch,
                start_date,
                end_date,
                author,
                number,
                format,
                git_log_cmd
            )
            return

def usage():
    usage = """
    使用说明:几乎所有的选项都是可选的
    0. -h 或者 --help 帮助
    1. -w 或者 --workspace= 表示工作路径
    2. -s 或者 --start_date= 表示日志开始时间
    3. -e 或者 --end_date= 表示日志结束时间
    4. -a 或者 --author= 表示作者
    5. -n 或者 --number= 表示日志最大个数
    6. -f 或者 --format= 表示 自定义的fomart 格式
    7. -b 或者 --branch= 表示获取哪个分支的日志
    8. -g 或者 --git_log_cmd= 表示使用自定义的git_log_cmd命令,使用此命令不会添加序号
    """
    print(usage);

# handleLog()

if __name__ == "__main__":
    main()
上一篇 下一篇

猜你喜欢

热点阅读