@zjex/git-workflow 0.3.0 → 0.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,199 @@
1
+ # 🎉 Git Wrapped - 年度编程回顾
2
+
3
+ > 将你的Git活动转化为精美的年度报告,让编程成就可视化
4
+
5
+ ## 📋 功能概述
6
+
7
+ Git Wrapped 是一个受 Spotify Wrapped 启发的功能,它分析你的Git提交历史,生成一份精美的年度编程报告。这不仅是对过去一年编程工作的总结,更是对个人成长的庆祝。
8
+
9
+ ## 🎯 核心功能
10
+
11
+ ### 基础命令
12
+ ```bash
13
+ gw wrapped # 生成当前年份报告
14
+ gw wrapped 2024 # 生成指定年份报告
15
+ gw wrapped --share # 生成可分享的图片版本
16
+ gw wrapped --format png # 指定输出格式 (png/svg/pdf)
17
+ gw wrapped --theme dark # 指定主题风格
18
+ ```
19
+
20
+ ### 高级选项
21
+ ```bash
22
+ gw wrapped --repo ./my-project # 分析特定仓库
23
+ gw wrapped --author "张三" # 分析特定作者
24
+ gw wrapped --range 2024-01-01..2024-12-31 # 自定义时间范围
25
+ gw wrapped --compare 2023 # 与去年对比
26
+ gw wrapped --team # 生成团队报告
27
+ ```
28
+
29
+ ## 📊 报告内容
30
+
31
+ ### 1. 📈 基础统计
32
+ - **总提交数**: 今年的总提交次数
33
+ - **活跃天数**: 有提交活动的天数
34
+ - **最长连击**: 连续提交的最长天数
35
+ - **代码行数**: 新增/删除的代码行数统计
36
+ - **文件变更**: 修改的文件总数
37
+
38
+ ### 2. 🏆 年度亮点
39
+ - **最忙碌的月份**: 提交最多的月份
40
+ - **最活跃时间**: 最常提交的时间段
41
+ - **最大单日提交**: 单日最多提交次数
42
+ - **里程碑时刻**: 重要的提交节点
43
+ - **项目贡献**: 贡献最多的项目
44
+
45
+ ### 3. 💻 技术分析
46
+ - **编程语言分布**: 各语言使用占比
47
+ - **文件类型统计**: 最常修改的文件类型
48
+ - **提交类型分析**: feat/fix/docs等类型分布
49
+ - **项目活跃度**: 各项目的贡献分布
50
+
51
+ ### 4. ⏰ 时间模式
52
+ - **编程习惯**: 早鸟 vs 夜猫子分析
53
+ - **工作日 vs 周末**: 工作时间分布
54
+ - **月度趋势**: 全年活跃度变化曲线
55
+ - **季节性模式**: 不同季节的编程活跃度
56
+
57
+ ### 5. 🎨 个性化洞察
58
+ - **编程风格**: 基于提交信息的风格分析
59
+ - **专注度**: 单次提交的平均文件数
60
+ - **完美主义指数**: 小提交 vs 大提交的比例
61
+ - **探索精神**: 新项目/新语言的尝试次数
62
+
63
+ ## 🎨 视觉设计
64
+
65
+ ### 终端版本
66
+ ```
67
+ ╭─────────────────────────────────────────────────────────────╮
68
+ │ 🎉 2024 Git Wrapped 🎉 │
69
+ ├─────────────────────────────────────────────────────────────┤
70
+ │ │
71
+ │ 📊 你的编程年度数据 │
72
+ │ ├─ 总提交数: 1,247 次 (+23% vs 2023) │
73
+ │ ├─ 活跃天数: 287 天 (78.6% 的日子) │
74
+ │ ├─ 最长连击: 45 天 🔥 │
75
+ │ └─ 代码贡献: +15,432 / -8,901 行 │
76
+ │ │
77
+ │ 🏆 年度亮点 │
78
+ │ ├─ 最忙月份: 三月 (156 次提交) │
79
+ │ ├─ 夜猫子指数: 68% (你更喜欢夜晚编程) │
80
+ │ ├─ 最爱语言: TypeScript (42.3%) │
81
+ │ └─ 主力项目: git-workflow (312 次提交) │
82
+ │ │
83
+ │ 🎯 成就解锁 │
84
+ │ ├─ 🔥 连击大师 (连续30天提交) │
85
+ │ ├─ 🌙 夜猫子 (凌晨提交超过100次) │
86
+ │ ├─ 🚀 效率之王 (单日最多23次提交) │
87
+ │ └─ 📝 文档达人 (docs类型提交占15%) │
88
+ │ │
89
+ ╰─────────────────────────────────────────────────────────────╯
90
+ ```
91
+
92
+ ### 分享版本 (图片)
93
+ - **卡片式设计**: 类似Instagram Story的竖版布局
94
+ - **渐变背景**: 根据主要编程语言生成配色
95
+ - **图表可视化**: 饼图、柱状图、热力图等
96
+ - **个人头像**: 集成GitHub头像
97
+ - **二维码**: 链接到个人GitHub或项目
98
+
99
+ ## 🛠️ 技术实现
100
+
101
+ ### 数据收集
102
+ ```typescript
103
+ interface GitWrappedData {
104
+ year: number;
105
+ totalCommits: number;
106
+ activeDays: number;
107
+ longestStreak: number;
108
+ linesAdded: number;
109
+ linesDeleted: number;
110
+ languages: LanguageStats[];
111
+ repositories: RepoStats[];
112
+ timePatterns: TimePattern;
113
+ commitTypes: CommitTypeStats;
114
+ achievements: Achievement[];
115
+ }
116
+ ```
117
+
118
+ ### 分析算法
119
+ 1. **Git日志解析**: 使用`git log`命令获取提交历史
120
+ 2. **语言检测**: 分析文件扩展名和Git属性
121
+ 3. **时间模式**: 统计提交时间分布
122
+ 4. **趋势分析**: 计算月度、季度变化
123
+ 5. **成就系统**: 基于规则检测特殊成就
124
+
125
+ ### 图片生成
126
+ - **Canvas API**: 使用Node.js的canvas库
127
+ - **SVG生成**: 矢量图形支持
128
+ - **模板系统**: 可配置的设计模板
129
+ - **字体支持**: 中英文字体兼容
130
+
131
+ ## 🎨 主题风格
132
+
133
+ ### 预设主题
134
+ 1. **GitHub风格**: 绿色系,类似GitHub贡献图
135
+ 2. **暗黑模式**: 深色背景,霓虹色彩
136
+ 3. **彩虹主题**: 渐变色彩,活泼风格
137
+ 4. **极简风格**: 黑白灰,简洁设计
138
+ 5. **节日主题**: 根据生成时间的节日风格
139
+
140
+ ### 自定义选项
141
+ ```bash
142
+ gw wrapped --theme custom \
143
+ --bg-color "#1a1a1a" \
144
+ --accent-color "#00ff88" \
145
+ --font-family "JetBrains Mono"
146
+ ```
147
+
148
+ ## 📱 分享功能
149
+
150
+ ### 社交媒体优化
151
+ - **Twitter**: 1200x675 横版卡片
152
+ - **Instagram**: 1080x1920 竖版故事
153
+ - **LinkedIn**: 1200x627 专业风格
154
+ - **微信朋友圈**: 正方形 1080x1080
155
+
156
+ ### 导出格式
157
+ - **PNG**: 高质量位图,适合分享
158
+ - **SVG**: 矢量图形,可编辑
159
+ - **PDF**: 打印友好格式
160
+ - **HTML**: 交互式网页版本
161
+
162
+ ## 🔮 未来扩展
163
+
164
+ ### v1.0 增强功能
165
+ - [ ] **AI洞察**: 使用AI分析编程模式并给出建议
166
+ - [ ] **团队对比**: 与团队成员的数据对比
167
+ - [ ] **目标设定**: 基于今年数据设定明年目标
168
+ - [ ] **历史对比**: 多年数据的趋势分析
169
+
170
+ ### v2.0 高级功能
171
+ - [ ] **Web仪表板**: 在线查看和分享
172
+ - [ ] **实时更新**: 年度数据的实时追踪
173
+ - [ ] **集成API**: 与其他平台的数据整合
174
+ - [ ] **团队版本**: 企业级团队分析
175
+
176
+ ## 💡 使用场景
177
+
178
+ ### 个人用途
179
+ - **年终总结**: 个人技术成长回顾
180
+ - **简历亮点**: 展示编程活跃度
181
+ - **社交分享**: 在社交媒体展示成就
182
+ - **自我激励**: 通过数据可视化保持动力
183
+
184
+ ### 团队用途
185
+ - **团队回顾**: 团队年度技术总结
186
+ - **绩效展示**: 可视化团队贡献
187
+ - **文化建设**: 增强团队凝聚力
188
+ - **招聘宣传**: 展示团队技术实力
189
+
190
+ ## 🎯 成功指标
191
+
192
+ - **用户参与度**: 生成报告的用户数量
193
+ - **分享率**: 用户分享图片的比例
194
+ - **回访率**: 用户重复使用的频率
195
+ - **社交影响**: 在社交媒体的传播效果
196
+
197
+ ---
198
+
199
+ *这个功能将让Git Workflow不仅仅是一个工具,更是一个让开发者为自己的编程旅程感到骄傲的平台。*
package/docs/index.md CHANGED
@@ -23,6 +23,9 @@ features:
23
23
  - icon: 🎯
