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

This commit is contained in:
Jeffery
2026-06-26 14:09:13 +08:00
parent 32153b7bd5
commit f7e6f1c64e
+18 -15
View File
@@ -97,25 +97,28 @@ 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}`]);
const merge = this._git(['merge', '--no-commit', '--no-ff', `refs/remotes/pr/${source}`]); try {
let hasConflict = merge.status !== 0; const merge = this._git(['merge', '--no-commit', '--no-ff', `refs/remotes/pr/${source}`]);
let files = []; const hasConflict = merge.status !== 0;
let files = [];
if (hasConflict) { if (hasConflict) {
const unmerged = this._git(['diff', '--name-only', '--diff-filter=U']); const unmerged = this._git(['diff', '--name-only', '--diff-filter=U']);
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(['checkout', '--detach']);
this._git(['branch', '-D', tmp]);
} }
// 還原工作區
this._git(['merge', '--abort']);
this._git(['checkout', '--detach']);
this._git(['branch', '-D', tmp]);
return { hasConflict, files };
} }
/** /**