Git日志收集工具:让写周报更轻松

99 阅读2分钟

在日常工作中,编写周报往往需要回顾过去一周的工作内容。对于开发人员来说,Git提交记录是最好的工作记录。但是手动收集多个项目的Git日志比较麻烦,特别是当你同时负责多个项目时。这个小工具就是为了解决这个问题而开发的。它的主要功能包括:

  • 多项目管理:可以同时添加多个Git项目目录

  • 目录记忆:会保存已添加的项目目录,下次打开时自动加载

  • 时间范围选择:可以自定义要查看的时间范围(默认7天)

  • 一键收集:点击收集按钮,自动获取所有项目的提交记录

  • 自动复制:将收集到的日志自动复制到剪贴板,方便直接粘贴到周报中

使用这个工具,你只需要:

  • 添加需要统计的项目目录

  • 设置要查看的时间范围

  • 点击"收集日志"按钮

工具就会自动收集所有项目的Git提交记录,并整理成易读的格式。这样就可以快速回顾自己的工作内容,轻松完成周报编写。这个工具特别适合需要经常编写工作周报的开发人员使用,能够大大提高周报编写的效率。

import os
import tkinter as tk
from tkinter import filedialog, ttk, messagebox
import subprocess
from datetime import datetime, timedelta
import json
import pyperclip

# 在文件开头定义一个默认的目录列表
DEFAULT_DIRS = []

class GitLogCollector:
    def __init__(self):
        self.root = tk.Tk()
        self.root.title("Git Log 收集器")
        self.root.geometry("600x500")
        
        # 加载缓存的目录
        self.cached_dirs = DEFAULT_DIRS
        
        # 项目目录列表
        self.dirs_frame = ttk.LabelFrame(self.root, text="选择的项目目录", padding=10)
        self.dirs_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=5)
        
        self.dirs_listbox = tk.Listbox(self.dirs_frame)
        self.dirs_listbox.pack(fill=tk.BOTH, expand=True)
        
        # 从缓存加载目录到列表
        for dir in self.cached_dirs:
            self.dirs_listbox.insert(tk.END, dir)
        
        # 按钮区域
        self.btn_frame = ttk.Frame(self.root, padding=10)
        self.btn_frame.pack(fill=tk.X, padx=10, pady=5)
        
        ttk.Button(self.btn_frame, text="添加目录", command=self.add_directory).pack(side=tk.LEFT, padx=5)
        ttk.Button(self.btn_frame, text="移除选中", command=self.remove_directory).pack(side=tk.LEFT, padx=5)
        
        # 时间范围选择
        self.time_frame = ttk.LabelFrame(self.root, text="时间范围", padding=10)
        self.time_frame.pack(fill=tk.X, padx=10, pady=5)
        
        self.time_var = tk.StringVar(value="7")
        ttk.Entry(self.time_frame, textvariable=self.time_var, width=5).pack(side=tk.LEFT, padx=5)
        ttk.Label(self.time_frame, text="天内").pack(side=tk.LEFT)
        
        # 执行按钮
        ttk.Button(self.root, text="收集日志", command=self.collect_logs).pack(pady=10)
        
        # 窗口关闭时保存目录
        self.root.protocol("WM_DELETE_WINDOW", self.on_closing)
    
    def add_directory(self):
        directory = filedialog.askdirectory()
        if directory:
            self.dirs_listbox.insert(tk.END, directory)
            self.save_cached_dirs()
    
    def remove_directory(self):
        selection = self.dirs_listbox.curselection()
        if selection:
            self.dirs_listbox.delete(selection)
            self.save_cached_dirs()
    
    def save_cached_dirs(self):
        directories = list(self.dirs_listbox.get(0, tk.END))
        current_file = os.path.abspath(__file__)
        with open(current_file, 'r', encoding='utf-8') as f:
            content = f.read()
        
        # 更新DEFAULT_DIRS的值
        new_content = content.replace(
            f"DEFAULT_DIRS = {DEFAULT_DIRS}",
            f"DEFAULT_DIRS = {directories}"
        )
        
        with open(current_file, 'w', encoding='utf-8') as f:
            f.write(new_content)
    
    def on_closing(self):
        self.save_cached_dirs()
        self.root.destroy()
    
    def collect_logs(self):
        directories = self.dirs_listbox.get(0, tk.END)
        if not directories:
            messagebox.showwarning("警告", "请至少选择一个项目目录")
            return
            
        days = int(self.time_var.get())
        since_date = f"{days} days ago"
        
        log_content = ""
        for directory in directories:
            log_content += f"\n=== {os.path.basename(directory)} ===\n"
            try:
                result = subprocess.run(
                    ['git', 'log', '--pretty=format:%s', f'--since={since_date}'],
                    cwd=directory,
                    capture_output=True,
                    text=True,
                    encoding='utf-8'
                )
                log_content += result.stdout or "没有找到提交记录\n"
            except Exception as e:
                log_content += f"Error: {str(e)}\n"
       
        messagebox.showinfo("Git日志", log_content)
        # 将结果复制到剪贴板
        pyperclip.copy(log_content)
        messagebox.showinfo("完成", "日志已复制到剪贴板")
        
    def run(self):
        self.root.mainloop()

if __name__ == "__main__":
    app = GitLogCollector()
    app.run()