Ubisam-MergeTool/src/MergeHub/Services/MergeConflictRecord.cs
ksj09406 a9cbb50884 11차 F-8: 저장한 뒤에도 되돌리기 · 푼 파일을 다시 충돌로
- 저장할 것 있음을 되돌리기 목록이 아니라 "마지막 저장과 다른가" 로(SaveBaseline). 저장 · 저장 후 커밋은 목록을 둠
- 줄을 다시 세울 때(커밋 뒤 새 HEAD · 규칙 바꾸기 · 친 뒤 재정렬) 이력을 글 단위로 옮겨 지킴, 친 것도 한 걸음
- 전체 되돌리기는 파일을 연 시점, 저장했으면 화면만
- Git 탭 "이번 병합에서 푼 파일" + [다시 충돌로] (이 단추만 git checkout -m, 해결 기록에서 뺌)

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-22 20:55:51 +09:00

46 lines
2.7 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
namespace MergeHub.Services
{
/// <summary>
/// 병합 때 처음 충돌 목록을 적어 두는 <c>.git/MERGEHUB_CONFLICTS</c> 를 치울지 가른다(7차 B-1).
///
/// 이 파일은 "푼 것 M개 (M/전체)" 를 세려고 둔다(6차 C-1). 첫 줄이 그때의 MERGE_HEAD 라 다른 병합과 섞이지는 않지만,
/// 지우는 곳이 없어 병합 커밋 · 작업 취소 · 터미널에서 끝낸 병합 뒤에도 남의 <c>.git</c> 에 남았다.
/// 판단만 여기 두어 저장소 없이 검사한다. 지우는 것은 <see cref="GitService"/> 가 한다.
/// </summary>
public static class MergeConflictRecord
{
/// <summary>
/// 적어 둔 것이 이제 쓸모없는지. 병합 중이 아니면(MERGE_HEAD 없음) 쓸모없다.
/// 병합 중이어도 첫 줄이 지금 MERGE_HEAD 와 다르면 다른 병합의 것이라 쓸모없다.
/// </summary>
/// <param name="mergeHeadSha">지금 MERGE_HEAD. 병합 중이 아니면 null.</param>
/// <param name="recordFirstLine">적어 둔 파일의 첫 줄. 빈 파일이면 null.</param>
public static bool IsStale(string? mergeHeadSha, string? recordFirstLine)
{
if (string.IsNullOrWhiteSpace(mergeHeadSha)) return true;
if (string.IsNullOrWhiteSpace(recordFirstLine)) return true;
return !string.Equals(recordFirstLine!.Trim(), mergeHeadSha!.Trim(), StringComparison.OrdinalIgnoreCase);
}
/// <summary>
/// [다시 충돌로] 로 되돌릴 수 있는 파일(11차 F-8) - 이번 병합에서 처음 충돌 났고(<paramref name="initial"/>),
/// 지금은 충돌이 아니며(<paramref name="current"/> 에 없음), git 이 해결 전 세 벌을 기억하는(<paramref name="resolveUndo"/>, REUC) 파일.
/// REUC 만 보면 안 된다 - libgit2 는 저절로 병합된 파일도 거기 남긴다(6차 C-1). 처음 목록 차례를 지킨다.
/// </summary>
public static IReadOnlyList<string> Resolved(IEnumerable<string> initial, IEnumerable<string> current, IEnumerable<string> resolveUndo)
{
static string N(string p) => (p ?? string.Empty).Trim().Replace('\\', '/');
var now = new HashSet<string>(current.Select(N), StringComparer.Ordinal);
var undo = new HashSet<string>(resolveUndo.Select(N), StringComparer.Ordinal);
var seen = new HashSet<string>(StringComparer.Ordinal);
return initial.Select(N)
.Where(p => p.Length > 0 && !now.Contains(p) && undo.Contains(p) && seen.Add(p))
.ToList();
}
}
}