feat: AI Pull Request action — opencode 自動產生 PR 並通過 AI review #2
+18
-15
@@ -97,25 +97,28 @@ export class Git {
|
||||
* @returns {{ hasConflict: boolean, files: string[] }}
|
||||
*/
|
||||
detectConflict(target, source) {
|
||||
// 建立暫時的本地 target 分支,嘗試以 --no-commit 合併 source
|
||||
const tmp = `__conflict_check_${target}`;
|
||||
// 建立暫時的本地 target 分支,嘗試以 --no-commit 合併 source。
|
||||
// 名稱帶 PID,避免並行或前次殘留造成命名衝突。
|
||||
const tmp = `__conflict_check_${target}_${process.pid}`;
|
||||
this._git(['checkout', '-B', tmp, `refs/remotes/pr/${target}`]);
|
||||
|
||||
const merge = this._git(['merge', '--no-commit', '--no-ff', `refs/remotes/pr/${source}`]);
|
||||
let hasConflict = merge.status !== 0;
|
||||
let files = [];
|
||||
try {
|
||||
const merge = this._git(['merge', '--no-commit', '--no-ff', `refs/remotes/pr/${source}`]);
|
||||
const hasConflict = merge.status !== 0;
|
||||
let files = [];
|
||||
|
||||
if (hasConflict) {
|
||||
const unmerged = this._git(['diff', '--name-only', '--diff-filter=U']);
|
||||
files = unmerged.stdout.split('\n').map((s) => s.trim()).filter(Boolean);
|
||||
if (hasConflict) {
|
||||
const unmerged = this._git(['diff', '--name-only', '--diff-filter=U']);
|
||||
files = unmerged.stdout.split('\n').map((s) => s.trim()).filter(Boolean);
|
||||
}
|
||||
|
||||
return { hasConflict, files };
|
||||
} finally {
|
||||
// 無論成敗都還原工作區並清除暫存分支
|
||||
this._git(['merge', '--abort']);
|
||||
this._git(['checkout', '--detach']);
|
||||
this._git(['branch', '-D', tmp]);
|
||||
}
|
||||
|
||||
// 還原工作區
|
||||
this._git(['merge', '--abort']);
|
||||
this._git(['checkout', '--detach']);
|
||||
this._git(['branch', '-D', tmp]);
|
||||
|
||||
return { hasConflict, files };
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user