返回市场
MCP-Git-提交助手

MCP-Git-提交助手

作者:MrOrz7 星标更新:2025-05-13

项目介绍

git-commit-aider MCP 服务器

代表AI进行Git提交,以便您可以在代码库中追踪AI的贡献。

这是一个基于TypeScript的MCP服务器,提供了一个工具来提交Git仓库中的暂存更改,并在提交者的名字后面自动添加"(aider)"。

功能

此MCP服务器仅提供一个工具:

commit_staged - 使用特定消息提交暂存更改。

  • 接受message(字符串,必需)作为提交信息。
  • 接受cwd(字符串,可选)指定git命令的工作目录。
  • 自动在提交者名字后追加"(aider)"。
  • 如果设置了环境变量GIT_COMMITTER_NAMEGIT_COMMITTER_EMAIL,则从这些环境变量读取提交者的名字和邮箱;否则,回退到git config user.namegit config user.email

在您的代码编辑器中安装此工具后,可以通过类似以下提示来触发AI:

为我提交这些更改

通常,在AI对您的代码库进行了某些更改之后,会使用此功能。因此,AI通常能够根据上下文提供一个好的提交信息。

安装

要使用此服务器,请将其配置添加到您的MCP设置文件中。

{
  "mcpServers": {
    "git-commit-aider": {
      "command": "npx",
      "args": ["mcp-git-commit-aider"]
    }
  }
}

提交者信息从以下来源获取:

  1. 环境变量GIT_COMMITTER_NAMEGIT_COMMITTER_EMAIL,遵循git的约定
  2. git config user.namegit config user.email命令的输出。

替代方案:提交后修改作者

如果您不想使用这个MCP服务器,也可以直接在终端中使用git命令。

您可以先进行正常的提交,然后使用以下git命令来更改最后一次提交的作者:

git commit --amend --author="$(git config user.name) (aider) <$(git config user.email)>"

这将把最后一次提交的作者更改为您的名字,并在其后追加"(aider)"。

为了简化这一过程,您可以设置一个Git别名。在您的终端中运行以下命令:

git config --global alias.aimend '!git commit --amend --author="$(git config user.name) (aider) <$(git config user.email)>"'

设置完成后,您可以通过运行以下命令来使用该别名:

git aimend

计算AI贡献

带有"(aider)"的提交可以被aider --stats命令捕获,该命令将显示AI在您的代码库中的贡献。

或者,您可以使用以下脚本来计算AI在您的代码库中的贡献,以行数(增加、删除和总变化)为单位。

#!/bin/bash

# 脚本用于计算由AI和人类作者之间的行变化(增加、删除、总变化)
# 输出为JSON格式。
#
# 此逻辑是从git-quick-stats.sh提取并修改而来的,MIT许可。

# --- 配置 ---
# 您可以根据自己的仓库惯例更改配置。

# 用于识别AI生成提交的作者名称中的字符串
AI_MATCHER="(aider)"

# 定义要排除的文件/路径模式,这些将转换为git路径规格如":(exclude)*package-lock.json"
IGNORE_PATTERNS=(
  "*package-lock.json"
  "*.lock"
)

# --- 辅助函数 ---
function print_usage() {
  echo "用法: $0 <REVISION_RANGE>"
  echo "  <REVISION_RANGE>: 要分析的修订范围(例如,HEAD~5..HEAD, my-branch, commit_sha)。"
  echo "  参考'git help log'或'git help revisions'以了解更多的范围选项。"
  echo "示例: $0 HEAD~5..HEAD"
  echo "示例: $0 origin..HEAD"
  echo "示例: $0 my-feature-branch"
  echo "示例: $0 abcdef1..fedcba2"
}

# --- 参数解析 ---
if [ "$#" -ne 1 ]; then
  echo "错误: 参数数量不正确。请提供一个修订范围。"
  print_usage
  exit 1
fi

REVISION_RANGE="$1"

# --- 主逻辑 ---

# 构建git log的路径规格参数
pathspec_args=()
for pattern in "${IGNORE_PATTERNS[@]}"; do
  pathspec_args+=(":(exclude)$pattern")
done

git_log_output=$(git log "$REVISION_RANGE" --numstat --pretty="format:AuthorName:%an" -- "${pathspec_args[@]}")

# DEBUG: 解除注释以检查每个提交的计算情况。
# echo "$git_log_output"

