【Node】git 统计用户某天的提交次数、提交详情
效果:
使用方式: node gitCommitReport.js
注意修改:定义要扫描的根目录
代码:
▼js复制代码const child_process = require("child_process"); const fs = require("fs"); const readline = require("readline"); // 定义要扫描的根目录 const rootDir = "C:\\99\\code"; // 要忽略的目录 const ignoreDirs = [ "node_modules", "dist", "build", "target", ".idea", ".vscode", ".cache", "logs", "__pycache__", ".venv", ".next", ".nuxt", "vendor/bundle", ]; console.log("开始查找 Git 仓库目录..."); // 查找所有包含 .git 文件夹的目录,并排除忽略的目录 function findGitRepos(dir) { const repos = []; const entries = fs.readdirSync(dir, { withFileTypes: true }); for (const entry of entries) { const fullPath = `${dir}\\${entry.name}`; if (entry.isDirectory()) { if (ignoreDirs.some((ignoreDir) => fullPath.includes(ignoreDir))) { continue; } if (fs.existsSync(`${fullPath}\\.git`)) { repos.push(fullPath); } else { repos.push(...findGitRepos(fullPath)); } } } return repos; } const repos = findGitRepos(rootDir); console.log(`共找到 ${repos.length} 个 Git 仓库目录。`); // 创建 readline 接口 const rl = readline.createInterface({ input: process.stdin, output: process.stdout, }); // 提示用户输入 Git 账号名 rl.question("Please enter your Git username: ", (gitUsername) => { // 提示用户输入日期(格式:YYYY-MM-DD) rl.question("Please enter the date (format: yyyy-MM-dd): ", (inputDate) => { rl.close(); // 计算时间范围 const startDate = `${inputDate} 00:00:00`; const endDate = `${inputDate} 23:59:59`; // 初始化计数器 let totalCommits = 0; const commitDetails = []; let completedRepos = 0; // 遍历每个仓库 repos.forEach((repo) => { const command = `git -C ${repo} log --after="${startDate}" --before="${endDate}" --pretty="%h|%an|%ad|%s" --date=iso --no-merges`; child_process.exec( command, { encoding: "utf8" }, (error, stdout, stderr) => { if (error) { console.error( `Error processing repository ${repo}:`, error.message ); } else { const commits = stdout .split("\n") .filter((line) => line.trim() !== ""); // 过滤当前用户的提交 const userCommits = commits.filter((line) => line.startsWith(`${line.split("|")[0]}|${gitUsername}|`) ); // 统计提交次数 const count = userCommits.length; totalCommits += count; // 收集提交详情 if (count > 0) { userCommits.forEach((line) => { const parts = line.split("|", 4); commitDetails.push({ Repo: repo.split("\\").pop(), Hash: parts[0], Author: parts[1], Date: parts[2], Message: parts[3], }); }); } } completedRepos++; if (completedRepos === repos.length) { // 按照日期时间递增排序 commitDetails.sort((a, b) => { const dateA = new Date( `${a.Date.split(" ")[0]} ${a.Date.split(" ")[1] .split(":") .slice(0, 2) .join(":")}` ); const dateB = new Date( `${b.Date.split(" ")[0]} ${b.Date.split(" ")[1] .split(":") .slice(0, 2) .join(":")}` ); return dateA - dateB; }); // 输出结果 console.log("Daily Commits Report"); console.log("===================="); console.log(`Date: ${inputDate}`); console.log(`User: ${gitUsername}`); console.log(`Total Commits: ${totalCommits}`); console.log("\nCommit Details:"); if (commitDetails.length === 0) { console.log("No commits found"); } else { console.table( commitDetails.map((item) => ({ Repository: item.Repo, Hash: item.Hash, Date: `${item.Date.split(" ")[0]} ${item.Date.split(" ")[1] .split(":") .slice(0, 2) .join(":")}`, Message: item.Message, })) ); } } } ); }); }); });
使用 uTools 插件 快捷命令 版
输出今天和昨天的 git 提交信息
效果:
代码:
注意修改 Git 账号 用户名:
▼js复制代码// 写死 Git 账号 const gitUsername = "ygr99";
▼js复制代码const child_process = require("child_process"); const fs = require("fs"); // 定义要扫描的根目录 const rootDir = "C:\\99\\code"; // 要忽略的目录 const ignoreDirs = [ "node_modules", "dist", "build", "target", ".idea", ".vscode", ".cache", "logs", "__pycache__", ".venv", ".next", ".nuxt", "vendor/bundle", ]; console.log("开始查找 Git 仓库目录..."); // 查找所有包含 .git 文件夹的目录,并排除忽略的目录 function findGitRepos(dir) { const repos = []; const entries = fs.readdirSync(dir, { withFileTypes: true }); for (const entry of entries) { const fullPath = `${dir}\\${entry.name}`; if (entry.isDirectory()) { if (ignoreDirs.some((ignoreDir) => fullPath.includes(ignoreDir))) { continue; } if (fs.existsSync(`${fullPath}\\.git`)) { repos.push(fullPath); } else { repos.push(...findGitRepos(fullPath)); } } } return repos; } const repos = findGitRepos(rootDir); console.log(`共找到 ${repos.length} 个 Git 仓库目录。`); // 写死 Git 账号 const gitUsername = "ygr99"; // 获取今天和昨天的日期 const now = new Date(); const today = new Date(now.getFullYear(), now.getMonth(), now.getDate()); const yesterday = new Date(today); yesterday.setDate(yesterday.getDate() - 1); // 格式化日期为 yyyy-MM-dd 格式 function formatDate(date) { const year = date.getFullYear(); const month = String(date.getMonth() + 1).padStart(2, '0'); const day = String(date.getDate()).padStart(2, '0'); return `${year}-${month}-${day}`; } const todayDate = formatDate(today); const yesterdayDate = formatDate(yesterday); // 处理日期范围 function processDateRange(date) { const startDate = `${date} 00:00:00`; const endDate = `${date} 23:59:59`; // 初始化计数器 let totalCommits = 0; const commitDetails = []; let completedRepos = 0; // 遍历每个仓库 repos.forEach((repo) => { const command = `git -C ${repo} log --after="${startDate}" --before="${endDate}" --pretty="%h|%an|%ad|%s" --date=iso --no-merges`; child_process.exec( command, { encoding: "utf8" }, (error, stdout, stderr) => { if (error) { console.error( `Error processing repository ${repo}:`, error.message ); } else { const commits = stdout .split("\n") .filter((line) => line.trim() !== ""); // 过滤当前用户的提交 const userCommits = commits.filter((line) => line.startsWith(`${line.split("|")[0]}|${gitUsername}|`) ); // 统计提交次数 const count = userCommits.length; totalCommits += count; // 收集提交详情 if (count > 0) { userCommits.forEach((line) => { const parts = line.split("|", 4); commitDetails.push({ Repo: repo.split("\\").pop(), Hash: parts[0], Date: parts[2], Message: parts[3], }); }); } } completedRepos++; if (completedRepos === repos.length) { // 按照日期时间递增排序 commitDetails.sort((a, b) => { const dateA = new Date( `${a.Date.split(" ")[0]} ${a.Date.split(" ")[1] .split(":") .slice(0, 2) .join(":")}` ); const dateB = new Date( `${b.Date.split(" ")[0]} ${b.Date.split(" ")[1] .split(":") .slice(0, 2) .join(":")}` ); return dateA - dateB; }); // 输出结果 console.log("Daily Commits Report"); console.log("===================="); console.log(`Date: ${date}`); console.log(`User: ${gitUsername}`); console.log(`Total Commits: ${totalCommits}`); console.log("\nCommit Details:"); if (commitDetails.length === 0) { console.log("No commits found"); } else { commitDetails.forEach((item) => { const time = item.Date.split(" ")[1].split(":").slice(0, 2).join(":"); const repoName = `【${item.Repo}】`; console.log(`${time} ${repoName} ${item.Message}`); }); } } } ); }); } // 先处理今天的 processDateRange(todayDate); // 等待一段时间确保今天的处理完成后再处理昨天的(可以根据实际情况调整等待时间) setTimeout(() => { processDateRange(yesterdayDate); }, 3000);
评论
问答助学
相关内容
0个评论
全部评论
点击登录,快来和大家讨论吧~
表情
图片
暂无评论
作者分享
【Electron】图片魔方
3
梦里的场景像被岁月浸过的老胶片,每一帧都带着温润的质感——指尖触到的藤蔓带着晨露的冰凉,远处钟楼的铜铃声震得空气发颤,甚至连擦肩而过的陌生人衣角上的暗纹,都清晰得如同刻在视网膜上。当意识从梦境的深潭里浮上来时,指尖还残留着虚空中攥住的微凉,目光扫过熟悉的天花板,却有半分恍惚悬在现实与幻梦的交界处,仿佛灵魂还在那片真实得令人心悸的风景里迟迟不肯归位。
2
99起始页:[99起始页](http://123.60.153.252:99)
上班摸鱼之作:一个拥有 40 多个组件的浏览器标签页,而且 99% 的代码都是 AI 帮我实现的!【从 4 月 6 日实现第一个组件,到现在 5 月 29 日,平均一天一个组件,中间有 1 个星期比较消极没咋搞】从随机哔哩哔哩到观音灵签,每个组件都是工作间隙的小小成就。
虽然只是基于前端三件套的简单实现,但借助 Cursor 和 AI 的强大能力,我只需提出想法,代码就自动生成了。这种高效协作让我能在不引人注意的情况下,悄悄构建自己的数字乐园。
当我看到这些组件在页面上流畅运行时,那种成就感比完成工作任务还要爽!这大概是 AI 时代最完美的摸鱼方式了。
#AI 编程 #上班摸鱼 #前端开发 #打工人的小确幸
4
反常规工具类型设计文档 ——5 大「反向生活助手」创意
3
程序员自救指南:从「想做很多事」到「开始第一件事」
8
