From 21a1870fd7bd3a251a9bdb3fea8a49eb6cdb50b1 Mon Sep 17 00:00:00 2001 From: Mika Kuns Date: Wed, 22 Apr 2026 09:29:24 +0200 Subject: [PATCH] feat(git): add MergeAbortAsync --- src/ClaudeDo.Data/Git/GitService.cs | 7 ++++++ .../Runner/GitServiceMergeTests.cs | 25 +++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/src/ClaudeDo.Data/Git/GitService.cs b/src/ClaudeDo.Data/Git/GitService.cs index d736b71..d0a27f8 100644 --- a/src/ClaudeDo.Data/Git/GitService.cs +++ b/src/ClaudeDo.Data/Git/GitService.cs @@ -191,6 +191,13 @@ public sealed class GitService return (exitCode, stderr); } + public async Task MergeAbortAsync(string repoDir, CancellationToken ct = default) + { + var (exitCode, _, stderr) = await RunGitAsync(repoDir, ["merge", "--abort"], ct); + if (exitCode != 0) + throw new InvalidOperationException($"git merge --abort failed (exit {exitCode}): {stderr}"); + } + public async Task MergeFfOnlyAsync(string repoDir, string branchName, CancellationToken ct = default) { var (exitCode, _, stderr) = await RunGitAsync(repoDir, ["merge", "--ff-only", branchName], ct); diff --git a/tests/ClaudeDo.Worker.Tests/Runner/GitServiceMergeTests.cs b/tests/ClaudeDo.Worker.Tests/Runner/GitServiceMergeTests.cs index bce82ed..21939ea 100644 --- a/tests/ClaudeDo.Worker.Tests/Runner/GitServiceMergeTests.cs +++ b/tests/ClaudeDo.Worker.Tests/Runner/GitServiceMergeTests.cs @@ -129,4 +129,29 @@ public class GitServiceMergeTests : IDisposable Assert.NotEqual(0, exitCode); } + + [Fact] + public async Task MergeAbortAsync_AfterConflict_ClearsMergeState() + { + if (!GitRepoFixture.IsGitAvailable()) return; + var repo = NewRepo(); + + GitRepoFixture.RunGit(repo.RepoDir, "checkout", "-b", "feature/abort"); + File.WriteAllText(Path.Combine(repo.RepoDir, "README.md"), "# feat side\n"); + GitRepoFixture.RunGit(repo.RepoDir, "add", "-A"); + GitRepoFixture.RunGit(repo.RepoDir, "commit", "-m", "edit"); + + try { GitRepoFixture.RunGit(repo.RepoDir, "checkout", "main"); } + catch { GitRepoFixture.RunGit(repo.RepoDir, "checkout", "master"); } + File.WriteAllText(Path.Combine(repo.RepoDir, "README.md"), "# main side\n"); + GitRepoFixture.RunGit(repo.RepoDir, "add", "-A"); + GitRepoFixture.RunGit(repo.RepoDir, "commit", "-m", "edit"); + + var git = new GitService(); + await git.MergeNoFfAsync(repo.RepoDir, "feature/abort", "merge"); // will conflict + + Assert.True(await git.IsMidMergeAsync(repo.RepoDir)); + await git.MergeAbortAsync(repo.RepoDir); + Assert.False(await git.IsMidMergeAsync(repo.RepoDir)); + } }