UNPKG

branch-commit-compare

Version:
223 lines (202 loc) 6.93 kB
const { execSync } = require("child_process"); function getAllBranches() { try { // 使用 git branch -a 获取所有分支,包括 worktree const branches = execSync("git branch -a", { encoding: "utf-8" }) .split("\n") .map((branch) => { // 移除前导空格和当前分支标记 '*' branch = branch.trim().replace("* ", ""); // 如果是 worktree 分支(以 '+' 开头),保留完整名称 if (branch.startsWith("+")) { return branch; } // 如果是远程分支,去掉 remotes/ 前缀 if (branch.startsWith("remotes/")) { return branch.replace("remotes/", ""); } return branch; }) .filter(Boolean) // 移除空行 .filter((branch) => !branch.includes("HEAD")) // 移除 HEAD 引用 .filter( (branch, index, self) => // 去重,但保留 worktree 分支 self.indexOf(branch) === index || branch.startsWith("+") ); return branches; } catch (error) { return []; } } function getAllAuthors() { try { // 根据操作系统选择不同的实现方式 if (process.platform === "win32") { // Windows系统下的实现: // 1. 使用git log命令获取所有提交者的名字 // 2. %an 是git内置的格式化参数,表示"作者名字" const authorList = execSync('git log --format="%an"', { encoding: "utf-8", }) .split("\n") // 按行分割 .filter(Boolean); // 过滤掉空行 // 使用Set数据结构来去重 // 1. new Set()创建一个集合,自动去除重复值 // 2. [...集合] 将集合转回数组 const uniqueAuthors = [...new Set(authorList)]; return uniqueAuthors; } else { // Mac/Linux系统下的实现: // 使用管道命令 | 组合git log和sort // 1. git log --format="%an" 获取所有作者名字 // 2. sort -u 对结果进行排序并去重 const authors = execSync('git log --format="%an" | sort -u', { encoding: "utf-8", }) .split("\n") // 按行分割 .filter(Boolean); // 过滤掉空行 return authors; } } catch (error) { // 如果出现错误,打印错误信息并返回空数组 console.error("获取作者列表失败:", error.message); return []; } } function getDateRange(timeRange) { // 使用上海时区 const now = new Date(); const tzOffset = 8 * 60; // 上海时区 UTC+8 const localTime = new Date( now.getTime() + (tzOffset + now.getTimezoneOffset()) * 60000 ); switch (timeRange) { case "最近一周": return new Date(localTime - 7 * 24 * 60 * 60 * 1000) .toISOString() .replace(/T.+/, ""); case "最近两周": return new Date(localTime - 14 * 24 * 60 * 60 * 1000) .toISOString() .replace(/T.+/, ""); case "最近一个月": return new Date(localTime - 30 * 24 * 60 * 60 * 1000) .toISOString() .replace(/T.+/, ""); case "最近三个月": return new Date(localTime - 90 * 24 * 60 * 60 * 1000) .toISOString() .replace(/T.+/, ""); case "最近半年": return new Date(localTime - 180 * 24 * 60 * 60 * 1000) .toISOString() .replace(/T.+/, ""); case "最近一年": return new Date(localTime - 365 * 24 * 60 * 60 * 1000) .toISOString() .replace(/T.+/, ""); default: return ""; } } function getAllCommits(branchName, targetBranch, author, timeRange) { try { // 直接移除 + 前缀 const actualBranchName = branchName.startsWith("+") ? branchName.substring(1) : branchName; let baseCommand = `git log --pretty=format:"%H|%an|%s|%ai"`; if (author && author !== "全部") { baseCommand += ` --author="${author}"`; } if (timeRange && timeRange !== "全部时间") { const sinceDate = getDateRange(timeRange); if (sinceDate) { // 使用严格的时间范围过滤,同时设置until以确保不会包含未来的提交 const now = new Date(); const untilDate = now.toISOString().split("T")[0]; baseCommand += ` --since="${sinceDate}T00:00:00+08:00" --until="${untilDate}T23:59:59+08:00"`; } } // 修改命令,确保获取完整历史 const finalCommand = `${baseCommand} ${actualBranchName}`; console.log("执行Git命令:", finalCommand); // 调试日志 try { // 获取分支提交 const output = execSync(finalCommand, { encoding: "utf-8", maxBuffer: 10 * 1024 * 1024, // 增加缓冲区大小到10MB }); if (!output || output.trim() === "") { return []; } const commits = output .split("\n") .filter(Boolean) .map((commit) => { const parts = commit.split("|"); if (parts.length < 4) { return null; } const [hash, authorName, message, date] = parts; try { // 验证日期格式 const commitDate = new Date(date); if (isNaN(commitDate.getTime())) { console.warn( `警告: 无效的提交日期格式 [${date}] for commit ${hash}` ); return null; } // 转换为上海时区的时间 const tzOffset = 8 * 60; // 上海时区 UTC+8 const localDate = new Date( commitDate.getTime() + (tzOffset + commitDate.getTimezoneOffset()) * 60000 ); // 验证时间范围(如果指定了时间范围) if (timeRange && timeRange !== "全部时间") { const sinceDate = new Date( getDateRange(timeRange) + "T00:00:00+08:00" ); const now = new Date(); if (localDate < sinceDate || localDate > now) { console.warn( `警告: 提交日期超出范围 [${date}] for commit ${hash}` ); return null; } } return { hash, authorName, message, date: localDate.toISOString(), dateIso: date, // 保留原始ISO日期字符串 }; } catch (dateError) { console.error( `处理提交日期时出错 [${date}] for commit ${hash}:`, dateError ); return null; } }) .filter((commit) => commit !== null); return commits; } catch (cmdError) { console.error("执行Git命令失败:", cmdError); return []; } } catch (error) { console.error("获取提交记录失败:", error); return []; } } module.exports = { getAllBranches, getAllAuthors, getAllCommits, getDateRange, };