24
24
  title: 规范命名
25
25
  details: 自动生成带日期的规范分支名,如 feature/20260109-PROJ-123-add-login
26
+ - icon: 📋
27
+ title: 优雅日志
28
+ details: GitHub 风格的提交历史查看,时间线分组,交互式浏览,支持搜索和过滤
26
29
  - icon: 🏷️
27
30
  title: 智能版本
28
31
  details: 自动识别当前版本,交互式选择下一版本,支持 semver + 预发布版本
@@ -126,6 +129,32 @@ gw f
126
129
  # ✔ 分支创建成功: feature/20260109-PROJ-123-add-user-login
127
130
  ```
128
131
 
132
+ ### 📋 优雅的提交历史
133
+
134
+ GitHub 风格的提交历史查看,让代码历史一目了然:
135
+
136
+ ```bash
137
+ gw log
138
+ # ┌─────────────────────────────────────────────────────────────────────────────┐
139
+ # │ Git 提交历史 │
140
+ # ├─────────────────────────────────────────────────────────────────────────────┤
141
+ # │ │
142
+ # │ 📅 今天 │
143
+ # │ │
144
+ # │ ✅ test: 完善commit message格式化测试用例 │
145
+ # │ 🔗 #8d74ffa • 2小时前 • zjex │
146
+ # │ │
147
+ # │ 🔧 chore: 删除重复的测试文件 │
148
+ # │ 🔗 #746aa87 • 3小时前 • zjex │
149
+ # │ │
150
+ # │ 📅 昨天 │
151
+ # │ │
152
+ # │ ✨ feat(log): 实现GitHub风格的提交历史查看 │
153
+ # │ 🔗 #a1b2c3d • 1天前 • zjex │
154
+ # │ 🔖 v0.3.0 │
155
+ # └─────────────────────────────────────────────────────────────────────────────┘
156
+ ```
157
+
129
158
  ### 🏷️ 智能版本管理
130
159
 
131
160
  自动检测现有 tag 前缀,智能递增版本号:
@@ -164,6 +193,7 @@ gw s
164
193
  | 分支命名规范 | ✅ 自动生成 | ❌ 需手动 | ❌ 需手动 |
165
194
  | 版本号管理 | ✅ 智能递增 | ❌ 需手动 | ❌ 需手动 |
166
195
  | AI Commit | ✅ 支持 | ❌ 不支持 | ❌ 不支持 |
196
+ | 提交历史查看 | ✅ GitHub风格 | ❌ 不支持 | ⚠️ 原生命令 |
167
197
  | Stash 可视化管理 | ✅ 支持 | ❌ 不支持 | ❌ 不支持 |
168
198
  | 交互式操作 | ✅ 支持 | ❌ 不支持 | ❌ 不支持 |
169
199
  | 配置灵活性 | ✅ 项目级配置 | ⚠️ 有限 | - |
@@ -187,7 +217,8 @@ Git Workflow 提供优雅的命令行界面,支持键盘快捷操作:
187
217
  [2] 🐛 创建 hotfix 分支 gw h
188
218
  [3] 🗑️ 删除分支 gw d
189
219
  [4] 📝 提交代码 gw c
190
- [5] 🏷️ 创建 tag gw t
220
+ [5] 📋 查看提交历史 gw log
221
+ [6] 🏷️ 创建 tag gw t
191
222
  ...
192
223
  ```
