PowerShell 自动化实战:自动化为 Git Staged 内容添加 Issue 注释标记

💡 前言:为何需要自动添加注释?

在实际开发中,我们经常遇到如下需求:

  • 当我们完成一个功能或修复一个 bug 后,需要在提交代码的同时记录其对应的 issue 编号;
  • 或者我们希望在每次 git add 阶段就自动生成注释格式,如:
javascript 复制代码
// Start: Added for CN-XXXXX
    const newFunction = () => {
        return 'New content added for this task'
    }
// End: Added for CN-XXXXX

这样的做法能显著增强版本历史的可读性与追溯能力。传统的解决方式通常是手动插入注释,效率低且容易遗漏。

本文将介绍一个实用的 PowerShell 脚本 ,它可以在 git add 上运行,自动识别出新增的代码块,并自动在其前后插入预定义注释标签。该方法非常适合本地使用或集成到构建流水线中。

❓ 第一部分:这个 PowerShell 脚本能解决什么问题?

假设你正在为多个 feature 新增代码并准备提交,但忘记为每一个新方法添加 issue 标记,后续追踪时便困难重重。这个问题可以通过下面几个步骤解决:

目标 功能描述
✅ 获取 staged 区域的所有 diff 使用 git diff --cached 获取当前暂存的内容
✅ 解析 diff 提取所有新增代码 提取 git hunk 中以 + 开头的有效行
✅ 找回这些代码在文件中的位置 在原文件中进行逐行比对
✅ 插入 marker 注释 将 start/end 索引注释写入实际文件中

🚀 脚本结构简化示意

以下是简化版逻辑流程图:

🧠 第二部分:代码结构详解 + 示例分析

完整的 PowerShell 脚本如下(已隐藏真实项目路径和 issue number):

🔧 脚本核心变量介绍

ini 复制代码
$issueNumber = "CN XXXXXX"
$lines         = $gitDiff -split "`n"
$currentFile   = $null
$patchBlocks   = @()
$currentPatch  = @()
$inHunk        = $false
  • $issueNumber:当前任务对应的 issue 编号
  • $lines:来自 git diff --cached 的每行内容
  • $currentFile:当前解析中的文件路径
  • $patchBlocks:最终提取出来的 patch 列表集合
  • $currentPatch:正在解析的 diff code 行数组
  • $inHunk:判断是否处在 git diff 的 block 内部

📂 文件识别 & Diff Block 提取

处理 git diff 的关键是提取每个 patch block 中的真实代码行。关键逻辑如下:

bash 复制代码
if ($line -like "+++ b/*") {
    $currentFile = $line.Substring(5).Trim()
    continue
}
if ($line -match "^@@ -\d+,?\d* +(\d+),?(\d*) @@") {
    if ($inHunk) {
        $patchBlocks += @{
            File    = $currentFile
            Lines   = $currentPatch
        }
    }
    $inHunk     = $true
    $currentPatch = @()
}

当脚本检测到一个新的 patch 区块起点(由 @@ ... @@ 标签决定),就会把之前收集的一组 code line 存入 patch blocks 数组中。

✨ 有效代码清洗逻辑

为了仅提取真正的新增代码行,过滤掉空白、上下文无关信息等,脚本使用了以下逻辑:

perl 复制代码
if ($line.StartsWith("+") -and -not ($line.StartsWith("++"))) {
    $code = $line.Substring(1).TrimEnd()
    if ($code.Trim() -ne "") {
        $currentPatch += $code
    }
}

上述逻辑确保我们只保留非空、真实的新增代码行,并去除多余的缩进或前缀字符。

🔁 第三部分:匹配与注释插入算法详解

🔑 Step 1:文件路径重建

ini 复制代码
$filePath = Join-Path $PWD.Path $block.File

Join-Path 将相对路径转换为绝对路径,比如:

bash 复制代码
$PSScriptRoot → C:\MyProject\src\
$file →       lwc/deal.js
→ full path = C:\MyProject\src\lwc\deal.js

🛠️ Step 2:查找 patch 在文件中的位置

perl 复制代码
for ($i = 0; $i -lt $contentArr.Length; $i++) {
    $match = $true
    for ($j = 0; $j -lt $block.Lines.Count; $j++) {
        ...
    }
    if ($match) {
        # 插入 marker ...
    }
}

这部分是典型的"逐行比较算法",目的是确定当前 patch 是否已经存在于原文件中。如果存在,则插入 marker。

注意:由于直接字符比对,所以要求源文件内容与 patch 完全一致才能插入,否则无法匹配上。

🖋️ Step 3:插入 marker 注释

bash 复制代码
$newContent = $contentArray[0..$i] +
              $markerStart +
              $contentArray[i..(i + count)] +
              $markerEnd +
              $contentArray[(i + count)..]

这是一个构造新的内容数组的方法,通过拼接原内容与 mark 注释的方式实现插入效果。

