7148487的强制清理
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"next_number": 18,
|
||||
"next_number": 19,
|
||||
"branches": [
|
||||
{
|
||||
"number": 1,
|
||||
@@ -198,6 +198,18 @@
|
||||
"status": "finished",
|
||||
"end_commit": "f4a82c96eec49822c39da4f68c87351fe527b0fe",
|
||||
"finished_at": "2025-12-18T18:18:43+08:00"
|
||||
},
|
||||
{
|
||||
"number": 18,
|
||||
"branch_name": "aide/018",
|
||||
"source_branch": "master",
|
||||
"start_commit": "714848745d2e443ff4ee1d907b3e3df0b5e65dc4",
|
||||
"task_id": "2025-12-18T18-38-48",
|
||||
"task_summary": "开始任务准备: aide flow clean 指令与分支概况文档分析",
|
||||
"started_at": "2025-12-18T18:38:48+08:00",
|
||||
"status": "force-cleaned",
|
||||
"end_commit": "19aa94e2e2e084b1c72b8b9e55d565948b8ac19d",
|
||||
"finished_at": "2025-12-18T20:33:37+08:00"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,5 +1,16 @@
|
||||
# Git 分支概况
|
||||
|
||||
## aide/018
|
||||
|
||||
- **任务**: 开始任务准备: aide flow clean 指令与分支概况文档分析
|
||||
- **任务ID**: 2025-12-18T18-38-48
|
||||
- **源分支**: master
|
||||
- **起始提交**: 7148487
|
||||
- **结束提交**: 19aa94e
|
||||
- **状态**: force-cleaned
|
||||
- **起始时间**: 2025-12-18 18:38
|
||||
- **结束时间**: 2025-12-18 20:33
|
||||
|
||||
## aide/017
|
||||
|
||||
- **任务**: 开始任务准备: 调整aide收尾清理逻辑
|
||||
@@ -8,7 +19,8 @@
|
||||
- **起始提交**: f4a82c9
|
||||
- **结束提交**: f4a82c9
|
||||
- **状态**: finished
|
||||
- **时间**: 2025-12-18 14:09 ~ 18:18
|
||||
- **起始时间**: 2025-12-18 14:09
|
||||
- **结束时间**: 2025-12-18 18:18
|
||||
|
||||
## aide/016
|
||||
|
||||
@@ -18,7 +30,8 @@
|
||||
- **起始提交**: 645a30c
|
||||
- **结束提交**: 645a30c
|
||||
- **状态**: finished
|
||||
- **时间**: 2025-12-18 13:29 ~ 13:58
|
||||
- **起始时间**: 2025-12-18 13:29
|
||||
- **结束时间**: 2025-12-18 13:58
|
||||
|
||||
## aide/015
|
||||
|
||||
@@ -28,7 +41,8 @@
|
||||
- **起始提交**: 80ebbd4
|
||||
- **结束提交**: 80ebbd4
|
||||
- **状态**: finished
|
||||
- **时间**: 2025-12-18 12:14 ~ 12:50
|
||||
- **起始时间**: 2025-12-18 12:14
|
||||
- **结束时间**: 2025-12-18 12:50
|
||||
|
||||
## aide/014
|
||||
|
||||
@@ -38,7 +52,8 @@
|
||||
- **起始提交**: d2882c9
|
||||
- **结束提交**: d2882c9
|
||||
- **状态**: finished
|
||||
- **时间**: 2025-12-18 11:53 ~ 11:53
|
||||
- **起始时间**: 2025-12-18 11:53
|
||||
- **结束时间**: 2025-12-18 11:53
|
||||
|
||||
## aide/013
|
||||
|
||||
@@ -48,7 +63,8 @@
|
||||
- **起始提交**: f4b9620
|
||||
- **结束提交**: f4b9620
|
||||
- **状态**: finished
|
||||
- **时间**: 2025-12-18 10:41 ~ 11:22
|
||||
- **起始时间**: 2025-12-18 10:41
|
||||
- **结束时间**: 2025-12-18 11:22
|
||||
|
||||
## aide/012
|
||||
|
||||
@@ -57,7 +73,7 @@
|
||||
- **源分支**: master
|
||||
- **起始提交**: c6f45f9
|
||||
- **状态**: active
|
||||
- **时间**: 2025-12-18 10:09
|
||||
- **起始时间**: 2025-12-18 10:09
|
||||
|
||||
## aide/011
|
||||
|
||||
@@ -67,7 +83,8 @@
|
||||
- **起始提交**: 2042238
|
||||
- **结束提交**: 8ea9ce7
|
||||
- **状态**: finished
|
||||
- **时间**: 2025-12-18 10:03 ~ 10:03
|
||||
- **起始时间**: 2025-12-18 10:03
|
||||
- **结束时间**: 2025-12-18 10:03
|
||||
|
||||
## aide/010
|
||||
|
||||
@@ -77,7 +94,8 @@
|
||||
- **起始提交**: c8d20db
|
||||
- **结束提交**: 2034962
|
||||
- **状态**: finished
|
||||
- **时间**: 2025-12-17 06:34 ~ 06:35
|
||||
- **起始时间**: 2025-12-17 06:34
|
||||
- **结束时间**: 2025-12-17 06:35
|
||||
|
||||
## aide/009
|
||||
|
||||
@@ -87,7 +105,8 @@
|
||||
- **起始提交**: 6305f61
|
||||
- **结束提交**: d705a73
|
||||
- **状态**: finished
|
||||
- **时间**: 2025-12-17 06:31 ~ 06:32
|
||||
- **起始时间**: 2025-12-17 06:31
|
||||
- **结束时间**: 2025-12-17 06:32
|
||||
|
||||
## aide/008
|
||||
|
||||
@@ -97,7 +116,8 @@
|
||||
- **起始提交**: c685c31
|
||||
- **结束提交**: 92eb2ba
|
||||
- **状态**: finished
|
||||
- **时间**: 2025-12-17 06:27 ~ 06:28
|
||||
- **起始时间**: 2025-12-17 06:27
|
||||
- **结束时间**: 2025-12-17 06:28
|
||||
|
||||
## aide/007
|
||||
|
||||
@@ -107,7 +127,8 @@
|
||||
- **起始提交**: 8d4cae6
|
||||
- **结束提交**: 346ec90
|
||||
- **状态**: finished
|
||||
- **时间**: 2025-12-17 06:07 ~ 06:07
|
||||
- **起始时间**: 2025-12-17 06:07
|
||||
- **结束时间**: 2025-12-17 06:07
|
||||
|
||||
## aide/006
|
||||
|
||||
@@ -117,7 +138,8 @@
|
||||
- **起始提交**: 2b0c007
|
||||
- **结束提交**: d60f0ba
|
||||
- **状态**: finished
|
||||
- **时间**: 2025-12-17 06:03 ~ 06:05
|
||||
- **起始时间**: 2025-12-17 06:03
|
||||
- **结束时间**: 2025-12-17 06:05
|
||||
|
||||
## aide/005
|
||||
|
||||
@@ -127,7 +149,8 @@
|
||||
- **起始提交**: a1d7263
|
||||
- **结束提交**: b2f922b
|
||||
- **状态**: finished
|
||||
- **时间**: 2025-12-17 06:00 ~ 06:02
|
||||
- **起始时间**: 2025-12-17 06:00
|
||||
- **结束时间**: 2025-12-17 06:02
|
||||
|
||||
## aide/004
|
||||
|
||||
@@ -137,7 +160,8 @@
|
||||
- **起始提交**: 6179833
|
||||
- **结束提交**: 6179833
|
||||
- **状态**: finished
|
||||
- **时间**: 2025-12-17 05:54 ~ 05:55
|
||||
- **起始时间**: 2025-12-17 05:54
|
||||
- **结束时间**: 2025-12-17 05:55
|
||||
|
||||
## aide/003
|
||||
|
||||
@@ -147,7 +171,8 @@
|
||||
- **起始提交**: aa067fc
|
||||
- **结束提交**: aa067fc
|
||||
- **状态**: finished
|
||||
- **时间**: 2025-12-17 05:42 ~ 05:48
|
||||
- **起始时间**: 2025-12-17 05:42
|
||||
- **结束时间**: 2025-12-17 05:48
|
||||
|
||||
## aide/002
|
||||
|
||||
@@ -156,7 +181,7 @@
|
||||
- **源分支**: master
|
||||
- **起始提交**: be25738
|
||||
- **状态**: active
|
||||
- **时间**: 2025-12-17 05:33
|
||||
- **起始时间**: 2025-12-17 05:33
|
||||
|
||||
## aide/001
|
||||
|
||||
@@ -165,4 +190,4 @@
|
||||
- **源分支**: master
|
||||
- **起始提交**: bd72362
|
||||
- **状态**: active
|
||||
- **时间**: 2025-12-17 04:54
|
||||
- **起始时间**: 2025-12-17 04:54
|
||||
|
||||
195
.aide/logs/2025-12-18T18-38-48-status.json
Normal file
195
.aide/logs/2025-12-18T18-38-48-status.json
Normal file
@@ -0,0 +1,195 @@
|
||||
{
|
||||
"task_id": "2025-12-18T18-38-48",
|
||||
"current_phase": "task-optimize",
|
||||
"current_step": 23,
|
||||
"started_at": "2025-12-18T18:38:48+08:00",
|
||||
"history": [
|
||||
{
|
||||
"timestamp": "2025-12-18T18:38:48+08:00",
|
||||
"action": "start",
|
||||
"phase": "task-optimize",
|
||||
"step": 1,
|
||||
"summary": "开始任务准备: aide flow clean 指令与分支概况文档分析",
|
||||
"git_commit": "f74306e46f459e6642eb84c8463e86d9e0bc697b"
|
||||
},
|
||||
{
|
||||
"timestamp": "2025-12-18T18:42:34+08:00",
|
||||
"action": "next-step",
|
||||
"phase": "task-optimize",
|
||||
"step": 2,
|
||||
"summary": "任务内容解析完成,生成结构化任务描述",
|
||||
"git_commit": "e5211e7e1299da688db14baa65c37a6920f4c9ed"
|
||||
},
|
||||
{
|
||||
"timestamp": "2025-12-18T18:50:34+08:00",
|
||||
"action": "next-step",
|
||||
"phase": "task-optimize",
|
||||
"step": 3,
|
||||
"summary": "用户确认任务需求,发现分支哈希相同的 bug 原因",
|
||||
"git_commit": "3417151e189396a1b2ae8369603045e5c040057b"
|
||||
},
|
||||
{
|
||||
"timestamp": "2025-12-18T18:53:07+08:00",
|
||||
"action": "next-step",
|
||||
"phase": "task-optimize",
|
||||
"step": 4,
|
||||
"summary": "任务细则已确认",
|
||||
"git_commit": "345c44455cc05bbb1c128b96b98c9c6c4b46cb81"
|
||||
},
|
||||
{
|
||||
"timestamp": "2025-12-18T18:53:18+08:00",
|
||||
"action": "next-part",
|
||||
"phase": "flow-design",
|
||||
"step": 5,
|
||||
"summary": "进入流程设计环节",
|
||||
"git_commit": "ca07defc6e5760dccade2969aae608d5d27b9f4b"
|
||||
},
|
||||
{
|
||||
"timestamp": "2025-12-18T18:55:03+08:00",
|
||||
"action": "next-step",
|
||||
"phase": "flow-design",
|
||||
"step": 6,
|
||||
"summary": "流程图设计完成",
|
||||
"git_commit": "aa456b7f3f09d3e089df0ddd16fcc432648db8f9"
|
||||
},
|
||||
{
|
||||
"timestamp": "2025-12-18T18:55:18+08:00",
|
||||
"action": "next-part",
|
||||
"phase": "impl",
|
||||
"step": 7,
|
||||
"summary": "流程设计完成,进入实现环节",
|
||||
"git_commit": "65660e4265e1a67420bc62b503923444236323d7"
|
||||
},
|
||||
{
|
||||
"timestamp": "2025-12-18T18:56:06+08:00",
|
||||
"action": "next-step",
|
||||
"phase": "impl",
|
||||
"step": 8,
|
||||
"summary": "完成: decisions 清理逻辑修改为直接删除不备份",
|
||||
"git_commit": "9ed16d17f24c3e962dc91d85efdd198f434c5f6b"
|
||||
},
|
||||
{
|
||||
"timestamp": "2025-12-18T18:59:53+08:00",
|
||||
"action": "next-step",
|
||||
"phase": "impl",
|
||||
"step": 9,
|
||||
"summary": "完成: finish 流程重构,修复哈希 bug,添加 clean_branch_merge 方法",
|
||||
"git_commit": "e0cc0a4556577b953cec406f79d05857d2840829"
|
||||
},
|
||||
{
|
||||
"timestamp": "2025-12-18T19:01:34+08:00",
|
||||
"action": "next-step",
|
||||
"phase": "impl",
|
||||
"step": 10,
|
||||
"summary": "完成: 添加 aide flow clean 指令",
|
||||
"git_commit": "57cc51781e9a9e5aae02c7fef6604c739c6b4f47"
|
||||
},
|
||||
{
|
||||
"timestamp": "2025-12-18T19:02:57+08:00",
|
||||
"action": "next-step",
|
||||
"phase": "impl",
|
||||
"step": 11,
|
||||
"summary": "测试验证: clean 命令正确检测工作区状态",
|
||||
"git_commit": "f28cb62ccb5154afdc09a626608c56f0e23c3892"
|
||||
},
|
||||
{
|
||||
"timestamp": "2025-12-18T19:03:11+08:00",
|
||||
"action": "next-part",
|
||||
"phase": "verify",
|
||||
"step": 12,
|
||||
"summary": "实现完成,进入验证环节",
|
||||
"git_commit": "0f2de0a72b93b36a55e35dba718f78b2e50982e5"
|
||||
},
|
||||
{
|
||||
"timestamp": "2025-12-18T19:04:52+08:00",
|
||||
"action": "next-step",
|
||||
"phase": "verify",
|
||||
"step": 13,
|
||||
"summary": "验证完成: finish 流程、clean 指令、decisions 清理逻辑均已验证",
|
||||
"git_commit": "2c20dd4d11d804583e2e5ebe78203909a1b61dbf"
|
||||
},
|
||||
{
|
||||
"timestamp": "2025-12-18T19:05:06+08:00",
|
||||
"action": "next-part",
|
||||
"phase": "docs",
|
||||
"step": 14,
|
||||
"summary": "验证通过,进入文档环节",
|
||||
"git_commit": "52dde4809fd8359c962ea77d37f78f03b7560e84"
|
||||
},
|
||||
{
|
||||
"timestamp": "2025-12-18T19:07:09+08:00",
|
||||
"action": "next-step",
|
||||
"phase": "docs",
|
||||
"step": 15,
|
||||
"summary": "CHANGELOG.md 更新完成",
|
||||
"git_commit": "5e7b1381b9b23c72eed2a7af7486f3b2a1875fe6"
|
||||
},
|
||||
{
|
||||
"timestamp": "2025-12-18T19:07:24+08:00",
|
||||
"action": "next-part",
|
||||
"phase": "confirm",
|
||||
"step": 16,
|
||||
"summary": "文档更新完成,进入用户确认环节",
|
||||
"git_commit": "d3c1986de7b08f69051a6a2f5aa7d19fd5743456"
|
||||
},
|
||||
{
|
||||
"timestamp": "2025-12-18T19:29:56+08:00",
|
||||
"action": "back-part",
|
||||
"phase": "task-optimize",
|
||||
"step": 17,
|
||||
"summary": "返工:修复三个问题 - 1.结束提交哈希未记录到md 2.md时间格式调整 3.clean应自动提交脏工作区",
|
||||
"git_commit": "9858fa48c393b6b21f0ab8d51f54aec5d5b12a8e"
|
||||
},
|
||||
{
|
||||
"timestamp": "2025-12-18T19:33:43+08:00",
|
||||
"action": "next-part",
|
||||
"phase": "flow-design",
|
||||
"step": 18,
|
||||
"summary": "开始修复三个问题",
|
||||
"git_commit": "f166f406b52586a4b9e357b8f3b29d19b24dfb64"
|
||||
},
|
||||
{
|
||||
"timestamp": "2025-12-18T19:36:49+08:00",
|
||||
"action": "next-part",
|
||||
"phase": "impl",
|
||||
"step": 19,
|
||||
"summary": "开始验证修复",
|
||||
"git_commit": "878d10cd7b79d2a9aaf2889a37de122a2e025c31"
|
||||
},
|
||||
{
|
||||
"timestamp": "2025-12-18T19:38:06+08:00",
|
||||
"action": "next-part",
|
||||
"phase": "verify",
|
||||
"step": 20,
|
||||
"summary": "验证修复完成",
|
||||
"git_commit": "64552682b4f2d3f86ce7d97f3930d9251f0add4a"
|
||||
},
|
||||
{
|
||||
"timestamp": "2025-12-18T19:38:18+08:00",
|
||||
"action": "next-part",
|
||||
"phase": "docs",
|
||||
"step": 21,
|
||||
"summary": "更新文档",
|
||||
"git_commit": "64d626d32c861125dd636281eea8fd974d3bd90c"
|
||||
},
|
||||
{
|
||||
"timestamp": "2025-12-18T19:39:28+08:00",
|
||||
"action": "next-part",
|
||||
"phase": "confirm",
|
||||
"step": 22,
|
||||
"summary": "返工修复完成,进入用户确认",
|
||||
"git_commit": "1bf8ff39654b7d9c915f90684c1587f3e63a173b"
|
||||
},
|
||||
{
|
||||
"timestamp": "2025-12-18T19:50:49+08:00",
|
||||
"action": "back-part",
|
||||
"phase": "task-optimize",
|
||||
"step": 23,
|
||||
"summary": "返工:修复 find_project_root 向上查找逻辑",
|
||||
"git_commit": "05dace3dd55e5cf33236270180eb105dac6e3175"
|
||||
}
|
||||
],
|
||||
"source_branch": "master",
|
||||
"start_commit": "714848745d2e443ff4ee1d907b3e3df0b5e65dc4",
|
||||
"task_branch": "aide/018"
|
||||
}
|
||||
77
CHANGELOG.md
77
CHANGELOG.md
@@ -4,6 +4,83 @@
|
||||
|
||||
## 2025-12-18
|
||||
|
||||
### 修复
|
||||
|
||||
**修复 end_commit 记录逻辑**
|
||||
- `end_commit` 现在记录 tracker 创建的 finish 提交哈希(`[aide] finish: {summary}`)
|
||||
- `finished_at` 使用 finish 提交的时间戳
|
||||
- tracker.py:移除多余的 `[aide] finish: 更新状态文件` 提交,改为传递 end_commit 和 finished_at 给 branch_mgr
|
||||
- branch.py:finish_branch_merge 接收 end_commit 和 finished_at 参数
|
||||
- 正常 finish 流程不再创建额外的结束提交,直接使用 tracker 传入的值
|
||||
- 强制清理(clean)仍会创建自己的结束提交
|
||||
- flow-status.json 和 branches.json/md 的更新合并到同一个提交 `[aide] finish: 更新状态`
|
||||
- 新增 `git.amend()` 方法(备用)
|
||||
|
||||
**修复 find_project_root 在子项目中定位错误的问题**
|
||||
- 原因:从复制的测试目录运行时,因没有 `flow-status.json` 而向上查找到父项目
|
||||
- 解决:添加"步骤 0",如果当前目录已有 `.aide` 目录,直接使用不向上查找
|
||||
- 新的查找策略:
|
||||
0. 当前目录有 `.aide` → 直接使用
|
||||
1. 向上查找有 `flow-status.json` 的目录(活跃任务)
|
||||
2. 向上查找有 `config.toml` 的目录
|
||||
|
||||
### 新增功能
|
||||
|
||||
**`aide flow clean` 强制清理命令**
|
||||
- 用于在任务中途强制终止流程
|
||||
- 如果工作区不干净,自动创建一个提交
|
||||
- 执行流程与 finish 类似,但:
|
||||
- 提交消息格式为 `{start_commit[:7]}的强制清理`
|
||||
- 分支状态标记为 `force-cleaned`
|
||||
- 保留任务分支供后续参考
|
||||
|
||||
### 修复
|
||||
|
||||
**修复 finish 流程中起始/结束提交哈希相同的 bug**
|
||||
- 原因:切回源分支后才调用 `record_branch_finish`,导致 `rev_parse_head()` 获取的是源分支 HEAD
|
||||
- 解决:在任务分支上先创建"结束提交"并记录哈希,在最终保存时直接使用保存的变量
|
||||
- 新增 `record_end_commit` 方法:仅记录结束提交和时间,不更新状态
|
||||
- 在 `_merge_normal` 和 `_merge_with_temp_branch` 中,直接使用保存的 `end_commit` 变量,确保不会丢失
|
||||
|
||||
### 变更
|
||||
|
||||
**finish/clean 流程重构**
|
||||
- 新流程:结束提交 → 记录哈希 → 清理 → 清理提交 → 切回源分支 → squash 合并 → 更新状态(使用保存的end_commit) → 收尾提交
|
||||
- `_merge_normal` 方法新增 `is_force_clean` 参数,不再调用 `update_branch_status`,直接内联更新
|
||||
- `_merge_with_temp_branch` 方法也同步更新
|
||||
|
||||
**decisions 清理逻辑简化**
|
||||
- 清理时不再备份 `decisions/*.json`,直接删除
|
||||
- 移除备份目录创建逻辑
|
||||
|
||||
**branches.md 时间格式调整**
|
||||
- 起始时间和结束时间分别单独列出
|
||||
- 原格式:`- **时间**: 2025-12-18 10:30 ~ 11:45`
|
||||
- 新格式:
|
||||
- `- **起始时间**: 2025-12-18 10:30`
|
||||
- `- **结束时间**: 2025-12-18 11:45`
|
||||
|
||||
### 修改的文件
|
||||
- `aide-program/aide/core/config.py`
|
||||
- `find_project_root` 函数:添加步骤 0,当前目录有 .aide 时不向上查找
|
||||
- `aide-program/aide/flow/git.py`
|
||||
- 新增 `amend` 方法:将暂存区内容追加到上一次提交
|
||||
- `aide-program/aide/flow/branch.py`
|
||||
- `_cleanup_task_files` 方法:decisions 直接删除不备份
|
||||
- `record_branch_finish` 方法:保持兼容
|
||||
- 新增 `record_end_commit` 方法
|
||||
- `clean_branch_merge` 方法:脏工作区时自动创建提交
|
||||
- `_merge_normal` 方法:重构流程,结束提交后立即更新状态再清理
|
||||
- `_merge_with_temp_branch` 方法:同步重构
|
||||
- `_generate_markdown` 方法:时间格式分开显示
|
||||
- `aide-program/aide/flow/tracker.py`
|
||||
- 新增 `clean` 方法
|
||||
- `aide-program/aide/main.py`
|
||||
- 新增 `flow clean` 子命令
|
||||
- 新增 `handle_flow_clean` 处理函数
|
||||
|
||||
---
|
||||
|
||||
### 改进
|
||||
|
||||
**收尾清理逻辑增强**
|
||||
|
||||
@@ -17,11 +17,14 @@ def find_project_root(start_path: Path | None = None) -> Path:
|
||||
类似于 git 查找 .git 目录的逻辑:从当前目录开始向上遍历,
|
||||
直到找到包含有效 .aide 目录的父目录。
|
||||
|
||||
查找策略(两遍遍历):
|
||||
查找策略(三遍遍历):
|
||||
0. 首先:如果当前目录有 .aide 目录,直接使用(不向上查找)
|
||||
1. 第一遍:优先查找包含 flow-status.json 的目录(活跃任务)
|
||||
2. 第二遍:如果第一遍未找到,查找包含 config.toml 的目录
|
||||
|
||||
这样可以确保从子目录运行时,优先找到有活跃任务的项目根目录。
|
||||
这样可以确保:
|
||||
- 在子项目目录运行时,使用子项目的配置
|
||||
- 从子目录运行时,优先找到有活跃任务的项目根目录
|
||||
|
||||
Args:
|
||||
start_path: 起始路径,默认为当前工作目录
|
||||
@@ -46,6 +49,10 @@ def find_project_root(start_path: Path | None = None) -> Path:
|
||||
return current
|
||||
return None
|
||||
|
||||
def has_aide_dir(path: Path) -> bool:
|
||||
"""检查是否有 .aide 目录"""
|
||||
return (path / ".aide").is_dir()
|
||||
|
||||
def has_flow_status(path: Path) -> bool:
|
||||
"""检查是否有活跃任务状态文件"""
|
||||
return (path / ".aide" / "flow-status.json").exists()
|
||||
@@ -54,6 +61,10 @@ def find_project_root(start_path: Path | None = None) -> Path:
|
||||
"""检查是否有配置文件"""
|
||||
return (path / ".aide" / "config.toml").exists()
|
||||
|
||||
# 步骤 0:如果当前目录有 .aide 目录,直接使用(不向上查找)
|
||||
if has_aide_dir(start_path):
|
||||
return start_path
|
||||
|
||||
# 第一遍:优先查找有活跃任务的目录
|
||||
result = search_upward(has_flow_status)
|
||||
if result is not None:
|
||||
|
||||
@@ -162,20 +162,14 @@ class BranchManager:
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
# 5. 备份并删除 decisions/*.json
|
||||
# 5. 直接删除 decisions/*.json(不备份)
|
||||
decisions_dir = self.aide_dir / "decisions"
|
||||
if decisions_dir.exists():
|
||||
decision_files = list(decisions_dir.glob("*.json"))
|
||||
if decision_files:
|
||||
# 创建备份目录
|
||||
backup_decisions_dir = self.logs_dir / f"{task_id}-decisions"
|
||||
backup_decisions_dir.mkdir(parents=True, exist_ok=True)
|
||||
for decision_file in decision_files:
|
||||
try:
|
||||
shutil.copy2(decision_file, backup_decisions_dir / decision_file.name)
|
||||
decision_file.unlink()
|
||||
except OSError:
|
||||
pass
|
||||
for decision_file in decisions_dir.glob("*.json"):
|
||||
try:
|
||||
decision_file.unlink()
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
# 6. 删除 pending-items.json
|
||||
pending_items_path = self.aide_dir / "pending-items.json"
|
||||
@@ -252,10 +246,13 @@ class BranchManager:
|
||||
if branch.end_commit:
|
||||
lines.append(f"- **结束提交**: {branch.end_commit[:7]}")
|
||||
lines.append(f"- **状态**: {branch.status}")
|
||||
time_str = branch.started_at[:16].replace("T", " ")
|
||||
# 起始时间
|
||||
start_time_str = branch.started_at[:16].replace("T", " ")
|
||||
lines.append(f"- **起始时间**: {start_time_str}")
|
||||
# 结束时间(单独列出)
|
||||
if branch.finished_at:
|
||||
time_str += f" ~ {branch.finished_at[11:16]}"
|
||||
lines.append(f"- **时间**: {time_str}")
|
||||
end_time_str = branch.finished_at[:16].replace("T", " ")
|
||||
lines.append(f"- **结束时间**: {end_time_str}")
|
||||
if branch.temp_branch:
|
||||
lines.append(f"- **临时分支**: {branch.temp_branch}")
|
||||
lines.append("")
|
||||
@@ -349,7 +346,7 @@ class BranchManager:
|
||||
end_commit: str | None = None,
|
||||
temp_branch: str | None = None,
|
||||
) -> None:
|
||||
"""记录分支结束信息"""
|
||||
"""记录分支结束信息(兼容旧接口,一次性更新所有字段)"""
|
||||
data = self.load_branches()
|
||||
branch_info = self.get_active_branch_info()
|
||||
|
||||
@@ -378,9 +375,97 @@ class BranchManager:
|
||||
self._current_branch_info = None
|
||||
self.save_branches()
|
||||
|
||||
def finish_branch_merge(self, task_summary: str) -> tuple[bool, str]:
|
||||
def record_end_commit(self, end_commit: str) -> None:
|
||||
"""记录结束提交和时间(不更新状态)
|
||||
|
||||
用于在任务分支上先记录结束点,再执行清理操作。
|
||||
"""
|
||||
data = self.load_branches()
|
||||
branch_info = self.get_active_branch_info()
|
||||
|
||||
if branch_info is None:
|
||||
return
|
||||
|
||||
# 更新分支信息(只更新 end_commit 和 finished_at)
|
||||
for i, branch in enumerate(data.branches):
|
||||
if branch.number == branch_info.number:
|
||||
data.branches[i] = BranchInfo(
|
||||
number=branch.number,
|
||||
branch_name=branch.branch_name,
|
||||
source_branch=branch.source_branch,
|
||||
start_commit=branch.start_commit,
|
||||
end_commit=end_commit,
|
||||
task_id=branch.task_id,
|
||||
task_summary=branch.task_summary,
|
||||
started_at=branch.started_at,
|
||||
finished_at=now_iso(),
|
||||
status=branch.status, # 保持原状态
|
||||
temp_branch=branch.temp_branch,
|
||||
)
|
||||
break
|
||||
|
||||
self._data = data
|
||||
self.save_branches()
|
||||
|
||||
def update_branch_status(self, status: str) -> None:
|
||||
"""更新分支状态(不修改其他字段)
|
||||
|
||||
用于在切回源分支后更新最终状态。
|
||||
"""
|
||||
data = self.load_branches()
|
||||
|
||||
# 查找当前任务分支(可能已不是当前分支)
|
||||
current_branch = self.git.get_current_branch()
|
||||
|
||||
# 优先使用缓存的分支信息
|
||||
target_number = None
|
||||
if self._current_branch_info is not None:
|
||||
target_number = self._current_branch_info.number
|
||||
else:
|
||||
# 查找最近的活跃分支
|
||||
for branch in reversed(data.branches):
|
||||
if branch.status == "active":
|
||||
target_number = branch.number
|
||||
break
|
||||
|
||||
if target_number is None:
|
||||
return
|
||||
|
||||
# 更新分支状态
|
||||
for i, branch in enumerate(data.branches):
|
||||
if branch.number == target_number:
|
||||
data.branches[i] = BranchInfo(
|
||||
number=branch.number,
|
||||
branch_name=branch.branch_name,
|
||||
source_branch=branch.source_branch,
|
||||
start_commit=branch.start_commit,
|
||||
end_commit=branch.end_commit,
|
||||
task_id=branch.task_id,
|
||||
task_summary=branch.task_summary,
|
||||
started_at=branch.started_at,
|
||||
finished_at=branch.finished_at,
|
||||
status=status,
|
||||
temp_branch=branch.temp_branch,
|
||||
)
|
||||
break
|
||||
|
||||
self._data = data
|
||||
self._current_branch_info = None
|
||||
self.save_branches()
|
||||
|
||||
def finish_branch_merge(
|
||||
self,
|
||||
task_summary: str,
|
||||
end_commit: str | None = None,
|
||||
finished_at: str | None = None,
|
||||
) -> tuple[bool, str]:
|
||||
"""执行分支合并逻辑
|
||||
|
||||
Args:
|
||||
task_summary: 任务摘要
|
||||
end_commit: 结束提交哈希(由 tracker 传入)
|
||||
finished_at: 结束时间(由 tracker 传入)
|
||||
|
||||
返回 (是否成功, 消息)
|
||||
"""
|
||||
branch_info = self.get_active_branch_info()
|
||||
@@ -398,49 +483,148 @@ class BranchManager:
|
||||
return self._merge_with_temp_branch(
|
||||
branch_info=branch_info,
|
||||
task_summary=task_summary,
|
||||
end_commit=end_commit,
|
||||
finished_at=finished_at,
|
||||
)
|
||||
else:
|
||||
# 正常合并流程
|
||||
return self._merge_normal(
|
||||
branch_info=branch_info,
|
||||
task_summary=task_summary,
|
||||
end_commit=end_commit,
|
||||
finished_at=finished_at,
|
||||
)
|
||||
|
||||
def clean_branch_merge(self) -> tuple[bool, str]:
|
||||
"""强制清理当前任务分支
|
||||
|
||||
如果工作区不干净,会自动创建一个提交。
|
||||
返回 (是否成功, 消息)
|
||||
"""
|
||||
# 如果工作区不干净,自动创建提交
|
||||
if not self.git.is_clean():
|
||||
self.git.add_all()
|
||||
self.git.commit("[aide] 强制清理前保存未提交的变更")
|
||||
|
||||
branch_info = self.get_active_branch_info()
|
||||
|
||||
if branch_info is None:
|
||||
return False, "未找到活跃的任务分支"
|
||||
|
||||
source_branch = branch_info.source_branch
|
||||
start_commit = branch_info.start_commit
|
||||
|
||||
# 检查源分支是否有新提交
|
||||
if self.git.has_commits_since(start_commit, source_branch):
|
||||
# 源分支有新提交,使用临时分支策略(强制清理模式)
|
||||
return self._merge_with_temp_branch(
|
||||
branch_info=branch_info,
|
||||
task_summary="强制清理",
|
||||
is_force_clean=True,
|
||||
)
|
||||
else:
|
||||
# 正常合并流程(强制清理模式)
|
||||
return self._merge_normal(
|
||||
branch_info=branch_info,
|
||||
task_summary="强制清理",
|
||||
is_force_clean=True,
|
||||
)
|
||||
|
||||
def _merge_normal(
|
||||
self,
|
||||
branch_info: BranchInfo,
|
||||
task_summary: str,
|
||||
is_force_clean: bool = False,
|
||||
end_commit: str | None = None,
|
||||
finished_at: str | None = None,
|
||||
) -> tuple[bool, str]:
|
||||
"""正常合并流程:清理 → 临时提交 → squash 合并 → 收尾提交"""
|
||||
"""正常合并流程:更新状态 → 清理 → squash 合并 → 收尾提交
|
||||
|
||||
Args:
|
||||
branch_info: 分支信息
|
||||
task_summary: 任务摘要
|
||||
is_force_clean: 是否为强制清理模式
|
||||
end_commit: 结束提交哈希(finish 时由 tracker 传入)
|
||||
finished_at: 结束时间(finish 时由 tracker 传入)
|
||||
"""
|
||||
source_branch = branch_info.source_branch
|
||||
task_branch = branch_info.branch_name
|
||||
task_id = branch_info.task_id
|
||||
start_commit = branch_info.start_commit
|
||||
branch_number = branch_info.number
|
||||
|
||||
# 1. 执行任务文件清理(在工作分支上)
|
||||
# === 在任务分支上执行 ===
|
||||
|
||||
# 对于强制清理,需要创建结束提交;对于正常 finish,使用 tracker 传入的
|
||||
if is_force_clean:
|
||||
# 1. 创建"结束提交"(强制清理模式)
|
||||
self.git.add_all()
|
||||
end_commit_msg = f"[aide] 强制清理: {task_summary}"
|
||||
self.git.commit(end_commit_msg)
|
||||
end_commit = self.git.rev_parse_head()
|
||||
finished_at = now_iso()
|
||||
|
||||
# 如果没有 end_commit(兜底),使用当前 HEAD
|
||||
if end_commit is None:
|
||||
end_commit = self.git.rev_parse_head()
|
||||
if finished_at is None:
|
||||
finished_at = now_iso()
|
||||
|
||||
# 2. 更新分支状态(记录 end_commit 和完成时间)
|
||||
status = "force-cleaned" if is_force_clean else "finished"
|
||||
data = self.load_branches()
|
||||
for i, branch in enumerate(data.branches):
|
||||
if branch.number == branch_number:
|
||||
data.branches[i] = BranchInfo(
|
||||
number=branch.number,
|
||||
branch_name=branch.branch_name,
|
||||
source_branch=branch.source_branch,
|
||||
start_commit=branch.start_commit,
|
||||
end_commit=end_commit,
|
||||
task_id=branch.task_id,
|
||||
task_summary=branch.task_summary,
|
||||
started_at=branch.started_at,
|
||||
finished_at=finished_at,
|
||||
status=status,
|
||||
temp_branch=branch.temp_branch,
|
||||
)
|
||||
break
|
||||
self._data = data
|
||||
self._current_branch_info = None
|
||||
self.save_branches()
|
||||
|
||||
# 3. 提交状态更新(包含 flow-status.json 和 branches.json/md)
|
||||
self.git.add_all()
|
||||
if is_force_clean:
|
||||
self.git.commit("[aide] 强制清理: 更新状态")
|
||||
else:
|
||||
self.git.commit("[aide] finish: 更新状态")
|
||||
|
||||
# 4. 执行任务文件清理
|
||||
self._cleanup_task_files(task_id)
|
||||
|
||||
# 2. 创建临时提交保存清理后的变更
|
||||
# 5. 创建"清理提交"
|
||||
self.git.add_all()
|
||||
self.git.commit("[aide] 清理任务临时文件")
|
||||
|
||||
# 3. 切回源分支
|
||||
# === 切回源分支执行 ===
|
||||
|
||||
# 6. 切回源分支
|
||||
self.git.checkout(source_branch)
|
||||
|
||||
# 切换分支后清理 lock 文件
|
||||
self._cleanup_lock_file()
|
||||
|
||||
# 4. squash 合并任务分支
|
||||
# 7. squash 合并任务分支
|
||||
self.git.merge_squash(task_branch)
|
||||
|
||||
# 5. 先更新分支记录(不再记录 end_commit)
|
||||
self.record_branch_finish(status="finished")
|
||||
|
||||
# 6. 创建收尾提交(包含 squash 内容和分支记录更新)
|
||||
# 格式:{起始哈希}的任务收尾
|
||||
# 8. 创建收尾提交
|
||||
self.git.add_all()
|
||||
short_hash = start_commit[:7] if start_commit else "unknown"
|
||||
commit_msg = f"{short_hash}的任务收尾"
|
||||
if is_force_clean:
|
||||
commit_msg = f"{short_hash}的强制清理"
|
||||
else:
|
||||
commit_msg = f"{short_hash}的任务收尾"
|
||||
self.git.commit(commit_msg)
|
||||
|
||||
return True, f"任务分支已合并到 {source_branch}"
|
||||
@@ -449,35 +633,103 @@ class BranchManager:
|
||||
self,
|
||||
branch_info: BranchInfo,
|
||||
task_summary: str,
|
||||
is_force_clean: bool = False,
|
||||
end_commit: str | None = None,
|
||||
finished_at: str | None = None,
|
||||
) -> tuple[bool, str]:
|
||||
"""临时分支合并策略:源分支有新提交时使用"""
|
||||
"""临时分支合并策略:源分支有新提交时使用
|
||||
|
||||
流程:更新状态 → 清理 → 临时分支 squash 合并
|
||||
|
||||
Args:
|
||||
branch_info: 分支信息
|
||||
task_summary: 任务摘要
|
||||
is_force_clean: 是否为强制清理模式
|
||||
end_commit: 结束提交哈希(finish 时由 tracker 传入)
|
||||
finished_at: 结束时间(finish 时由 tracker 传入)
|
||||
"""
|
||||
start_commit = branch_info.start_commit
|
||||
task_branch = branch_info.branch_name
|
||||
task_id = branch_info.task_id
|
||||
branch_number = branch_info.number
|
||||
temp_branch = f"{task_branch}-merge"
|
||||
|
||||
# 从起始提交检出临时分支
|
||||
# === 在任务分支上执行 ===
|
||||
|
||||
# 对于强制清理,需要创建结束提交;对于正常 finish,使用 tracker 传入的
|
||||
if is_force_clean:
|
||||
# 1. 创建"结束提交"(强制清理模式)
|
||||
self.git.add_all()
|
||||
end_commit_msg = f"[aide] 强制清理: {task_summary}"
|
||||
self.git.commit(end_commit_msg)
|
||||
end_commit = self.git.rev_parse_head()
|
||||
finished_at = now_iso()
|
||||
|
||||
# 如果没有 end_commit(兜底),使用当前 HEAD
|
||||
if end_commit is None:
|
||||
end_commit = self.git.rev_parse_head()
|
||||
if finished_at is None:
|
||||
finished_at = now_iso()
|
||||
|
||||
# 2. 更新分支状态(记录 end_commit 和完成时间)
|
||||
status = "force-cleaned-to-temp" if is_force_clean else "merged-to-temp"
|
||||
data = self.load_branches()
|
||||
for i, branch in enumerate(data.branches):
|
||||
if branch.number == branch_number:
|
||||
data.branches[i] = BranchInfo(
|
||||
number=branch.number,
|
||||
branch_name=branch.branch_name,
|
||||
source_branch=branch.source_branch,
|
||||
start_commit=branch.start_commit,
|
||||
end_commit=end_commit,
|
||||
task_id=branch.task_id,
|
||||
task_summary=branch.task_summary,
|
||||
started_at=branch.started_at,
|
||||
finished_at=finished_at,
|
||||
status=status,
|
||||
temp_branch=temp_branch,
|
||||
)
|
||||
break
|
||||
self._data = data
|
||||
self._current_branch_info = None
|
||||
self.save_branches()
|
||||
|
||||
# 3. 提交状态更新(包含 flow-status.json 和 branches.json/md)
|
||||
self.git.add_all()
|
||||
if is_force_clean:
|
||||
self.git.commit("[aide] 强制清理: 更新状态")
|
||||
else:
|
||||
self.git.commit("[aide] finish: 更新状态")
|
||||
|
||||
# 4. 执行任务文件清理
|
||||
self._cleanup_task_files(task_id)
|
||||
|
||||
# 5. 创建"清理提交"
|
||||
self.git.add_all()
|
||||
self.git.commit("[aide] 清理任务临时文件")
|
||||
|
||||
# === 切换到临时分支执行 ===
|
||||
|
||||
# 6. 从起始提交检出临时分支
|
||||
self.git.checkout_new_branch(temp_branch, start_commit)
|
||||
|
||||
# 切换分支后清理 lock 文件
|
||||
self._cleanup_lock_file()
|
||||
|
||||
# 在临时分支执行 squash 合并
|
||||
# 7. 在临时分支执行 squash 合并
|
||||
self.git.merge_squash(task_branch)
|
||||
|
||||
# 创建提交
|
||||
# 8. 创建压缩提交
|
||||
self.git.add_all()
|
||||
commit_msg = f"[aide] 任务压缩提交: {task_summary}"
|
||||
end_commit = self.git.commit(commit_msg)
|
||||
|
||||
# 记录完成(保留任务分支和临时分支)
|
||||
self.record_branch_finish(
|
||||
status="merged-to-temp",
|
||||
end_commit=end_commit,
|
||||
temp_branch=temp_branch,
|
||||
)
|
||||
if is_force_clean:
|
||||
commit_msg = f"[aide] 强制清理压缩提交: {task_summary}"
|
||||
else:
|
||||
commit_msg = f"[aide] 任务压缩提交: {task_summary}"
|
||||
self.git.commit(commit_msg)
|
||||
|
||||
action_name = "强制清理" if is_force_clean else "任务完成"
|
||||
return False, (
|
||||
f"⚠ 源分支 {branch_info.source_branch} 有新提交\n"
|
||||
f"已在临时分支 {temp_branch} 完成合并\n"
|
||||
f"已在临时分支 {temp_branch} 完成{action_name}合并\n"
|
||||
f"请手动处理后续操作"
|
||||
)
|
||||
|
||||
@@ -127,6 +127,13 @@ class GitIntegration:
|
||||
if result.returncode != 0:
|
||||
raise FlowError(_format_git_error(f"squash 合并分支 {branch} 失败", result))
|
||||
|
||||
def amend(self) -> str:
|
||||
"""将暂存区内容追加到上一次提交(不修改提交消息)"""
|
||||
result = self._run(["commit", "--amend", "--no-edit"], check=False)
|
||||
if result.returncode != 0:
|
||||
raise FlowError(_format_git_error("git commit --amend 失败", result))
|
||||
return self.rev_parse_head()
|
||||
|
||||
def _run(self, args: list[str], check: bool) -> subprocess.CompletedProcess[str]:
|
||||
return subprocess.run(
|
||||
["git", *args],
|
||||
|
||||
@@ -47,6 +47,37 @@ class FlowTracker:
|
||||
def error(self, description: str) -> bool:
|
||||
return self._run(action="error", to_phase=None, text=description)
|
||||
|
||||
def clean(self) -> bool:
|
||||
"""强制清理当前任务
|
||||
|
||||
前提条件:工作区必须干净
|
||||
"""
|
||||
try:
|
||||
self.storage.ensure_ready()
|
||||
|
||||
with self.storage.lock():
|
||||
status = self.storage.load_status()
|
||||
if status is None:
|
||||
output.err("未找到活跃任务,无需清理")
|
||||
return False
|
||||
|
||||
# 执行强制清理
|
||||
success, msg = self.branch_mgr.clean_branch_merge()
|
||||
|
||||
if success:
|
||||
output.ok(f"强制清理完成: {msg}")
|
||||
else:
|
||||
if "工作区不干净" in msg or "未找到活跃" in msg:
|
||||
output.err(msg)
|
||||
else:
|
||||
# 临时分支情况,需要手动处理
|
||||
output.warn(msg)
|
||||
return success
|
||||
|
||||
except FlowError as exc:
|
||||
output.err(str(exc))
|
||||
return False
|
||||
|
||||
def _run(self, *, action: str, to_phase: str | None, text: str) -> bool:
|
||||
try:
|
||||
self.storage.ensure_ready()
|
||||
@@ -129,12 +160,18 @@ class FlowTracker:
|
||||
|
||||
# 如果进入 finish 环节,执行分支合并(必须在提交后执行)
|
||||
if action == "next-part" and to_phase == "finish":
|
||||
# 再次提交状态文件(因为 save_status 更新了 git_commit hash)
|
||||
self.git.add_all()
|
||||
self.git.commit("[aide] finish: 更新状态文件")
|
||||
# finish 提交的哈希就是 end_commit
|
||||
finish_commit = None
|
||||
finish_timestamp = None
|
||||
if final_status.history:
|
||||
last_entry = final_status.history[-1]
|
||||
finish_commit = last_entry.git_commit
|
||||
finish_timestamp = last_entry.timestamp
|
||||
|
||||
success, merge_msg = self.branch_mgr.finish_branch_merge(
|
||||
task_summary=normalized_text,
|
||||
end_commit=finish_commit,
|
||||
finished_at=finish_timestamp,
|
||||
)
|
||||
if not success:
|
||||
output.warn(merge_msg)
|
||||
|
||||
@@ -140,6 +140,10 @@ def build_parser() -> argparse.ArgumentParser:
|
||||
flow_show.add_argument("task_id", help="任务 ID(时间戳格式,如 20251215-103000)")
|
||||
flow_show.set_defaults(func=handle_flow_show)
|
||||
|
||||
# aide flow clean
|
||||
flow_clean = flow_sub.add_parser("clean", help="强制清理当前任务(工作区需干净)")
|
||||
flow_clean.set_defaults(func=handle_flow_clean)
|
||||
|
||||
flow_parser.set_defaults(func=handle_flow_help)
|
||||
|
||||
# aide decide
|
||||
@@ -310,6 +314,14 @@ def handle_flow_error(args: argparse.Namespace) -> bool:
|
||||
return tracker.error(args.description)
|
||||
|
||||
|
||||
def handle_flow_clean(args: argparse.Namespace) -> bool:
|
||||
"""aide flow clean - 强制清理当前任务。"""
|
||||
root = find_project_root()
|
||||
cfg = ConfigManager(root)
|
||||
tracker = FlowTracker(root, cfg)
|
||||
return tracker.clean()
|
||||
|
||||
|
||||
def handle_flow_status(args: argparse.Namespace) -> bool:
|
||||
"""aide flow status - 查看当前任务状态。"""
|
||||
from aide.flow.storage import FlowStorage
|
||||
|
||||
17
task-now.md
17
task-now.md
@@ -1,17 +0,0 @@
|
||||
1.
|
||||
|
||||
创建一个aide flow clean指令,用于强制结束flow流程:
|
||||
|
||||
如果当前工作仓库状态干净,则按照finish时需要清理的东西,同样的对那些文件进行清理,
|
||||
|
||||
然后创建一个清理提交,回到原分支,
|
||||
|
||||
然后压缩提交,但不同的是此时提交消息不是任务收尾,而是abcdef123的强制清理
|
||||
|
||||
2.
|
||||
|
||||
调整aide程序,清理时不用备份decisions,而是直接删除,
|
||||
|
||||
3.
|
||||
|
||||
你需要查看文档以及程序实现,然后告诉我关于git分支概况文档的创建和维护、原理及其工作流程逻辑,然后我需要对它做出一些调整
|
||||
Reference in New Issue
Block a user