193
224
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zjex/git-workflow",
3
- "version": "0.3.0",
3
+ "version": "0.3.3",
4
4
  "description": "🚀 极简的 Git 工作流 CLI 工具,让分支管理和版本发布变得轻松愉快",
5
5
  "type": "module",
6
6
  "bin": {
@@ -54,6 +54,7 @@
54
54
  "@inquirer/prompts": "^7.0.0",
55
55
  "boxen": "^8.0.1",
56
56
  "cac": "^6.7.14",
57
+ "node-pager": "^0.3.6",
57
58
  "ora": "^9.0.0",
58
59
  "semver": "^7.7.3"
59
60
  },
@@ -0,0 +1,258 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Commit Message Emoji 格式化工具
5
+ *
6
+ * 功能:
7
+ * 1. 检测 commit message 是否包含 emoji
8
+ * 2. 如果没有 emoji,根据 type 自动添加
9
+ * 3. 如果有 emoji 但与 type 不匹配,自动替换
10
+ * 4. 支持 Conventional Commits 规范
11
+ */
12
+
13
+ import { readFileSync, writeFileSync, existsSync } from 'fs';
14
+ import { homedir } from 'os';
15
+ import path from 'path';
16
+
17
+ // Emoji 映射表
18
+ const EMOJI_MAP = {
19
+ feat: '✨',
20
+ fix: '🐛',
21
+ docs: '📝',
22
+ style: '💄',
23
+ refactor: '♻️',
24
+ perf: '⚡️',
25
+ test: '✅',
26
+ build: '📦',
27
+ ci: '👷',
28
+ chore: '🔧',
29
+ revert: '⏪',
30
+ merge: '🔀',
31
+ release: '🔖',
32
+ hotfix: '🚑',
33
+ security: '🔒',
34
+ breaking: '💥'
35
+ };
36
+
37
+ /**
38
+ * 解析 commit message
39
+ * @param {string} message - commit message
40
+ * @returns {object} 解析结果
41
+ */
42
+ function parseCommitMessage(message) {
43
+ // 移除开头和结尾的空白字符
44
+ const cleanMessage = message.trim();
45
+
46
+ // 检测是否以已知的emoji开头
47
+ const allEmojis = Object.values(EMOJI_MAP);
48
+ let hasEmoji = false;
49
+ let currentEmoji = null;
50
+ let messageWithoutEmoji = cleanMessage;
51
+
52
+ for (const emoji of allEmojis) {
53
+ if (cleanMessage.startsWith(emoji)) {
54
+ hasEmoji = true;
55
+ currentEmoji = emoji;
56
+ messageWithoutEmoji = cleanMessage.substring(emoji.length).trim();
57
+ break;
58
+ }
59
+ }
60
+
61
+ // 如果没有找到已知emoji,检查是否以其他emoji开头
62
+ if (!hasEmoji) {
63
+ const emojiMatch = cleanMessage.match(/^(\p{Emoji})\s*/u);
64
+ if (emojiMatch) {
65
+ hasEmoji = true;
66
+ currentEmoji = emojiMatch[1];
67
+ messageWithoutEmoji = cleanMessage.replace(/^(\p{Emoji})\s*/u, '').trim();
68
+ }
69
+ }
70
+
71
+ // 解析 Conventional Commits 格式: type(scope): subject
72
+ const conventionalMatch = messageWithoutEmoji.match(/^(\w+)(\([^)]+\))?(!)?:\s*(.+)/);
73
+
74
+ if (!conventionalMatch) {
75
+ return {
76
+ isConventional: false,
77
+ hasEmoji,
78
+ currentEmoji,
79
+ originalMessage: message,
80
+ cleanMessage: messageWithoutEmoji
81
+ };
82
+ }
83
+
84
+ const [, type, scope, breaking, subject] = conventionalMatch;
85
+
86
+ return {
87
+ isConventional: true,
88
+ hasEmoji,
89
+ currentEmoji,
90
+ type: type.toLowerCase(),
91
+ scope: scope || '',
92
+ breaking: breaking === '!',
93
+ subject,
94
+ originalMessage: message,
95
+ cleanMessage: messageWithoutEmoji,
96
+ messageWithoutEmoji
97
+ };
98
+ }
99
+
100
+ /**
101
+ * 获取正确的 emoji
102
+ * @param {string} type - commit type
103
+ * @returns {string} emoji
104
+ */
105
+ function getCorrectEmoji(type) {
106
+ return EMOJI_MAP[type] || EMOJI_MAP.chore;
107
+ }
108
+
109
+ /**
110
+ * 检查 emoji 是否匹配 type
111
+ * @param {string} emoji - 当前 emoji
112
+ * @param {string} type - commit type
113
+ * @returns {boolean} 是否匹配
114
+ */
115
+ function isEmojiCorrect(emoji, type) {
116
+ return emoji === getCorrectEmoji(type);
117
+ }
118
+
119
+ /**
120
+ * 格式化 commit message
121
+ * @param {string} message - 原始 commit message
122
+ * @returns {object} 格式化结果
123
+ */
124
+ function formatCommitMessage(message) {
125
+ const parsed = parseCommitMessage(message);
126
+
127
+ // 如果不是 Conventional Commits 格式,不处理
128
+ if (!parsed.isConventional) {
129
+ return {
130
+ needsUpdate: false,
131
+ originalMessage: message,
132
+ formattedMessage: message,
133
+ reason: 'Not a conventional commit format'
134
+ };
135
+ }
136
+
137
+ const correctEmoji = getCorrectEmoji(parsed.type);
138
+ let needsUpdate = false;
139
+ let reason = '';
140
+
141
+ // 检查是否需要更新
142
+ if (!parsed.hasEmoji) {
143
+ needsUpdate = true;
144
+ reason = `Added missing emoji for type '${parsed.type}'`;
145
+ } else if (!isEmojiCorrect(parsed.currentEmoji, parsed.type)) {
146
+ needsUpdate = true;
147
+ reason = `Replaced incorrect emoji '${parsed.currentEmoji}' with '${correctEmoji}' for type '${parsed.type}'`;
148
+ }
149
+
150
+ // 构建格式化后的消息
151
+ const formattedMessage = needsUpdate
152
+ ? `${correctEmoji} ${parsed.messageWithoutEmoji}`
153
+ : message;
154
+
155
+ return {
156
+ needsUpdate,
157
+ originalMessage: message,
158
+ formattedMessage,
159
+ reason,
160
+ type: parsed.type,
161
+ currentEmoji: parsed.currentEmoji,
162
+ correctEmoji
163
+ };
164
+ }
165
+
166
+ /**
167
+ * 检查用户配置是否启用 emoji
168
+ * @returns {boolean} 是否启用 emoji
169
+ */
170
+ function isEmojiEnabled() {
171
+ try {
172
+ // 尝试读取配置文件
173
+ const configPaths = ['.gwrc.json', '.gwrc', 'gw.config.json'];
174
+
175
+ for (const configPath of configPaths) {
176
+ try {
177
+ if (existsSync(configPath)) {
178
+ const config = JSON.parse(readFileSync(configPath, 'utf-8'));
179
+ if (config.useEmoji !== undefined) {
180
+ return config.useEmoji;
181
+ }
182
+ }
183
+ } catch {
184
+ // 继续尝试下一个配置文件
185
+ }
186
+ }
187
+
188
+ // 尝试读取全局配置
189
+ try {
190
+ const globalConfigPath = path.join(homedir(), '.gwrc.json');
191
+ if (existsSync(globalConfigPath)) {
192
+ const globalConfig = JSON.parse(readFileSync(globalConfigPath, 'utf-8'));
193
+ if (globalConfig.useEmoji !== undefined) {
194
+ return globalConfig.useEmoji;
195
+ }
196
+ }
197
+ } catch {
198
+ // 忽略全局配置错误
199
+ }
200
+
201
+ // 默认启用 emoji
202
+ return true;
203
+ } catch {
204
+ return true;
205
+ }
206
+ }
207
+
208
+ /**
209
+ * 主函数
210
+ */
211
+ function main() {
212
+ // 获取 commit message 文件路径
213
+ const commitMsgFile = process.argv[2];
214
+
215
+ if (!commitMsgFile) {
216
+ console.error('Error: No commit message file provided');
217
+ process.exit(1);
218
+ }
219
+
220
+ try {
221
+ // 检查是否启用 emoji
222
+ if (!isEmojiEnabled()) {
223
+ // 如果禁用了 emoji,直接退出
224
+ process.exit(0);
225
+ }
226
+
227
+ // 读取 commit message
228
+ const originalMessage = readFileSync(commitMsgFile, 'utf-8').trim();
229
+
230
+ // 跳过空消息或合并消息
231
+ if (!originalMessage || originalMessage.startsWith('Merge ')) {
232
+ process.exit(0);
233
+ }
234
+
235
+ // 格式化消息
236
+ const result = formatCommitMessage(originalMessage);
237
+
238
+ // 如果需要更新
239
+ if (result.needsUpdate) {
240
+ // 写入格式化后的消息
241
+ writeFileSync(commitMsgFile, result.formattedMessage + '\n');
242
+
243
+ // 输出提示信息
244
+ console.log(`\n🎨 Commit message formatted:`);
245
+ console.log(` ${result.reason}`);
246
+ console.log(` Before: ${result.originalMessage}`);
247
+ console.log(` After: ${result.formattedMessage}\n`);
248
+ }
249
+
250
+ process.exit(0);
251
+ } catch (error) {
252
+ console.error('Error formatting commit message:', error.message);
253
+ process.exit(0); // 不阻止提交,只是跳过格式化
254
+ }
255
+ }
256
+
257
+ // 运行主函数
258
+ main();
@@ -138,7 +138,67 @@ print_success "已登录 npm (用户: ${NPM_USER})"
138
138
  # 拉取最新代码