🧹 结语:小技巧带来大便利

虽然这个 PowerShell 脚本看似简单,但它完美地解决了在本地工作流中自动标注代码与 issue 编号的需求。这不仅让开发者省去了手动标注的时间,还提高了团队协作效率和代码透明度。

如果你也在寻找一款提升本地开发自动化的小工具,不妨试着将此脚本嵌入你的 Git 工作流中!

🔗 附录:完整 PowerShell 脚本

php 复制代码
# 定义 Issue 编号
$issueNumber = "CN XXXXXX"
Write-Host "Analyzing staged changes..."
# 获取 staged 的 git diff
$gitDiff = git diff --cached -U0
if (-not $gitDiff) {
    Write-Host "No changes are currently staged."
    exit
}
# 按行处理 diff 内容
$lines = $gitDiff -split "`n"
$currentFile = $null
$patchBlocks = @()
$currentPatch = @()
$inHunk = $false
foreach ($line in $lines) {
    if ($line.StartsWith("diff ")) { continue }
    if ($line -match "^index .+$") { continue }
    if ($line -like "+++ b/*") {
        $currentFile = $line.Substring(5).Trim()
        continue
    }
    if ($line -match "^@@ -\d+,?\d* +(\d+),?(\d*) @@") {
        if ($inHunk) {
            $patchBlocks += @{ File = $currentFile; Lines = $currentPatch }
        }
        $inHunk = $true
        $currentPatch = @()
    }
    if ($inHunk) {
        if ($line.StartsWith("+") -and -not ($line.StartsWith("++"))) {
            $code = $line.Substring(1).TrimEnd()
            if ($code.Trim() -ne "") {
                $currentPatch += $code
            }
        }
    }
}
if ($inHunk -and $currentPatch.Count -gt 0) {
    $patchBlocks += @{ File = $currentFile; Lines = $currentPatch }
}
$markerStart = "    // Start: Added for $issueNumber"
$markerEnd = "    // End: Added for $issueNumber"
foreach ($block in $patchBlocks) {
    $filePath = Join-Path $PWD.Path $block.File
    if (-not (Test-Path $filePath)) {
        Write-Warning "File not found: $filePath"
        continue
    }
    $contentArr = Get-Content -Path $filePath
    for ($i = 0; $i -lt $contentArr.Length; $i++) {
        $match = $true
        for ($j = 0; $j -lt $block.Lines.Count; $j++) {
            if ($i + $j -ge $contentArr.Length -or 
                $contentArr[$i + $j].Trim() -ne $block.Lines[$j].Trim()) {
                $match = $false
                break
            }
        }
        if ($match) {
            $newContent = @()
            for ($k = 0; $k -lt $i; $k++) {
                $newContent += $contentArr[$k]
            }
            $newContent += $markerStart
            for ($k = 0; $k -lt $block.Lines.Count; $k++) {
                $newContent += $contentArr[$i + $k]
            }
            $newContent += $markerEnd
            for ($k = ($i + $block.Lines.Count); $k -lt $contentArr.Length; $k++) {
                $newContent += $contentArr[$k]
            }
            Set-Content -Path $filePath -Value $newContent
            Write-Host "Added markers to file '$filePath' at line(s): $($i) to $(($i + $block.Lines.Count - 1))"
            break
        }
    }
}
Write-Host "Markers added where applicable."

🙌 最后说句

如果你觉得这类"轻量级却高效的自动化工具"对你有用,请收藏、点赞或分享。也欢迎留言交流你的自动化经验,或告诉我你在脚本上还可以如何拓展!

相关推荐
AlienZHOU2 小时前
AI Coding 时代下,我的技术面试实践分享
前端·后端·面试
野生技术架构师3 小时前
2026 Java 面试全套总结,八股 + 场景 + AI 相关面试考点
java·人工智能·面试
狗头大军之江苏分军4 小时前
《潮水漫过十七岁》开学了
后端
苏三说技术4 小时前
如何看待GPT-6在UP主众测中碾压夺冠?它是现在最强大模型吗?
后端
mldong5 小时前
一份 JSON,一条能跑的审批流:把报销流程送上工作流引擎
后端·架构
wno7045 小时前
Spring Boot WebFlux增删改查
java·spring boot·后端
Captaincc5 小时前
AI用量v0.1.11更新发布 新增 jusage doctor 诊断指令 托盘展示token 和余额 新增 AutoClaw 支持
前端·后端·vibecoding
aramae6 小时前
模拟实现strlen()函数 (C语言)
c语言·开发语言·后端
kyriewen7 小时前
我让 AI 当面试官面了我一轮:第 3 个追问我就卡住了(附 10 道追问清单)
前端·面试·ai编程
IT_陈寒7 小时前
Python的GIL把我坑惨了,多线程跑得比单线程还慢
前端·人工智能·后端