fix(git): 衝突偵測暫存分支加 PID 並以 finally 確保清理

This commit is contained in:
Jeffery
2026-06-26 14:09:13 +08:00
parent 32153b7bd5
commit f7e6f1c64e
+9 -6
View File
@@ -97,12 +97,14 @@ export class Git {
* @returns {{ hasConflict: boolean, files: string[] }} * @returns {{ hasConflict: boolean, files: string[] }}
*/ */
detectConflict(target, source) { detectConflict(target, source) {
// 建立暫時的本地 target 分支,嘗試以 --no-commit 合併 source // 建立暫時的本地 target 分支,嘗試以 --no-commit 合併 source
const tmp = `__conflict_check_${target}`; // 名稱帶 PID,避免並行或前次殘留造成命名衝突。
const tmp = `__conflict_check_${target}_${process.pid}`;
this._git(['checkout', '-B', tmp, `refs/remotes/pr/${target}`]); this._git(['checkout', '-B', tmp, `refs/remotes/pr/${target}`]);
try {
const merge = this._git(['merge', '--no-commit', '--no-ff', `refs/remotes/pr/${source}`]); const merge = this._git(['merge', '--no-commit', '--no-ff', `refs/remotes/pr/${source}`]);
let hasConflict = merge.status !== 0; const hasConflict = merge.status !== 0;
let files = []; let files = [];
if (hasConflict) { if (hasConflict) {
@@ -110,12 +112,13 @@ export class Git {
files = unmerged.stdout.split('\n').map((s) => s.trim()).filter(Boolean); files = unmerged.stdout.split('\n').map((s) => s.trim()).filter(Boolean);
} }
// 還原工作區 return { hasConflict, files };
} finally {
// 無論成敗都還原工作區並清除暫存分支
this._git(['merge', '--abort']); this._git(['merge', '--abort']);
this._git(['checkout', '--detach']); this._git(['checkout', '--detach']);
this._git(['branch', '-D', tmp]); this._git(['branch', '-D', tmp]);
}
return { hasConflict, files };
} }
/** /**