feat(git): add non-destructive merge-tree conflict probe

This commit is contained in:
mika kuns
2026-06-04 23:18:54 +02:00
parent 82390047d2
commit 4098f7f341
2 changed files with 109 additions and 0 deletions

View File

@@ -0,0 +1,64 @@
using ClaudeDo.Data.Git;
using ClaudeDo.Worker.Tests.Infrastructure;
namespace ClaudeDo.Worker.Tests.Runner;
public class GitServicePreviewMergeTests : IDisposable
{
private readonly List<GitRepoFixture> _repos = new();
private GitRepoFixture NewRepo() { var r = new GitRepoFixture(); _repos.Add(r); return r; }
public void Dispose() { foreach (var r in _repos) try { r.Dispose(); } catch { } }
[Fact]
public async Task PreviewMergeAsync_NonConflicting_ReportsCleanWithChangedCount()
{
if (!GitRepoFixture.IsGitAvailable()) return;
var repo = NewRepo();
var git = new GitService();
var baseBranch = await git.GetCurrentBranchAsync(repo.RepoDir);
GitRepoFixture.RunGit(repo.RepoDir, "checkout", "-b", "feature");
File.WriteAllText(Path.Combine(repo.RepoDir, "newfile.txt"), "x\n");
GitRepoFixture.RunGit(repo.RepoDir, "add", "-A");
GitRepoFixture.RunGit(repo.RepoDir, "commit", "-m", "feat");
GitRepoFixture.RunGit(repo.RepoDir, "checkout", baseBranch);
var preview = await git.PreviewMergeAsync(repo.RepoDir, baseBranch, "feature", CancellationToken.None);
Assert.True(preview.Supported);
Assert.True(preview.Clean);
Assert.Empty(preview.ConflictFiles);
var count = await git.CountChangedFilesAsync(repo.RepoDir, baseBranch, "feature", CancellationToken.None);
Assert.Equal(1, count);
}
[Fact]
public async Task PreviewMergeAsync_Conflicting_ReportsFilesAndDoesNotMutateTree()
{
if (!GitRepoFixture.IsGitAvailable()) return;
var repo = NewRepo();
var git = new GitService();
var baseBranch = await git.GetCurrentBranchAsync(repo.RepoDir);
GitRepoFixture.RunGit(repo.RepoDir, "checkout", "-b", "feature");
File.WriteAllText(Path.Combine(repo.RepoDir, "README.md"), "# from feature\n");
GitRepoFixture.RunGit(repo.RepoDir, "add", "-A");
GitRepoFixture.RunGit(repo.RepoDir, "commit", "-m", "feat readme");
GitRepoFixture.RunGit(repo.RepoDir, "checkout", baseBranch);
File.WriteAllText(Path.Combine(repo.RepoDir, "README.md"), "# from base\n");
GitRepoFixture.RunGit(repo.RepoDir, "add", "-A");
GitRepoFixture.RunGit(repo.RepoDir, "commit", "-m", "base readme");
var headBefore = GitRepoFixture.RunGit(repo.RepoDir, "rev-parse", "HEAD").Trim();
var preview = await git.PreviewMergeAsync(repo.RepoDir, baseBranch, "feature", CancellationToken.None);
Assert.True(preview.Supported);
Assert.False(preview.Clean);
Assert.Contains("README.md", preview.ConflictFiles);
Assert.Equal(headBefore, GitRepoFixture.RunGit(repo.RepoDir, "rev-parse", "HEAD").Trim());
Assert.False(await git.IsMidMergeAsync(repo.RepoDir));
}
}