# 使用awk处理日志输出
result_json=$(echo "$git_log_output" | awk -v ai_matcher="$AI_MATCHER" '
BEGIN {
  ai_added = 0
  ai_deleted = 0
  human_added = 0
  human_deleted = 0
  current_author = ""
  is_ai_author = 0
}

/^AuthorName:/ {
  # 提取作者名称
  current_author = substr($0, length("AuthorName:") + 1)
  if (index(current_author, ai_matcher) > 0) {
    is_ai_author = 1
  } else {
    is_ai_author = 0
  }
  next
}

# 跳过提交块之间的空行或非numstat行
NF == 0 || !($1 ~ /^[0-9]+$/ && $2 ~ /^[0-9]+$/) {
  next
}

# 处理numstat行:<增加> <删除> <文件>
{
  added_lines = $1
  deleted_lines = $2

  # 跳过numstat显示“-”的二进制文件
  if (added_lines == "-" || deleted_lines == "-") {
    next
  }

  # 按作者和文件聚合统计详情数组
  file_name = $3
  # 使用文件分隔符字符\034的健壮键
  key = current_author "\034" file_name

  file_author_added[key] += added_lines
  file_author_deleted[key] += deleted_lines

  if (is_ai_author) {
    ai_added += added_lines
    ai_deleted += deleted_lines
  } else {
    human_added += added_lines
    human_deleted += deleted_lines
  }
}

END {
  ai_total_changed = ai_added + ai_deleted
  human_total_changed = human_added + human_deleted
  overall_total_changed = ai_total_changed + human_total_changed
  ai_percentage = 0.00

  if (overall_total_changed > 0) {
    ai_percentage = (ai_total_changed / overall_total_changed) * 100
  }

  printf "{\n"
  printf "  \"ai_percentage\": %.2f,\n", ai_percentage
  printf "  \"ai_changes\": {\"added\": %d, \"deleted\": %d, \"total\": %d},\n", ai_added, ai_deleted, ai_total_changed
  printf "  \"human_changes\": {\"added\": %d, \"deleted\": %d, \"total\": %d},\n", human_added, human_deleted, human_total_changed

  # 详细数组
  printf "  \"details\": [\n"
  first_detail = 1
  # 迭代其中一个数组,键应一致
  for (key in file_author_added) {
    if (!first_detail) {
      printf ",\n"
    }
    first_detail = 0

    # 分割键"author\034fileName"到key_parts数组
    # key_parts[1]将是author,key_parts[2]将是fileName
    split(key, key_parts, "\034")
    author = key_parts[1]
    fileName = key_parts[2]

    # 为JSON兼容性替换双引号
    gsub(/"/, "\\\"", author)
    gsub(/"/, "\\\"", fileName)

    detail_added = file_author_added[key] + 0 # 确保数值
    detail_deleted = file_author_deleted[key] + 0 # 确保数值
    detail_total = detail_added + detail_deleted

    printf "    {\n"
    printf "      \"fileName\": \"%s\",\n", fileName
    printf "      \"author\": \"%s\", \"isAI\": %s,\n", author, (index(author, ai_matcher) > 0 ? "true" : "false")
    printf "      \"added\": %d, \"deleted\": %d, \"total\": %d\n", detail_added, detail_deleted, detail_total
    printf "    }"
  }
  printf "\n  ]\n"
  printf "}\n"
}
')

# --- 输出 ---
echo "$result_json"

使用示例:

# 假设脚本保存为`calculate_ai_contribution.sh`并且是可执行的(chmod +x calculate_ai_contribution.sh)

# 示例1:分析最后5个提交
./calculate_ai_contribution.sh HEAD~5..HEAD

# 示例2:分析特定提交与HEAD之间的提交
./calculate_ai_contribution.sh 90a5fcd4..HEAD

# 示例3:分析尚未合并到主分支的功能分支上的所有提交
./calculate_ai_contribution.sh main..my-feature-branch

# 示例4:分析两个标签之间的提交
./calculate_ai_contribution.sh v1.0..v1.1

# 示例输出(将根据您的仓库和范围有所不同):
# {
#   "ai_percentage": 48.53,
#   "ai_changes": { "added": 100, "deleted": 32, "total": 132 },
#   "human_changes": { "added": 103, "deleted": 37, "total": 140 },
#   "details": [
#     {
#       "fileName": "src/featureA.js",
#       "author": "Developer One (aider)", "isAI": true,
#       "added": 60, "deleted": 10, "total": 70
#     },
#     {
#       "fileName": "src/featureB.js",
#       "author": "Developer One (aider)", "isAI": true,
#       "added": 40, "deleted": 22, "total": 62
#     },
#     {
#       "fileName": "src/utils.js",
#       "author": "Developer Two", "isAI": false,
#       "added": 80, "deleted": 15, "total": 95
#     },
#     {
#       "fileName": "README.md",
#       "author": "Developer Two", "isAI": false,
#       "added": 23, "deleted": 22, "total": 45
#     }
#   ]
# }

输出字段描述

JSON输出包含以下字段:

  • ai_percentage: (数字) 总行数变化(增加和删除行数之和)中由AI作者(通过AI_MATCHER标识)贡献的百分比。
  • ai_changes: (对象) 一个对象,详细说明了AI作者的聚合行变化(增加的行数added,删除的行数deleted及其总和total)。
  • human_changes: (对象) 一个对象,详细说明了人类作者的聚合行变化(增加的行数added,删除的行数deleted及其总和total)。
  • details: (对象数组) 提供详细的变更分解。数组中的每个对象表示特定author对特定fileName的贡献,包括该作者对该文件的增加行数added,删除行数deleted以及总的变更行数total