139
139
  print_step "拉取最新代码..."
140
140
  if [[ "$DRY_RUN" == false ]]; then
141
- git pull origin "$CURRENT_BRANCH"
141
+ # 检查是否有远程更新
142
+ git fetch origin "$CURRENT_BRANCH"
143
+
144
+ # 检查本地和远程是否有分歧
145
+ LOCAL_COMMIT=$(git rev-parse HEAD)
146
+ REMOTE_COMMIT=$(git rev-parse "origin/$CURRENT_BRANCH")
147
+
148
+ if [[ "$LOCAL_COMMIT" != "$REMOTE_COMMIT" ]]; then
149
+ print_warning "检测到本地和远程分支有分歧"
150
+
151
+ # 检查是否可以快进
152
+ if git merge-base --is-ancestor HEAD "origin/$CURRENT_BRANCH"; then
153
+ print_info "远程有新提交,正在快进合并..."
154
+ git pull origin "$CURRENT_BRANCH" --ff-only
155
+ elif git merge-base --is-ancestor "origin/$CURRENT_BRANCH" HEAD; then
156
+ print_info "本地有新提交,需要推送到远程"
157
+ print_warning "建议先推送本地提交再发布"
158
+ read -p "是否继续发布? (y/N) " -n 1 -r
159
+ echo
160
+ if [[ ! $REPLY =~ ^[Yy]$ ]]; then
161
+ print_info "已取消,请先推送本地提交: git push origin $CURRENT_BRANCH"
162
+ exit 0
163
+ fi
164
+ else
165
+ print_warning "本地和远程分支有冲突,需要解决分歧"
166
+ echo ""
167
+ echo "建议的解决方案:"
168
+ echo "1. 使用 rebase: git pull origin $CURRENT_BRANCH --rebase"
169
+ echo "2. 使用 merge: git pull origin $CURRENT_BRANCH --no-rebase"
170
+ echo ""
171
+ read -p "选择解决方案 (1=rebase, 2=merge, q=退出): " -n 1 -r
172
+ echo
173
+
174
+ case $REPLY in
175
+ 1)
176
+ print_info "使用 rebase 策略合并..."
177
+ if git pull origin "$CURRENT_BRANCH" --rebase; then
178
+ print_success "Rebase 成功"
179
+ else
180
+ print_error "Rebase 失败,请手动解决冲突后重新运行发布脚本"
181
+ exit 1
182
+ fi
183
+ ;;
184
+ 2)
185
+ print_info "使用 merge 策略合并..."
186
+ if git pull origin "$CURRENT_BRANCH" --no-rebase; then
187
+ print_success "Merge 成功"
188
+ else
189
+ print_error "Merge 失败,请手动解决冲突后重新运行发布脚本"
190
+ exit 1
191
+ fi
192
+ ;;
193
+ *)
194
+ print_info "已取消,请手动解决分支分歧后重新运行"
195
+ exit 0
196
+ ;;
197
+ esac
198
+ fi
199
+ else
200
+ print_info "本地和远程分支已同步"
201
+ fi
142
202
  fi
143
203
  print_success "代码已更新"
144
204