mcpField
G
git-commit-aider MCP Server

git-commit-aider MCP Server

本地服务
github.com/MrOrz版本控制876 周前更新

关于 git-commit-aider MCP Server

git-commit-aider 是一个 TypeScript MCP 服务,用于提交 Git 暂存更改,并在提交者名称后附加“(aider)”,帮助团队识别 AI 参与的提交。

主要功能

  1. 01提交 Git 暂存更改
  2. 02通过参数指定提交信息和工作目录
  3. 03提交者名称自动添加 (aider)
  4. 04从环境变量或 Git 配置读取提交者信息

适用场景

  1. 01让 AI 在完成代码修改后创建提交
  2. 02在 Git 历史中标记 AI 参与的提交
  3. 03按提交标记统计代码库中的 AI 贡献

MCP 相关

该 MCP 服务提供 commit_staged 工具,可按指定提交信息提交暂存更改,并自动标记提交者名称。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

暂未收录安装方式

我们还没有获取到这个服务的安装包或远程地址,请按项目 README 中的说明安装。

代码仓库

工具

还没有获取到工具列表

本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。

详细介绍

git-commit-aider MCP 服务

代表 AI 创建 Git 提交,以便在代码库中追踪 AI 的贡献。

这是一个基于 TypeScript 的 MCP 服务,提供一个工具,用于提交 Git 仓库中的暂存更改,并在提交者姓名后附加 “(aider)”。

功能

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

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

  • 接受 message(字符串,必填)作为提交消息。
  • 接受 cwd(字符串,可选)来指定 Git 命令的工作目录。
  • 自动在提交者姓名后附加 “(aider)”。
  • 如果已设置,则从环境变量(GIT_COMMITTER_NAME、GIT_COMMITTER_EMAIL)读取提交者姓名和邮箱;否则回退到 git config user.name 和 git config user.email。

在代码编辑器中安装此工具后,你可以像这样向 AI 提示:

替我提交这些更改

这通常发生在 AI 对代码库做出一些更改之后,因此 AI 往往能够根据上下文提供一条合适的提交消息。

安装

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

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

提交者信息从以下位置获取:

  1. 环境变量 GIT_COMMITTER_NAME 和 GIT_COMMITTER_EMAIL,遵循 Git 的约定。
  2. git config user.name 和 git 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

# Script to calculate line changes (added, deleted, total) by AI and human authors
# between two commits.
# Output is in JSON format.
#
# This logic is extracted and altered from git-quick-stats.sh, MIT license.

# --- Configuration ---
# You may change the config to match your repository's convention.

# String to identify AI-generated commits in author names
AI_MATCHER="(aider)"

# Define patterns for files/paths to be excluded from the calculation.
# These will be converted to git pathspecs like ":(exclude)*package-lock.json"
IGNORE_PATTERNS=(
  "*package-lock.json"
  "*.lock"
)

# --- Helper Functions ---
function print_usage() {
  echo "Usage: $0 <REVISION_RANGE>"
  echo "  <REVISION_RANGE>: The revision range to analyze (e.g., HEAD~5..HEAD, my-branch, commit_sha)."
  echo "  Refer to 'git help log' or 'git help revisions' for more range options."
  echo "Example: $0 HEAD~5..HEAD"
  echo "Example: $0 origin..HEAD"
  echo "Example: $0 my-feature-branch"
  echo "Example: $0 abcdef1..fedcba2"
}

# --- Argument Parsing ---
if [ "$#" -ne 1 ]; then
  echo "Error: Incorrect number of arguments. Please provide a single revision range."
  print_usage
  exit 1
fi

REVISION_RANGE="$1"

# --- Main Logic ---

# Construct pathspec arguments for 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: Uncomment to check the calculation for each commit.
# echo "$git_log_output"

# Process the log output with 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:/ {
  # Extract author name
  current_author = substr($0, length("AuthorName:") + 1)
  if (index(current_author, ai_matcher) > 0) {
    is_ai_author = 1
  } else {
    is_ai_author = 0
  }
  next
}

# Skip empty lines between commit blocks or lines that are not numstat
NF == 0 || !($1 ~ /^[0-9]+$/ && $2 ~ /^[0-9]+$/) {
  next
}

# Process numstat line: <added> <deleted> <file>
{
  added_lines = $1
  deleted_lines = $2

  # Skip binary files where numstat shows "-" for lines
  if (added_lines == "-" || deleted_lines == "-") {
    next
  }

  # Aggregate stats per author and file for details array
  file_name = $3
  # Robust key using File Separator character \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

  # Details array
  printf "  \"details\": [\n"
  first_detail = 1
  # Iterate over one of the arrays, keys should be consistent
  for (key in file_author_added) {
    if (!first_detail) {
      printf ",\n"
    }
    first_detail = 0

    # Split key "author\034fileName" into key_parts array
    # key_parts[1] will be author, key_parts[2] will be fileName
    split(key, key_parts, "\034")
    author = key_parts[1]
    fileName = key_parts[2]

    # Escape double quotes for JSON compatibility
    gsub(/"/, "\\\"", author)
    gsub(/"/, "\\\"", fileName)

    detail_added = file_author_added[key] + 0 # Ensure numeric
    detail_deleted = file_author_deleted[key] + 0 # Ensure numeric
    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"
}
')

# --- Output ---
echo "$result_json"

用法示例:

# Assume the script is saved as `calculate_ai_contribution.sh` and is executable (chmod +x calculate_ai_contribution.sh)

# Example 1: Analyze the last 5 commits
./calculate_ai_contribution.sh HEAD~5..HEAD

# Example 2: Analyze commits between a specific commit and HEAD
./calculate_ai_contribution.sh 90a5fcd4..HEAD

# Example 3: Analyze all commits on a feature branch not yet in main
./calculate_ai_contribution.sh main..my-feature-branch

# Example 4: Analyze commits between two tags
./calculate_ai_contribution.sh v1.0..v1.1

# Example output (will vary based on your repository and range):
# {
#   "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。

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。