From fc4d5fc2cdca8b00e84665c215e4d50dcbabdb91 Mon Sep 17 00:00:00 2001 From: zhengsl <13910913995@163.com> Date: Sun, 9 Nov 2025 21:48:30 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=BA=86=E4=BB=8Emain-framew?= =?UTF-8?q?ork=E5=88=86=E6=94=AF=E5=90=8C=E6=AD=A5=E8=84=9A=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/merge-main-framework.ps1 | 99 ++++++++++++++++++++++++++++++++ 业务分支Git处理方案.md | 91 +++++++++++++++++++++++++++++ 2 files changed, 190 insertions(+) create mode 100644 scripts/merge-main-framework.ps1 create mode 100644 业务分支Git处理方案.md diff --git a/scripts/merge-main-framework.ps1 b/scripts/merge-main-framework.ps1 new file mode 100644 index 0000000..ea7a2c5 --- /dev/null +++ b/scripts/merge-main-framework.ps1 @@ -0,0 +1,99 @@ +param( + [string]$RepoPath = (Split-Path $PSScriptRoot -Parent), + [bool]$AutoStash = $true, + [bool]$Push = $true, + [ValidateSet('abort','leave')][string]$OnConflict = 'leave' +) + +function ExecGit { + param([string[]]$ArgList, [bool]$IgnoreError = $false) + Write-Host ("git " + ($ArgList -join ' ')) -ForegroundColor Cyan + & git @ArgList + $code = $LASTEXITCODE + if (!$IgnoreError -and $code -ne 0) { + throw ("Git command failed ({0}): git {1}" -f $code, ($ArgList -join ' ')) + } + return $code +} + +try { + if (!(Test-Path $RepoPath)) { throw ("RepoPath not found: {0}" -f $RepoPath) } + Set-Location $RepoPath + + # Ensure git is available + ExecGit @('--version') $true | Out-Null + + $currentBranch = (& git rev-parse --abbrev-ref HEAD).Trim() + if ([string]::IsNullOrWhiteSpace($currentBranch)) { throw 'Cannot resolve current branch' } + Write-Host ("Current branch: {0}" -f $currentBranch) -ForegroundColor Green + + # Check worktree state + $statusPorcelain = (& git status --porcelain) + $hasChanges = -not [string]::IsNullOrWhiteSpace(($statusPorcelain -join '')) + $stashMade = $false + if ($hasChanges -and $AutoStash) { + Write-Host 'Worktree not clean, auto-stash' -ForegroundColor Yellow + ExecGit @('stash','push','-u','-m','auto-stash before merge-main-framework') + $stashMade = $true + } elseif ($hasChanges -and -not $AutoStash) { + throw 'Worktree has uncommitted changes; commit or enable -AutoStash' + } + + # Fetch remotes + ExecGit @('fetch','--all','--prune') + + # Ensure remote branch exists + $remoteRef = (& git ls-remote --heads origin main-framework) + if ([string]::IsNullOrWhiteSpace(($remoteRef -join ''))) { + throw 'Remote origin/main-framework not found. Check remote and branch name.' + } + + Write-Host ("Merging origin/main-framework -> {0}" -f $currentBranch) -ForegroundColor Green + $mergeCode = ExecGit @('merge','--no-ff','origin/main-framework') $true + + # Detect conflicts + $unmerged = (& git ls-files -u) + $hasConflicts = -not [string]::IsNullOrWhiteSpace(($unmerged -join '')) + if ($hasConflicts) { + Write-Host ('Conflicts detected. Strategy: {0}' -f $OnConflict) -ForegroundColor Yellow + if ($OnConflict -eq 'abort') { + ExecGit @('merge','--abort') + if ($stashMade) { + Write-Host 'Restoring stash (stash pop)' -ForegroundColor Yellow + ExecGit @('stash','pop') $true | Out-Null + } + throw 'Merge aborted. Please resolve conflicts manually and retry.' + } else { + Write-Host 'Leaving conflict state for manual resolution:' -ForegroundColor Yellow + Write-Host '- Edit conflicted files and run: git add ' + Write-Host '- Then conclude: git commit' + if ($stashMade) { Write-Host 'Note: run stash pop after resolving' -ForegroundColor Yellow } + exit 2 + } + } + + if ($mergeCode -eq 0) { + Write-Host 'Merge completed.' -ForegroundColor Green + } else { + $st = (& git status) + Write-Host $st + } + + # Pop stash if any + if ($stashMade) { + Write-Host 'Restoring stash (stash pop)' -ForegroundColor Yellow + ExecGit @('stash','pop') $true | Out-Null + } + + # Push if requested + if ($Push) { + Write-Host 'Pushing to remote...' -ForegroundColor Green + ExecGit @('push') + Write-Host 'Push completed.' -ForegroundColor Green + } + + Write-Host ("Done: origin/main-framework merged into {0}" -f $currentBranch) -ForegroundColor Green +} catch { + Write-Error $_ + exit 1 +} \ No newline at end of file diff --git a/业务分支Git处理方案.md b/业务分支Git处理方案.md new file mode 100644 index 0000000..f399b5a --- /dev/null +++ b/业务分支Git处理方案.md @@ -0,0 +1,91 @@ +# 业务分支 Git 处理方案 + +本文档定义在本仓库进行业务开发时的分支模型、日常协作流程、合并策略、冲突处理与发布规范,并给出从 `main-framework` 分支合并到当前分支的标准步骤与命令示例。 + +## 分支模型 +- `main-framework`:框架主线分支,承载通用框架能力与底层升级。 +- `develop`:集成分支(如有),用于聚合多业务分支进行联调。 +- `feature/*`:业务开发分支,以功能或需求编号命名,例如 `feature/order-approval`。 +- `hotfix/*`:线上紧急修复分支,例如 `hotfix/login-captcha-null`。 + +命名建议: +- 使用全小写、连字符分隔;避免中文和空格;包含简短语义或任务号。 + +## 工作流程(日常循环) +1. 从远端更新框架主线:`git fetch origin && git checkout main-framework && git pull`。 +2. 基于业务分支开展开发:`git checkout feature/xxx`。 +3. 频繁从 `main-framework` 变更合并(或重置基线),保持同步: + - 合并:`git checkout feature/xxx && git merge main-framework`。 + - 或重置基线(更干净的线性历史,需团队共识):`git rebase main-framework`。 +4. 提交与推送:按提交规范进行小步提交,`git push -u origin feature/xxx`。 +5. 发起合入评审:对 `feature/xxx` → 目标分支(`develop` 或 `main-framework`)创建 PR,并通过 CI。 + +## 合并策略 +- 默认使用 `merge --no-ff` 保留合并信息,便于回溯父子关系。 +- 团队同意时,可在业务分支内使用 `rebase` 以获得线性历史;但对共享分支避免对已推送历史进行 rebase。 + +## 提交规范 +- 提交信息格式:`(scope): ` + - `type`:feat / fix / refactor / docs / test / chore / perf / build / ci + - `scope`:可选,模块或子系统,如 `auth`、`quartz` + - `subject`:一句话描述改动,使用祈使句,如 `add captcha ttl config` +- 示例:`fix(quartz): handle null cron when loading jobs` +- 单次提交尽量关注一个变更点;避免将大量无关改动揉在一起。 + +## 冲突处理 +1. 运行合并命令后,如提示冲突: + - 逐文件解决:打开冲突标记 `<<<<<<<`, `=======`, `>>>>>>>`,保留正确逻辑。 + - 标记已解决:`git add `。 +2. 完成后继续: + - 合并:`git commit`(若自动生成合并提交信息可直接保存)。 + - 变基:`git rebase --continue`。 +3. 如需放弃变基过程:`git rebase --abort`;如需放弃合并:`git merge --abort`。 + +## 质量保障 +- 合并后本地构建:`mvn -q -DskipTests spring-boot:run` 或 `mvn -q clean package`。 +- 若包含前端:在 `framework/frontend` 下执行 `pnpm install && pnpm build`。 +- 通过单元测试与基本功能自检后再推送远端。 + +## 常用命令速查 +- 更新远端引用:`git fetch --all --prune` +- 查看当前分支:`git rev-parse --abbrev-ref HEAD` +- 查看变更:`git status -s` +- 暂存现场:`git stash push -u -m "auto-stash before merge"`,恢复:`git stash pop` +- 创建并推送分支:`git checkout -b feature/xxx && git push -u origin feature/xxx` + +## 从 main-framework 合并到当前分支(标准步骤) +在仓库根目录执行: + +1. 确认当前分支: + ```sh + git rev-parse --abbrev-ref HEAD + ``` +2. 确保工作区干净(如有未提交改动,可先提交或使用 stash): + ```sh + git status --porcelain + ``` +3. 更新远端: + ```sh + git fetch --all --prune + ``` +4. 若本地没有 `main-framework`,拉取远端追踪分支: + ```sh + git branch --track main-framework origin/main-framework 2>/dev/null || true + ``` +5. 在当前分支执行合并: + ```sh + git merge --no-ff main-framework + ``` +6. 解决冲突并提交(如有),然后本地验证构建与运行。 +7. 推送当前分支: + ```sh + git push + ``` + +## 常见问题 +- 找不到 `main-framework`:确认远端存在 `origin/main-framework`;如远端名非 `origin`,替换为实际远端名。 +- 工作区脏导致合并失败:先提交或使用 `git stash` 暂存,再合并,结束后 `stash pop` 并解决可能冲突。 +- 合并后启动失败:优先检查 `pom.xml`、`application-*.yml` 的配置合入及数据库变更迁移是否完整。 + +--- +如需自动化执行“从 main-framework 合并到当前分支”,请确保工作区干净并已配置远端,然后按上文标准步骤执行即可。 \ No newline at end of file