一、概述:跨仓库协作的挑战
现代软件工程中,项目规模不断膨胀,单一代码仓库(Monorepo)和多仓库(Polyrepo)两种架构各有利弊。当团队选择多仓库策略时,跨仓库协作便成为不可回避的工程难题。依赖管理、版本同步、CI/CD 协调、代码共享、Issue 追踪等环节都需要专门的工具和工作流来支撑。
Claude Code 作为 AI 辅助编程工具,能够在跨仓库协作场景中发挥独特作用——通过上下文感知、多文件分析、自动化脚本生成等能力,帮助团队高效管理多仓库间的复杂依赖关系。
核心挑战一览:
- 多仓库间的依赖版本管理 —— 如何确保 A 仓库的变更不会破坏 B 仓库
- 跨仓库的代码共享机制 —— 共享库、内部包的分发和版本控制
- 统一 CI/CD 流水线 —— 依赖仓库更新后如何自动触发下游构建
- 跨仓库 Issue 和 PR 的追踪 —— 全局视角的项目管理
- Git 子模块和子树的管理 —— 子仓库的更新、冲突解决和迁移
二、多仓库策略选型:Monorepo vs Polyrepo
2.1 Monorepo 方案
Monorepo 将所有相关项目放在同一个 Git 仓库中管理。优点在于原子提交、统一构建、简化依赖。但仓库体积会快速增长,Git 操作性能下降,权限控制粒度较粗。
Turborepo 配置示例
{
"$schema": "https://turbo.build/schema.json",
"globalDependencies": ["**/.env.*local"],
"pipeline": {
"build": {
"dependsOn": ["^build"],
"outputs": ["dist/**", ".next/**"],
"inputs": ["src/**/*.ts", "src/**/*.tsx"]
},
"test": {
"dependsOn": ["build"],
"inputs": ["src/**/*.test.ts", "src/**/*.spec.ts"]
},
"lint": {
"outputs": []
},
"deploy": {
"dependsOn": ["build", "test", "lint"],
"outputs": []
}
}
}
Nx 工作空间配置示例
{
"extends": "nx/presets/npm.json",
"tasksRunnerOptions": {
"default": {
"runner": "nx/tasks-runners/default",
"options": {
"cacheableOperations": ["build", "test", "lint"],
"parallel": 5
}
}
},
"targetDefaults": {
"build": {
"dependsOn": ["^build"],
"outputs": ["{projectRoot}/dist"]
},
"test": {
"dependsOn": ["build"]
}
}
}
2.2 Polyrepo 方案
Polyrepo 将不同服务或模块放在独立的 Git 仓库中。优点在于团队自治、独立发布、权限隔离。缺点是跨仓库变更需要多个 PR,版本对齐困难,全局重构成本高。
2.3 Workspace 方案
包管理器内置的 Workspace 功能是实现 Monorepo 的基础设施:
npm Workspaces
{
"name": "my-monorepo",
"private": true,
"workspaces": [
"packages/*",
"apps/*"
],
"scripts": {
"build": "npm run build --workspaces --if-present",
"test": "npm run test --workspaces --if-present",
"lint": "npm run lint --workspaces --if-present"
}
}
Yarn Workspaces
{
"name": "my-monorepo",
"private": true,
"workspaces": {
"packages": ["packages/*", "apps/*"],
"nohoist": ["**/react-native", "**/react-native/**"]
}
}
pnpm Workspaces
packages:
- "packages/*"
- "apps/*"
- "tools/*"
- "!**/test/fixtures/**"
选型建议:
- 小型团队(<10人): Monorepo + pnpm workspaces + Turborepo,学习成本低,开箱即用
- 中型团队(10-50人): Monorepo + Nx,缓存和分布式任务执行能力强
- 大型组织(>50人): Polyrepo + 统一工具链 + 自动同步机制,团队自治与全局协调兼顾
- 微服务架构: Polyrepo + CI/CD 协调发布 + 跨仓库依赖追踪
三、跨仓库依赖管理
3.1 版本同步策略
跨仓库依赖的核心问题是版本同步。常用的策略包括:
- 固定版本(Pinned): 下游仓库锁定上游依赖的具体版本,需要手动更新
- 范围版本(Range): 使用语义化版本范围(如 ^1.2.0),自动接受补丁更新
- Git 引用: 直接引用 Git 仓库的特定分支或提交(如 user/repo#main)
- 本地链接: 开发阶段使用 npm link / yarn link / pnpm link 进行本地调试
版本对齐脚本示例
CORE_VERSION=$(node -p "require('./packages/core/package.json').version")
REPOS=("service-a" "service-b" "service-c" "web-app" "mobile-app")
for repo in "${REPOS[@]}"; do
echo "更新 $repo 中的 @myorg/core 到 v$CORE_VERSION ..."
cd "../$repo"
jq ".dependencies[\"@myorg/core\"] = \"^$CORE_VERSION\"" package.json \
> package.json.tmp && mv package.json.tmp package.json
git add package.json
git commit -m "chore: sync @myorg/core to v$CORE_VERSION"
git push origin main
cd -
done
echo "所有仓库版本已同步完成。"
3.2 依赖更新与变更检测
依赖更新需要自动化的变更检测机制。常用的方案是基于文件变化触发依赖分析:
const { execSync } = require('child_process');
const fs = require('fs');
function getDependentRepos(changedPackage) {
const config = JSON.parse(
fs.readFileSync('dependency-graph.json', 'utf-8')
);
return config.dependencies
.filter(dep => dep.dependency === changedPackage)
.map(dep => dep.repository);
}
function checkForBreakingChanges(repo, oldVersion, newVersion) {
const log = execSync(
`git log ${oldVersion}..${newVersion} --oneline --grep="BREAKING"`
).toString().trim();
return log.length > 0;
}
const changedPkg = process.argv[2];
const oldVer = process.argv[3];
const newVer = process.argv[4];
const downstream = getDependentRepos(changedPkg);
const hasBreaking = checkForBreakingChanges(changedPkg, oldVer, newVer);
console.log(`检测到变更: ${changedPkg} ${oldVer} → ${newVer}`);
console.log(`影响的下游仓库: ${downstream.join(', ')}`);
console.log(`是否包含破坏性变更: ${hasBreaking ? '是' : '否'}`);
if (hasBreaking) {
console.log('建议: 创建跨仓库 PR 进行适配更新');
} else {
console.log('建议: 自动提交依赖更新 PR 到下游仓库');
}
3.3 版本兼容矩阵管理
当涉及多个互相依赖的包时,维护版本兼容矩阵变得至关重要:
| @myorg/core | @myorg/utils | service-a | service-b | 兼容性 |
| 1.0.x | 1.0.x | 2.x | 3.x | 兼容 |
| 1.1.x | 1.1.x | 2.x | 3.x | 兼容 |
| 2.0.x | 2.0.x | 3.x | 4.x | 需要迁移 |
| 2.0.x | 1.x | — | — | 不兼容 |
{
"packages": {
"@myorg/core": { "latest": "2.0.0", "compatible": ["1.0.0", "1.1.0"] },
"@myorg/utils": { "latest": "2.0.0", "compatible": ["1.0.0", "1.1.0"] },
"@myorg/types": { "latest": "1.5.0", "compatible": ["1.0.0"] }
},
"dependencies": [
{ "repository": "service-a", "dependency": "@myorg/core", "range": "^1.0.0" },
{ "repository": "service-b", "dependency": "@myorg/core", "range": "^2.0.0" },
{ "repository": "service-a", "dependency": "@myorg/utils", "range": "^1.0.0" }
],
"rules": [
{ "if": "core@^1.0.0 && utils@^1.0.0", "then": "service-a@2.x" },
{ "if": "core@^2.0.0 && utils@^2.0.0", "then": "service-b@4.x" }
]
}
3.4 自动发布与包发布顺序
在多包仓库中,包的发布顺序直接影响下游依赖的可用性。正确的策略是拓扑排序:先发布最底层的依赖包,逐层向上发布。
calculate_publish_order() {
node -e "
const graph = {
'@myorg/types': [],
'@myorg/utils': ['@myorg/types'],
'@myorg/core': ['@myorg/utils'],
'@myorg/react-ui': ['@myorg/core', '@myorg/utils'],
'@myorg/server-sdk': ['@myorg/core'],
'@myorg/client-sdk': ['@myorg/core', '@myorg/utils'],
};
// Kahn 拓扑排序
const inDegree = {};
const adj = {};
Object.keys(graph).forEach(pkg => {
inDegree[pkg] = inDegree[pkg] || 0;
adj[pkg] = adj[pkg] || [];
graph[pkg].forEach(dep => {
adj[dep] = adj[dep] || [];
adj[dep].push(pkg);
inDegree[pkg] = (inDegree[pkg] || 0) + 1;
});
});
const queue = Object.keys(inDegree).filter(p => inDegree[p] === 0);
const order = [];
while (queue.length > 0) {
const pkg = queue.shift();
order.push(pkg);
(adj[pkg] || []).forEach(dep => {
inDegree[dep]--;
if (inDegree[dep] === 0) queue.push(dep);
});
}
console.log('发布顺序:');
order.forEach((pkg, i) => console.log(\` \${i + 1}. \${pkg}\`));
"
}
order=$(calculate_publish_order)
echo "$order"
for pkg in $(echo "$order" | grep -oP '\d+\.\s+\K\S+'); do
echo "正在发布 $pkg ..."
(cd "packages/$pkg" && npm publish)
done
echo "所有包发布完成!"
四、统一 CI/CD 流水线
4.1 多仓库流水线架构
跨仓库的 CI/CD 策略需要在独立构建和统一协调之间取得平衡。推荐的架构是:每个仓库维护自己的 CI 配置,但通过共享的 Workflow 模板和跨仓库触发机制实现统一调度。
GitHub Actions 跨仓库触发
name: 跨仓库触发构建
on:
push:
branches: [main]
paths:
- 'packages/core/**'
- 'packages/utils/**'
jobs:
trigger-downstream:
runs-on: ubuntu-latest
steps:
- name: 触发下游仓库构建
uses: peter-evans/repository-dispatch@v3
with:
token: ${{ secrets.CROSS_REPO_PAT }}
repository: myorg/service-a
event-type: upstream-changed
client-payload: |
{
"upstream": "${{ github.repository }}",
"ref": "${{ github.ref }}",
"commit": "${{ github.sha }}",
"changed-packages": ["core", "utils"]
}
- name: 触发 service-b 构建
uses: peter-evans/repository-dispatch@v3
with:
token: ${{ secrets.CROSS_REPO_PAT }}
repository: myorg/service-b
event-type: upstream-changed
client-payload: '{"upstream": "${{ github.repository }}"}'
- name: 等待下游构建完成
run: |
echo "等待所有下游仓库构建完成..."
sleep 30
echo "所有下游构建已触发。"
下游仓库接收事件并构建
name: 上游依赖更新
on:
repository_dispatch:
types: [upstream-changed]
jobs:
build-and-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: 解析上游信息
run: |
echo "上游仓库: ${{ github.event.client_payload.upstream }}"
echo "触发提交: ${{ github.event.client_payload.commit }}"
- name: 更新依赖版本
run: |
UPSTREAM_COMMIT="${{ github.event.client_payload.commit }}"
jq '.dependencies["@myorg/core"] = "github:myorg/core#'$UPSTREAM_COMMIT'"' \
package.json > package.json.tmp
mv package.json.tmp package.json
- name: 安装依赖
run: npm ci
- name: 运行测试
run: npm test
- name: 构建
run: npm run build
- name: 创建自动更新 PR
if: success()
uses: peter-evans/create-pull-request@v6
with:
token: ${{ secrets.GITHUB_TOKEN }}
commit-message: "chore: auto-update dependency to ${{ github.event.client_payload.commit }}"
title: "自动依赖更新: 来自 ${{ github.event.client_payload.upstream }}"
body: |
上游仓库 ${{ github.event.client_payload.upstream }} 已更新。
本次提交已通过构建和测试验证。
branch: auto-dependency-update
delete-branch: true
4.2 协调发布与批量更新
当多个仓库需要同时发布时,协调发布策略至关重要。常用的模式包括:
- 版本锁步(Version Lockstep): 所有相关包使用相同版本号,一起发布
- 独立版本(Independent): 每个包独立版本化,单独发布
- 固定窗口发布: 设定固定的发布窗口(如每周四),集中处理所有变更
- 原子发布: 使用发布编排工具确保所有仓库同时或按依赖顺序发布
跨仓库批量更新脚本
REPOS=("service-a" "service-b" "service-c" "web-app" "admin-panel")
BRANCH="chore/update-core-to-v2"
TITLE="chore: 更新 @myorg/core 到 v2.0.0"
BODY="更新核心库到 v2.0.0,修复了若干安全性问题并提升了性能。"
for repo in "${REPOS[@]}"; do
echo "处理 $repo ..."
git clone "git@github.com:myorg/$repo.git" "tmp/$repo"
cd "tmp/$repo"
git checkout -b "$BRANCH"
jq '.dependencies["@myorg/core"] = "^2.0.0"' package.json > pkg.tmp
mv pkg.tmp package.json
git add package.json
git commit -m "$TITLE"
git push origin "$BRANCH"
gh pr create \
--repo "myorg/$repo" \
--title "$TITLE" \
--body "$BODY" \
--base main \
--head "$BRANCH"
cd ../..
rm -rf "tmp/$repo"
done
echo "所有仓库的 PR 已创建完成!"
五、代码共享策略
5.1 共享库与内部包
代码共享是跨仓库协作的核心需求。常见的共享方式包括:
- 内部 npm 包: 发布到私有 npm registry(如 Verdaccio、GitHub Packages)
- Git 子模块: 将共享库作为子模块嵌入多个仓库
- Git 子树: 将共享库的代码复制到仓库的子目录中
- Copy 脚本: 通过脚本将共享代码同步到多个仓库
私有 npm 包发布示例
set -e
REGISTRY="https://npm.pkg.github.com"
SCOPE="@myorg"
PACKAGE_DIR="./packages/shared-utils"
echo "构建共享包..."
cd "$PACKAGE_DIR"
npm run build
echo "配置私有 registry..."
echo "registry=$REGISTRY" > .npmrc
echo "//npm.pkg.github.com/:_authToken=$GITHUB_TOKEN" >> .npmrc
echo "发布到私有 registry..."
npm publish --registry="$REGISTRY" --access restricted
echo "清理..."
rm .npmrc
echo "共享包发布成功!版本: $(node -p 'require(\"./package.json\").version')"
5.2 代码生成器与模板仓库
对于需要在多个仓库中重复使用的标准化代码结构,代码生成器和模板仓库是最有效的方案。
使用 Claude Code 生成跨仓库代码生成器
const fs = require('fs-extra');
const path = require('path');
const handlebars = require('handlebars');
const { execSync } = require('child_process');
async function generateService(name, { repo, description, port }) {
const templateDir = path.resolve(__dirname, '../templates/service');
const outputDir = path.resolve(process.cwd(), repo);
execSync(`git clone git@github.com:myorg/service-template.git ${outputDir}`);
const files = await fs.readdir(templateDir);
for (const file of files) {
const content = await fs.readFile(
path.join(templateDir, file), 'utf-8'
);
const template = handlebars.compile(content);
const rendered = template({ name, description, port });
const outputFile = file.replace('.hbs', '');
await fs.writeFile(
path.join(outputDir, outputFile), rendered
);
}
execSync(`
cd ${outputDir} &&
git init &&
git add . &&
git commit -m "chore: initial commit from template" &&
git remote add origin git@github.com:myorg/${repo}.git &&
git push -u origin main
`);
console.log(`服务 ${name} 已生成并推送到 ${repo} 仓库`);
}
generateService('user-service', {
repo: 'user-service',
description: '用户管理微服务',
port: 3001
});
5.3 脚手架工具
专业的脚手架工具可以大幅提升跨仓库初始化的效率:
{
"hooks": {
"postCreate": {
"command": "node .claude/init-repo.js",
"description": "初始化仓库结构和依赖"
}
},
"allowedCommands": {
"createRepo": {
"command": "gh repo create myorg/${1} --private --template myorg/service-template",
"description": "从模板创建新仓库"
},
"setupWorkspace": {
"command": "node .claude/setup-workspace.js ${1}",
"description": "设置跨仓库开发环境"
}
}
}
const { execSync } = require('child_process');
const fs = require('fs');
const path = require('path');
function setupCrossRepoWorkspace(workspaceName) {
const rootDir = path.resolve(process.cwd(), '..', workspaceName);
if (!fs.existsSync(rootDir)) {
fs.mkdirSync(rootDir, { recursive: true });
}
const workspacePkg = {
name: workspaceName,
private: true,
workspaces: ['packages/*', 'services/*'],
scripts: {
build: 'turbo run build',
test: 'turbo run test',
lint: 'turbo run lint',
clean: 'turbo run clean',
},
devDependencies: {
turbo: 'latest',
typescript: '^5.0.0',
},
};
fs.writeFileSync(
path.join(rootDir, 'package.json'),
JSON.stringify(workspacePkg, null, 2)
);
console.log(`Workspace ${workspaceName} 已创建`);
console.log(`请运行: cd ${rootDir} && npm install`);
}
const name = process.argv[2] || 'my-workspace';
setupCrossRepoWorkspace(name);
六、跨仓库 Issue 管理
6.1 全局看板与跨仓库标签
当 Issue 分散在多个仓库中时,需要一个统一的管理视图。推荐的方案包括:
- GitHub Projects(Beta): 支持跨仓库 Issue 的全局看板,自定义视图和字段
- 统一标签规范: 所有仓库使用相同的标签体系(如 area/frontend、priority/P0)
- 里程碑关联: 在组织级别定义里程碑,关联多个仓库的 Issue
- 自动化同步: 使用 GitHub Actions 或第三方工具同步跨仓库状态
跨仓库 Issue 标签同步脚本
REPOS=("core" "service-a" "service-b" "web-app" "mobile-app")
LABELS=(
"bug:red"
"enhancement:blue"
"feature:green"
"breaking:orange"
"good-first-issue:purple"
"area/frontend:yellow"
"area/backend:grey"
"area/infra:dark-blue"
"priority/P0:red"
"priority/P1:orange"
"priority/P2:yellow"
"priority/P3:grey"
)
for repo in "${REPOS[@]}"; do
echo "同步 $repo 标签..."
for label in "${LABELS[@]}"; do
IFS=':' read -r name color <<< "$label"
gh label create "$name" --color "$color" \
--repo "myorg/$repo" --force 2>/dev/null
done
done
echo "所有仓库标签已同步完成!"
6.2 跨仓库 Issue 依赖追踪
当一个功能的实现需要在多个仓库中分别提交变更时,追踪 Issue 间的依赖关系就变得至关重要。
---
name: 跨仓库功能请求
about: 描述一个需要在多个仓库中实现的功能
title: "[CROSS-REPO] "
labels: cross-repo, feature
---
## 功能描述
[清晰描述需要实现的功能]
## 涉及的仓库
- [ ] myorg/core — [所需变更]
- [ ] myorg/service-a — [所需变更]
- [ ] myorg/web-app — [所需变更]
## 依赖关系
- [ ] 阻塞: #ISSUE_NUMBER
- [ ] 被阻塞: #ISSUE_NUMBER
## 实现计划
1. 步骤 1: [仓库名] — [变更描述]
2. 步骤 2: [仓库名] — [变更描述]
3. 步骤 3: [仓库名] — [变更描述]
## 验收标准
- [ ] 标准 1
- [ ] 标准 2
## 关联 PR
- [ ] myorg/core#PR_NUMBER
- [ ] myorg/service-a#PR_NUMBER
6.3 跨仓库依赖追踪工具
const { execSync } = require('child_process');
async function getCrossRepoStatus(milestone) {
const repos = ['core', 'service-a', 'service-b', 'web-app'];
const report = [];
for (const repo of repos) {
const output = execSync(
`gh issue list --repo myorg/${repo} ` +
`--milestone "${milestone}" ` +
`--json number,title,state,labels,assignees`
).toString();
const issues = JSON.parse(output);
issues.forEach(issue => {
report.push({
repo,
number: issue.number,
title: issue.title,
state: issue.state,
labels: issue.labels.map(l => l.name),
assignees: issue.assignees.map(a => a.login),
url: `https://github.com/myorg/${repo}/issues/${issue.number}`,
});
});
}
console.log(`=== 里程碑: ${milestone} ===`);
console.log(`总 Issue 数: ${report.length}`);
console.log(
`已完成: ${report.filter(i => i.state === 'closed').length}`
);
console.log(
`进行中: ${report.filter(i => i.state === 'open').length}`
);
const byRepo = {};
report.forEach(i => {
byRepo[i.repo] = byRepo[i.repo] || [];
byRepo[i.repo].push(i);
});
Object.entries(byRepo).forEach(([repo, issues]) => {
console.log(`\n--- ${repo} ---`);
issues.forEach(i => {
console.log(` #${i.number} [${i.state}] ${i.title}`);
});
});
return report;
}
getCrossRepoStatus('v2.0 Release');
七、Git 子模块与子树
7.1 Git Submodule 管理
Git 子模块允许将一个仓库作为另一个仓库的子目录嵌入。虽然功能强大,但管理不当会导致诸多问题。
子模块操作命令集
git submodule add git@github.com:myorg/shared-lib.git packages/shared-lib
git clone --recurse-submodules git@github.com:myorg/main-repo.git
git submodule update --remote --merge
git submodule update --init --recursive
git submodule foreach 'git checkout main && git pull'
git submodule status
git submodule deinit -f packages/shared-lib
git rm packages/shared-lib
rm -rf .git/modules/packages/shared-lib
子模块更新自动化脚本
set -e
BRANCH=${1:-main}
echo "正在更新子模块到 $BRANCH 分支的最新提交..."
git submodule foreach "
echo \"处理子模块: \$name\"
git fetch origin
git checkout $BRANCH
git pull origin $BRANCH
if [ \$? -ne 0 ]; then
echo \"警告: \$name 更新失败,请手动检查\"
exit 1
fi
echo \"\$name 已更新到 \$(git rev-parse --short HEAD)\"
"
git add .
git commit -m "chore: update submodules to latest $BRANCH"
echo "所有子模块已更新完毕!"
7.2 Git Subtree 合并策略
与子模块不同,子树合并将外部仓库的代码直接复制到当前仓库中,不保留外部引用。这意味着主仓库的克隆不需要额外操作,但更新时需要手动同步。
子树操作命令集
git subtree add \
--prefix packages/shared-lib \
git@github.com:myorg/shared-lib.git \
main --squash
git subtree pull \
--prefix packages/shared-lib \
git@github.com:myorg/shared-lib.git \
main --squash
git subtree push \
--prefix packages/shared-lib \
git@github.com:myorg/shared-lib.git \
feature/new-feature
git subtree split \
--prefix packages/shared-lib \
--branch shared-lib-standalone
mkdir ../shared-lib && cd ../shared-lib
git init
git pull ../main-repo shared-lib-standalone
7.3 冲突解决策略
子模块和子树在团队协作中最容易遇到的问题就是冲突。以下是一些实用的冲突解决策略:
git status
cd packages/shared-lib
git status
git log --oneline -5
git checkout <正确的提交哈希>
cd ../..
git add packages/shared-lib
git commit -m "fix: resolve submodule conflict in shared-lib"
子模块 vs 子树 对比
| 特性 | Git Submodule | Git Subtree |
| 代码存储方式 | 指针引用(链接) | 直接复制代码 |
| 克隆体验 | 需要 --recurse-submodules | 正常克隆即可 |
| 修改流程 | 在子模块中修改后推送 | 在主仓库中修改后子树推送 |
| 历史保留 | 保留子模块完整历史 | 可选 --squash 压缩历史 |
| 学习曲线 | 中等 | 较高 |
| 适合场景 | 大型共享库、频繁更新 | 小型工具、偶尔更新 |
7.4 从子模块迁移到 Monorepo
当项目规模增长到一定程度,团队可能会决定从子模块方案迁移到 Monorepo。这是一个需要谨慎规划的过程:
set -e
MONOREPO_DIR="my-monorepo"
SUB_MODULES=(
"packages/shared-lib:git@github.com:myorg/shared-lib.git"
"packages/utils:git@github.com:myorg/utils.git"
"services/service-a:git@github.com:myorg/service-a.git"
)
echo "创建 Monorepo..."
mkdir -p "$MONOREPO_DIR"
cd "$MONOREPO_DIR"
git init
echo "合并子模块历史..."
for entry in "${SUB_MODULES[@]}"; do
IFS=':' read -r target_path repo_url <<< "$entry"
echo "合并 $repo_url 到 $target_path ..."
git remote add -f "remote-$(echo $target_path | tr '/' '-')" "$repo_url"
git merge -s ours --no-commit \
"remote-$(echo $target_path | tr '/' '-')/main" \
--allow-unrelated-histories 2>/dev/null || true
git read-tree --prefix="$target_path/" \
"remote-$(echo $target_path | tr '/' '-')/main"
git commit -m "chore: merge $target_path into monorepo"
git remote remove "remote-$(echo $target_path | tr '/' '-')"
done
echo "Monorepo 创建完成!"
echo "所有子模块历史已保留在对应的子目录中。"
echo "请验证后推送到远程仓库。"
八、使用 Claude Code 管理跨仓库工作流
8.1 跨仓库代码审查
Claude Code 可以同时分析多个仓库的代码变更,帮助审查跨仓库 PR 的整体影响。
commands:
cross-review:
description: "审查跨仓库 PR 集合"
command: |
repos=("service-a" "service-b" "web-app")
for repo in "${repos[@]}"; do
echo "=== 审查 $repo ==="
gh pr view $repo#$PR_NUMBER --json files,body,title
done
check-deps:
description: "检查跨仓库依赖一致性"
command: |
node scripts/check-cross-repo-deps.js
sync-versions:
description: "同步所有仓库的依赖版本"
command: |
node scripts/sync-all-versions.js
status-report:
description: "生成跨仓库状态报告"
command: |
node scripts/cross-repo-issue-tracker.js "$MILESTONE"
8.2 自动化跨仓库 PR 创建
const { execSync } = require('child_process');
async function createCrossRepoPR({
repos,
branch,
title,
body,
base = 'main',
}) {
const results = [];
for (const repo of repos) {
console.log(`在 ${repo} 中创建 PR...`);
try {
const prUrl = execSync(
`gh pr create --repo myorg/${repo} ` +
`--title "${title}" ` +
`--body "${body}" ` +
`--base ${base} ` +
`--head ${branch} ` +
`--label cross-repo`
).toString().trim();
results.push({ repo, url: prUrl, status: 'success' });
console.log(` PR 创建成功: ${prUrl}`);
} catch (err) {
results.push({ repo, error: err.message, status: 'failed' });
console.error(` 创建失败: ${err.message}`);
}
}
console.log('\n=== 跨仓库 PR 创建报告 ===');
results.forEach(r => {
console.log(
` ${r.repo}: ${r.status === 'success' ? '✓' : '✗'} ${r.url || r.error}`
);
});
return results;
}
createCrossRepoPR({
repos: ['service-a', 'service-b', 'web-app', 'admin-panel'],
branch: 'chore/update-core-to-v2',
title: 'chore: update @myorg/core to v2.0.0',
body: `## 变更说明
更新 @myorg/core 到 v2.0.0。
### 主要变更
- 改进了 API 响应性能
- 修复了内存泄漏问题
- 更新了 TypeScript 类型定义
### 兼容性
- 需要 Node.js >= 18
- API 接口完全向后兼容
### 测试
- [x] 单元测试通过
- [x] 集成测试通过
🤖 由 Claude Code 自动创建。`
8.3 跨仓库重构辅助
当需要在多个仓库中进行同步重构时,Claude Code 可以分析所有相关仓库的代码,生成一致的变更方案:
请帮我完成跨仓库重构:
1. **主仓库 (myorg/core)**:
- 在 `src/user.ts` 中将 `getUser` 重命名为 `findUser`
- 保留 `getUser` 作为别名并标记为 `@deprecated`
- 更新所有内部引用
2. **下游仓库 (service-a, service-b, web-app)**:
- 在 `package.json` 中更新 `@myorg/core` 版本
- 将所有 `import { getUser }` 改为 `import { findUser }`
- 更新所有使用 `getUser()` 的调用
3. **验证**:
- 确保类型定义同步更新(`types.ts`)
- 确保测试文件同步修改
- 生成变更日志条目
请为每个仓库生成对应的 PR。