fix(git): 衝突偵測暫存分支加 PID 並以 finally 確保清理
This commit is contained in:
+18
-15
@@ -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 };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user