@zjex/git-workflow 0.4.4 → 0.4.5
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.
- package/CHANGELOG.md +11 -0
- package/README.md +1 -1
- package/dist/index.js +19 -5
- package/docs/commands/amend-date.md +75 -13
- package/package.json +1 -1
- package/src/commands/amend-date.ts +25 -5
- package/src/commands/amend.ts +0 -1
- package/tests/amend-date.test.ts +59 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [v0.4.4](https://github.com/iamzjt-front-end/git-workflow/compare/v0.4.3...v0.4.4) (2026-01-19)
|
|
4
|
+
|
|
5
|
+
### ✨ Features
|
|
6
|
+
|
|
7
|
+
- 优化分支创建和删除功能的用户体验 ([88dec43](https://github.com/iamzjt-front-end/git-workflow/commit/88dec43))
|
|
8
|
+
|
|
9
|
+
### 🔧 Chore
|
|
10
|
+
|
|
11
|
+
- 🔖 chore(release): 发布 v0.4.4 ([d673bfb](https://github.com/iamzjt-front-end/git-workflow/commit/d673bfb))
|
|
12
|
+
|
|
13
|
+
|
|
3
14
|
## [v0.4.3](https://github.com/iamzjt-front-end/git-workflow/compare/v0.4.2...v0.4.3) (2026-01-19)
|
|
4
15
|
|
|
5
16
|
### ✨ Features
|
package/README.md
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
<a href="https://github.com/iamzjt-front-end/git-workflow"><img src="https://img.shields.io/github/stars/iamzjt-front-end/git-workflow?style=flat&colorA=18181B&colorB=F59E0B" alt="github stars"></a>
|
|
13
13
|
<a href="https://github.com/iamzjt-front-end/git-workflow/blob/main/LICENSE"><img src="https://img.shields.io/npm/l/@zjex/git-workflow?style=flat&colorA=18181B&colorB=10B981" alt="license"></a>
|
|
14
14
|
<a href="https://nodejs.org"><img src="https://img.shields.io/badge/node-%3E%3D18-339933?style=flat&logo=node.js&logoColor=white&colorA=18181B" alt="node version"></a>
|
|
15
|
-
<a href="https://github.com/iamzjt-front-end/git-workflow/actions"><img src="https://img.shields.io/badge/tests-
|
|
15
|
+
<a href="https://github.com/iamzjt-front-end/git-workflow/actions"><img src="https://img.shields.io/badge/tests-435%20passed-success?style=flat&colorA=18181B" alt="tests"></a>
|
|
16
16
|
<a href="https://github.com/iamzjt-front-end/git-workflow/issues"><img src="https://img.shields.io/github/issues/iamzjt-front-end/git-workflow?style=flat&colorA=18181B&colorB=EC4899" alt="issues"></a>
|
|
17
17
|
</p>
|
|
18
18
|
|
package/dist/index.js
CHANGED
|
@@ -3223,6 +3223,20 @@ function formatGitDate(date) {
|
|
|
3223
3223
|
}
|
|
3224
3224
|
function parseDate(input8) {
|
|
3225
3225
|
const trimmed = input8.trim();
|
|
3226
|
+
const fullMatch = trimmed.match(
|
|
3227
|
+
/^(\d{4})-(\d{2})-(\d{2})\s+(\d{2}):(\d{2}):(\d{2})$/
|
|
3228
|
+
);
|
|
3229
|
+
if (fullMatch) {
|
|
3230
|
+
const [, year, month, day, hours, minutes, seconds] = fullMatch;
|
|
3231
|
+
return new Date(
|
|
3232
|
+
parseInt(year),
|
|
3233
|
+
parseInt(month) - 1,
|
|
3234
|
+
parseInt(day),
|
|
3235
|
+
parseInt(hours),
|
|
3236
|
+
parseInt(minutes),
|
|
3237
|
+
parseInt(seconds)
|
|
3238
|
+
);
|
|
3239
|
+
}
|
|
3226
3240
|
const dateMatch = trimmed.match(/^(\d{4})-(\d{2})-(\d{2})$/);
|
|
3227
3241
|
if (dateMatch) {
|
|
3228
3242
|
const [, year, month, day] = dateMatch;
|
|
@@ -3279,7 +3293,6 @@ async function amendDate(commitHash) {
|
|
|
3279
3293
|
value: c,
|
|
3280
3294
|
description: c.date
|
|
3281
3295
|
})),
|
|
3282
|
-
pageSize: 15,
|
|
3283
3296
|
theme
|
|
3284
3297
|
});
|
|
3285
3298
|
}
|
|
@@ -3289,14 +3302,16 @@ async function amendDate(commitHash) {
|
|
|
3289
3302
|
console.log(` Message: ${selectedCommit.message}`);
|
|
3290
3303
|
console.log(` Date: ${colors.cyan(selectedCommit.date)}`);
|
|
3291
3304
|
divider();
|
|
3292
|
-
console.log(colors.dim("\
|
|
3305
|
+
console.log(colors.dim("\u652F\u6301\u683C\u5F0F:"));
|
|
3306
|
+
console.log(colors.dim(" YYYY-MM-DD (\u5982: 2026-01-19\uFF0C\u9ED8\u8BA4 00:00:00)"));
|
|
3307
|
+
console.log(colors.dim(" YYYY-MM-DD HH:mm:ss (\u5982: 2026-01-19 14:30:00)"));
|
|
3293
3308
|
console.log("");
|
|
3294
3309
|
const dateInput = await input6({
|
|
3295
3310
|
message: "\u8F93\u5165\u65B0\u7684\u65E5\u671F:",
|
|
3296
3311
|
validate: (value) => {
|
|
3297
3312
|
const parsed = parseDate(value);
|
|
3298
3313
|
if (!parsed) {
|
|
3299
|
-
return "\u65E5\u671F\u683C\u5F0F\u4E0D\u6B63\u786E\uFF0C\u8BF7\u4F7F\u7528 YYYY-MM-DD \u683C\u5F0F";
|
|
3314
|
+
return "\u65E5\u671F\u683C\u5F0F\u4E0D\u6B63\u786E\uFF0C\u8BF7\u4F7F\u7528 YYYY-MM-DD \u6216 YYYY-MM-DD HH:mm:ss \u683C\u5F0F";
|
|
3300
3315
|
}
|
|
3301
3316
|
return true;
|
|
3302
3317
|
},
|
|
@@ -3409,7 +3424,6 @@ async function amend(commitHash) {
|
|
|
3409
3424
|
value: c,
|
|
3410
3425
|
description: c.message
|
|
3411
3426
|
})),
|
|
3412
|
-
pageSize: 15,
|
|
3413
3427
|
theme
|
|
3414
3428
|
});
|
|
3415
3429
|
}
|
|
@@ -3519,7 +3533,7 @@ process.on("SIGTERM", () => {
|
|
|
3519
3533
|
console.log("");
|
|
3520
3534
|
process.exit(0);
|
|
3521
3535
|
});
|
|
3522
|
-
var version = true ? "0.4.
|
|
3536
|
+
var version = true ? "0.4.5" : "0.0.0-dev";
|
|
3523
3537
|
async function mainMenu() {
|
|
3524
3538
|
console.log(
|
|
3525
3539
|
colors.green(`
|
|
@@ -66,12 +66,17 @@ gw ad HEAD~2 # 上上个 commit
|
|
|
66
66
|
### 步骤 3: 输入新日期
|
|
67
67
|
|
|
68
68
|
```
|
|
69
|
-
|
|
69
|
+
支持格式:
|
|
70
|
+
YYYY-MM-DD (如: 2026-01-19,默认 00:00:00)
|
|
71
|
+
YYYY-MM-DD HH:mm:ss (如: 2026-01-19 14:30:00)
|
|
70
72
|
|
|
71
|
-
? 输入新的日期: 2026-01-15
|
|
73
|
+
? 输入新的日期: 2026-01-15 14:30:00
|
|
72
74
|
```
|
|
73
75
|
|
|
74
|
-
|
|
76
|
+
**支持的日期格式**:
|
|
77
|
+
|
|
78
|
+
- `YYYY-MM-DD` - 只指定日期,时间默认为 `00:00:00`
|
|
79
|
+
- `YYYY-MM-DD HH:mm:ss` - 指定完整的日期和时间
|
|
75
80
|
|
|
76
81
|
### 步骤 4: 确认修改
|
|
77
82
|
|
|
@@ -79,7 +84,7 @@ gw ad HEAD~2 # 上上个 commit
|
|
|
79
84
|
修改预览:
|
|
80
85
|
Commit: a1b2c3d
|
|
81
86
|
旧时间: 2026-01-19 14:30:00 +0800
|
|
82
|
-
新时间: 2026-01-15
|
|
87
|
+
新时间: 2026-01-15 14:30:00
|
|
83
88
|
修改类型: Author + Committer (两者都修改)
|
|
84
89
|
────────────────────────────────────────
|
|
85
90
|
|
|
@@ -164,9 +169,37 @@ git push --force
|
|
|
164
169
|
|
|
165
170
|
### 📅 时间格式
|
|
166
171
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
-
|
|
172
|
+
支持两种输入格式:
|
|
173
|
+
|
|
174
|
+
1. **仅日期**: `YYYY-MM-DD`(如 `2026-01-19`)
|
|
175
|
+
- 时间默认为 `00:00:00`
|
|
176
|
+
- 适合只关心日期的场景
|
|
177
|
+
|
|
178
|
+
2. **完整时间**: `YYYY-MM-DD HH:mm:ss`(如 `2026-01-19 14:30:00`)
|
|
179
|
+
- 可以精确指定时分秒
|
|
180
|
+
- 适合需要精确时间的场景
|
|
181
|
+
|
|
182
|
+
**示例**:
|
|
183
|
+
|
|
184
|
+
```bash
|
|
185
|
+
# 只指定日期
|
|
186
|
+
输入: 2026-01-19
|
|
187
|
+
结果: 2026-01-19 00:00:00
|
|
188
|
+
|
|
189
|
+
# 指定完整时间
|
|
190
|
+
输入: 2026-01-19 14:30:00
|
|
191
|
+
结果: 2026-01-19 14:30:00
|
|
192
|
+
|
|
193
|
+
# 指定午夜
|
|
194
|
+
输入: 2026-01-19 00:00:00
|
|
195
|
+
结果: 2026-01-19 00:00:00
|
|
196
|
+
|
|
197
|
+
# 指定一天结束
|
|
198
|
+
输入: 2026-01-19 23:59:59
|
|
199
|
+
结果: 2026-01-19 23:59:59
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
**时区**: 使用系统当前时区
|
|
170
203
|
|
|
171
204
|
### 🔄 修改范围
|
|
172
205
|
|
|
@@ -187,11 +220,21 @@ $ gw ad HEAD
|
|
|
187
220
|
✔ 修改成功
|
|
188
221
|
```
|
|
189
222
|
|
|
190
|
-
### 示例 2:
|
|
223
|
+
### 示例 2: 修改为指定的完整时间
|
|
224
|
+
|
|
225
|
+
```bash
|
|
226
|
+
$ gw ad HEAD
|
|
227
|
+
输入新的日期: 2026-01-15 14:30:00
|
|
228
|
+
确认修改? y
|
|
229
|
+
|
|
230
|
+
✔ 修改成功
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
### 示例 3: 修改指定 hash 的 commit
|
|
191
234
|
|
|
192
235
|
```bash
|
|
193
236
|
$ gw ad a1b2c3d
|
|
194
|
-
输入新的日期: 2026-01-10
|
|
237
|
+
输入新的日期: 2026-01-10 09:00:00
|
|
195
238
|
确认修改? y
|
|
196
239
|
|
|
197
240
|
⚠️ 警告: 修改非最新 commit 需要使用 rebase,可能会改变 commit hash
|
|
@@ -199,7 +242,7 @@ $ gw ad a1b2c3d
|
|
|
199
242
|
✔ 修改成功
|
|
200
243
|
```
|
|
201
244
|
|
|
202
|
-
### 示例
|
|
245
|
+
### 示例 4: 交互式选择并修改
|
|
203
246
|
|
|
204
247
|
```bash
|
|
205
248
|
$ gw ad
|
|
@@ -208,7 +251,7 @@ $ gw ad
|
|
|
208
251
|
❯ a1b2c3d ✨ feat: 添加登录功能 2026-01-19 14:30:00
|
|
209
252
|
d4e5f6g 🐛 fix: 修复bug 2026-01-18 10:20:00
|
|
210
253
|
|
|
211
|
-
输入新的日期: 2026-01-15
|
|
254
|
+
输入新的日期: 2026-01-15 16:45:30
|
|
212
255
|
确认修改? y
|
|
213
256
|
|
|
214
257
|
✔ 修改成功
|
|
@@ -363,11 +406,30 @@ git am < patch.diff
|
|
|
363
406
|
|
|
364
407
|
### Q: 为什么时间是 00:00:00?
|
|
365
408
|
|
|
366
|
-
A:
|
|
409
|
+
A: 当你只输入日期(YYYY-MM-DD)时,时间会默认为 00:00:00。这是为了简化操作,大多数情况下我们只关心日期。
|
|
410
|
+
|
|
411
|
+
如果需要指定精确时间,可以使用完整格式:
|
|
412
|
+
|
|
413
|
+
```bash
|
|
414
|
+
# 只输入日期
|
|
415
|
+
输入: 2026-01-15
|
|
416
|
+
结果: 2026-01-15 00:00:00
|
|
417
|
+
|
|
418
|
+
# 输入完整时间
|
|
419
|
+
输入: 2026-01-15 14:30:00
|
|
420
|
+
结果: 2026-01-15 14:30:00
|
|
421
|
+
```
|
|
367
422
|
|
|
368
423
|
### Q: 可以修改时间部分吗?
|
|
369
424
|
|
|
370
|
-
A:
|
|
425
|
+
A: 可以!使用完整格式 `YYYY-MM-DD HH:mm:ss` 即可指定精确时间:
|
|
426
|
+
|
|
427
|
+
```bash
|
|
428
|
+
$ gw ad
|
|
429
|
+
输入新的日期: 2026-01-15 14:30:00
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
如果需要更灵活的控制,也可以手动使用 git 命令:
|
|
371
433
|
|
|
372
434
|
```bash
|
|
373
435
|
# 修改最新 commit 的时间为指定的精确时间
|
package/package.json
CHANGED
|
@@ -19,14 +19,33 @@ function formatGitDate(date: Date): string {
|
|
|
19
19
|
|
|
20
20
|
/**
|
|
21
21
|
* 解析用户输入的日期
|
|
22
|
-
* 支持格式:
|
|
22
|
+
* 支持格式:
|
|
23
|
+
* - YYYY-MM-DD (默认 00:00:00)
|
|
24
|
+
* - YYYY-MM-DD HH:mm:ss
|
|
23
25
|
* @param input 用户输入
|
|
24
26
|
* @returns Date 对象或 null
|
|
25
27
|
*/
|
|
26
28
|
function parseDate(input: string): Date | null {
|
|
27
29
|
const trimmed = input.trim();
|
|
28
|
-
const dateMatch = trimmed.match(/^(\d{4})-(\d{2})-(\d{2})$/);
|
|
29
30
|
|
|
31
|
+
// 尝试匹配完整格式: YYYY-MM-DD HH:mm:ss
|
|
32
|
+
const fullMatch = trimmed.match(
|
|
33
|
+
/^(\d{4})-(\d{2})-(\d{2})\s+(\d{2}):(\d{2}):(\d{2})$/,
|
|
34
|
+
);
|
|
35
|
+
if (fullMatch) {
|
|
36
|
+
const [, year, month, day, hours, minutes, seconds] = fullMatch;
|
|
37
|
+
return new Date(
|
|
38
|
+
parseInt(year),
|
|
39
|
+
parseInt(month) - 1,
|
|
40
|
+
parseInt(day),
|
|
41
|
+
parseInt(hours),
|
|
42
|
+
parseInt(minutes),
|
|
43
|
+
parseInt(seconds),
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// 尝试匹配简化格式: YYYY-MM-DD (默认 00:00:00)
|
|
48
|
+
const dateMatch = trimmed.match(/^(\d{4})-(\d{2})-(\d{2})$/);
|
|
30
49
|
if (dateMatch) {
|
|
31
50
|
const [, year, month, day] = dateMatch;
|
|
32
51
|
return new Date(
|
|
@@ -120,7 +139,6 @@ export async function amendDate(commitHash?: string): Promise<void> {
|
|
|
120
139
|
value: c,
|
|
121
140
|
description: c.date,
|
|
122
141
|
})),
|
|
123
|
-
pageSize: 15,
|
|
124
142
|
theme,
|
|
125
143
|
});
|
|
126
144
|
}
|
|
@@ -133,7 +151,9 @@ export async function amendDate(commitHash?: string): Promise<void> {
|
|
|
133
151
|
divider();
|
|
134
152
|
|
|
135
153
|
// ========== 步骤 2: 输入新日期 ==========
|
|
136
|
-
console.log(colors.dim("
|
|
154
|
+
console.log(colors.dim("支持格式:"));
|
|
155
|
+
console.log(colors.dim(" YYYY-MM-DD (如: 2026-01-19,默认 00:00:00)"));
|
|
156
|
+
console.log(colors.dim(" YYYY-MM-DD HH:mm:ss (如: 2026-01-19 14:30:00)"));
|
|
137
157
|
console.log("");
|
|
138
158
|
|
|
139
159
|
const dateInput = await input({
|
|
@@ -141,7 +161,7 @@ export async function amendDate(commitHash?: string): Promise<void> {
|
|
|
141
161
|
validate: (value) => {
|
|
142
162
|
const parsed = parseDate(value);
|
|
143
163
|
if (!parsed) {
|
|
144
|
-
return "日期格式不正确,请使用 YYYY-MM-DD 格式";
|
|
164
|
+
return "日期格式不正确,请使用 YYYY-MM-DD 或 YYYY-MM-DD HH:mm:ss 格式";
|
|
145
165
|
}
|
|
146
166
|
return true;
|
|
147
167
|
},
|
package/src/commands/amend.ts
CHANGED
package/tests/amend-date.test.ts
CHANGED
|
@@ -96,8 +96,25 @@ describe("amend-date command", () => {
|
|
|
96
96
|
describe("日期解析", () => {
|
|
97
97
|
const parseDate = (input: string): Date | null => {
|
|
98
98
|
const trimmed = input.trim();
|
|
99
|
-
const dateMatch = trimmed.match(/^(\d{4})-(\d{2})-(\d{2})$/);
|
|
100
99
|
|
|
100
|
+
// 尝试匹配完整格式: YYYY-MM-DD HH:mm:ss
|
|
101
|
+
const fullMatch = trimmed.match(
|
|
102
|
+
/^(\d{4})-(\d{2})-(\d{2})\s+(\d{2}):(\d{2}):(\d{2})$/,
|
|
103
|
+
);
|
|
104
|
+
if (fullMatch) {
|
|
105
|
+
const [, year, month, day, hours, minutes, seconds] = fullMatch;
|
|
106
|
+
return new Date(
|
|
107
|
+
parseInt(year),
|
|
108
|
+
parseInt(month) - 1,
|
|
109
|
+
parseInt(day),
|
|
110
|
+
parseInt(hours),
|
|
111
|
+
parseInt(minutes),
|
|
112
|
+
parseInt(seconds),
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// 尝试匹配简化格式: YYYY-MM-DD (默认 00:00:00)
|
|
117
|
+
const dateMatch = trimmed.match(/^(\d{4})-(\d{2})-(\d{2})$/);
|
|
101
118
|
if (dateMatch) {
|
|
102
119
|
const [, year, month, day] = dateMatch;
|
|
103
120
|
return new Date(
|
|
@@ -131,6 +148,33 @@ describe("amend-date command", () => {
|
|
|
131
148
|
expect(date?.getDate()).toBe(5);
|
|
132
149
|
});
|
|
133
150
|
|
|
151
|
+
it("should parse full datetime format", () => {
|
|
152
|
+
const date = parseDate("2026-01-19 14:30:45");
|
|
153
|
+
expect(date).toBeTruthy();
|
|
154
|
+
expect(date?.getFullYear()).toBe(2026);
|
|
155
|
+
expect(date?.getMonth()).toBe(0);
|
|
156
|
+
expect(date?.getDate()).toBe(19);
|
|
157
|
+
expect(date?.getHours()).toBe(14);
|
|
158
|
+
expect(date?.getMinutes()).toBe(30);
|
|
159
|
+
expect(date?.getSeconds()).toBe(45);
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
it("should parse midnight time", () => {
|
|
163
|
+
const date = parseDate("2026-01-19 00:00:00");
|
|
164
|
+
expect(date).toBeTruthy();
|
|
165
|
+
expect(date?.getHours()).toBe(0);
|
|
166
|
+
expect(date?.getMinutes()).toBe(0);
|
|
167
|
+
expect(date?.getSeconds()).toBe(0);
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
it("should parse end of day time", () => {
|
|
171
|
+
const date = parseDate("2026-01-19 23:59:59");
|
|
172
|
+
expect(date).toBeTruthy();
|
|
173
|
+
expect(date?.getHours()).toBe(23);
|
|
174
|
+
expect(date?.getMinutes()).toBe(59);
|
|
175
|
+
expect(date?.getSeconds()).toBe(59);
|
|
176
|
+
});
|
|
177
|
+
|
|
134
178
|
it("should return null for invalid format", () => {
|
|
135
179
|
expect(parseDate("invalid")).toBeNull();
|
|
136
180
|
expect(parseDate("2026-1-19")).toBeNull(); // 缺少前导零
|
|
@@ -138,9 +182,10 @@ describe("amend-date command", () => {
|
|
|
138
182
|
expect(parseDate("19-01-2026")).toBeNull(); // 错误的顺序
|
|
139
183
|
});
|
|
140
184
|
|
|
141
|
-
it("should return null for
|
|
142
|
-
expect(parseDate("2026-01-19 14:30
|
|
143
|
-
expect(parseDate("2026-01-19 14
|
|
185
|
+
it("should return null for incomplete datetime", () => {
|
|
186
|
+
expect(parseDate("2026-01-19 14:30")).toBeNull(); // 缺少秒
|
|
187
|
+
expect(parseDate("2026-01-19 14")).toBeNull(); // 只有小时
|
|
188
|
+
expect(parseDate("2026-01-19 14:30:45:00")).toBeNull(); // 多余部分
|
|
144
189
|
});
|
|
145
190
|
|
|
146
191
|
it("should handle edge cases", () => {
|
|
@@ -149,6 +194,16 @@ describe("amend-date command", () => {
|
|
|
149
194
|
expect(parseDate("2026-13-01")).not.toBeNull(); // 月份超出范围,但格式正确
|
|
150
195
|
expect(parseDate("2026-00-01")).not.toBeNull(); // 月份为0,但格式正确
|
|
151
196
|
});
|
|
197
|
+
|
|
198
|
+
it("should handle whitespace", () => {
|
|
199
|
+
const date1 = parseDate(" 2026-01-19 ");
|
|
200
|
+
expect(date1).toBeTruthy();
|
|
201
|
+
expect(date1?.getFullYear()).toBe(2026);
|
|
202
|
+
|
|
203
|
+
const date2 = parseDate(" 2026-01-19 14:30:45 ");
|
|
204
|
+
expect(date2).toBeTruthy();
|
|
205
|
+
expect(date2?.getHours()).toBe(14);
|
|
206
|
+
});
|
|
152
207
|
});
|
|
153
208
|
|
|
154
209
|
describe("修改最新 commit", () => {
|