chore(claude-do): merge feat(worktrees): warn about git worktrees ClaudeDo doesn't k
ClaudeDo-Task: 765fed13-db66-44e4-9285-c4b2d415b443
This commit is contained in:
@@ -338,6 +338,38 @@ public sealed class GitService
|
||||
return paths;
|
||||
}
|
||||
|
||||
/// <summary>All git-registered worktrees for <paramref name="repoDir"/>, with their branch (short name, null if detached).</summary>
|
||||
public async Task<List<(string Path, string? Branch)>> ListWorktreesAsync(string repoDir, CancellationToken ct = default)
|
||||
{
|
||||
var (exitCode, stdout, _) = await RunGitAsync(repoDir, ["worktree", "list", "--porcelain"], ct);
|
||||
if (exitCode != 0) return new();
|
||||
|
||||
var result = new List<(string Path, string? Branch)>();
|
||||
string? currentPath = null;
|
||||
string? currentBranch = null;
|
||||
foreach (var raw in stdout.Split('\n'))
|
||||
{
|
||||
var line = raw.TrimEnd('\r');
|
||||
if (line.StartsWith("worktree ", StringComparison.Ordinal))
|
||||
{
|
||||
currentPath = line["worktree ".Length..].Trim();
|
||||
}
|
||||
else if (line.StartsWith("branch ", StringComparison.Ordinal))
|
||||
{
|
||||
var b = line["branch ".Length..].Trim();
|
||||
currentBranch = b.StartsWith("refs/heads/", StringComparison.Ordinal) ? b["refs/heads/".Length..] : b;
|
||||
}
|
||||
else if (string.IsNullOrWhiteSpace(line))
|
||||
{
|
||||
if (currentPath is not null) result.Add((currentPath, currentBranch));
|
||||
currentPath = null;
|
||||
currentBranch = null;
|
||||
}
|
||||
}
|
||||
if (currentPath is not null) result.Add((currentPath, currentBranch));
|
||||
return result;
|
||||
}
|
||||
|
||||
public async Task WorktreePruneAsync(string repoDir, CancellationToken ct = default)
|
||||
{
|
||||
var (exitCode, _, stderr) = await RunGitAsync(repoDir, ["worktree", "prune"], ct);
|
||||
|
||||
Reference in New Issue
Block a user