[patch] Wire up Pull and stop advertising unimplemented Commit and Push - #393
Conversation
The repository detail panel drew three enabled buttons that did nothing when clicked. Because they gave no indication of being unfinished, clicking one looked like a silent failure rather than absent functionality. Pull is now implemented. The TODO asked for a check for uncommitted changes before pulling, and GitCli.HasUncommittedChanges already existed to answer it, so PullRepoConfirmingUncommittedChanges pulls straight away on a clean tree and otherwise asks first, offering "Pull Anyway" and "Cancel". This is a warning rather than a safety mechanism, and deliberately so. PullRepo already passes --ff-only, which refuses to advance a divergent branch, but that protects the history and says nothing about the working tree: a pull across uncommitted changes can still fail partway, or succeed and leave the user unsure which changes were theirs. Proceeding stays available because there are legitimate reasons to pull with a dirty tree. Commit and Push are disabled rather than implemented, with a shared "Not implemented yet." tooltip. They stay visible so the layout is unchanged. Both need policy decisions rather than plumbing -- what Commit stages, whether the user sees the file list first, which remote and branch Push targets, and how a rejected push is surfaced. PullRepo's own comment records that unattended git operations swallowing their failures already caused a bad bug in this file, so guessing at those answers is the wrong move. Raised as #392 with the details. Uses ImGui.BeginDisabled/EndDisabled rather than ImGuiWidgets.ScopedDisable, which is not nested under ImGuiWidgets in the referenced package version. The hover states are captured per-button before EndDisabled, since IsItemHovered only ever refers to the item immediately submitted. Fixes #391 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DTHNXgSNEHUSQ5KMLgivno
SonarCloud failed the quality gate on the previous commit with 0% coverage on new code. That commit was almost entirely ImGui drawing, which needs a live context and a display, but it did contain one rule: whether clicking Pull runs immediately or asks first. Extracts that rule into DecidePull, which returns a PullDecision rather than branching inline, and covers it with PullDecisionTests against real throwaway repositories the way GitCliTests already does. Getting it wrong is user-visible in both directions: nagging on a clean tree makes the button annoying, and staying silent on a dirty one is the case the confirmation exists for. Covered: a clean tree pulls without asking; a modified tracked file, an untracked file and a staged-but-uncommitted change each ask first; and committing the change stops the confirmation, so the decision tracks the tree's current state rather than merely that it was ever dirty. Verified by mutation: inverting the decision fails 5 of the 12 tests. This does not make the whole diff reach the 80% new-code coverage threshold -- the remainder is ImGui drawing with no headless harness in this repository to exercise it. Noted on the pull request rather than left silent. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DTHNXgSNEHUSQ5KMLgivno
|
SonarCloud is red and I've stopped pushing at it. Here's exactly what's blocking. Everything else is green — build, tests on Windows and Ubuntu, CodeQL, CodeQL Actions analysis, GitHub Advanced Security. The one failing condition
It was 0.0%. I extracted Why it will not reach 80%The rest of the diff is ImGui drawing:
All of it needs a live ImGui context, a window and a display. This repository has no headless UI test harness, so none of those lines is reachable from a test. The 80% new-code threshold is therefore unreachable for any predominantly-UI change here, not just this one. I'd rather say that than keep pushing speculative commits at the number. What I'd need to actually clear itOne of these, and each is a decision rather than a detail:
Happy to do (1) as its own issue if you want it — say the word. I have not opened one, since it is a big enough commitment that it should be your call. Generated by Claude Code |
github-code-quality flagged all six Path.Combine calls in the new test file: "Call to 'System.IO.Path.Combine' may silently drop its earlier arguments." Path.Combine returns its later argument verbatim when that argument is rooted, discarding everything before it. Every second argument here is a literal file name or a generated directory name, so none of them can be rooted and the current behaviour is correct -- but Path.Join concatenates unconditionally and so cannot exhibit the pattern at all, which is the safer construct to reach for by default. The results are identical for these inputs; Path.GetTempPath's trailing separator is handled by both. Left the pre-existing Path.Combine calls in GitCliTests alone: they are not part of this change, and widening the diff to satisfy a rule the bot did not raise against them belongs in its own commit. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DTHNXgSNEHUSQ5KMLgivno
|


Fixes #391. Splits the remaining functionality out to #392.
The problem
The repository detail panel drew three enabled buttons that did nothing when clicked. Nothing indicated they were unfinished, so clicking one looked like a silent failure rather than absent functionality.
Pull is now implemented
The TODO asked for a check for uncommitted changes before pulling — and
GitCli.HasUncommittedChangesalready existed to answer it, so this was mostly a wiring job.PullRepoConfirmingUncommittedChangespulls straight away on a clean tree, and otherwise asks first with Pull Anyway / Cancel.This is a warning, not a safety mechanism, and deliberately so.
PullRepoalready passes--ff-only, so a divergent branch is refused rather than merged — but that protects the history and says nothing about the working tree. A pull across uncommitted changes can still fail partway, or succeed and leave the user unsure which changes were theirs. Proceeding stays available because there are legitimate reasons to pull with a dirty tree.Commit and Push are disabled, not implemented
Both stay visible so the layout is unchanged, but are disabled with a shared "Not implemented yet." tooltip.
I stopped short of implementing them on purpose. Neither is blocked on plumbing —
GitCli.RunIn,ImGuiPopups.InputStringandQueueGitLogare all there — they are blocked on policy decisions that are yours, not mine:git add -Asweeps up untracked files, which is a surprising thing to do to someone's working tree from a background click.PullRepo's own comment records that unattended git operations swallowing their failures already caused a bad bug in this file — a merge committed unattended, the conflict exception swallowed, the working tree left mid-conflict with nothing said. Guessing at the answers above would be repeating that mistake. #392 carries the full detail and the suggested shape.If you would rather I just implement them with a particular set of answers, say which and I will.
Verification
dotnet testpasses 7/7 (5 succeeded, 2 self-skipped —git-lfsis not installed in this sandbox, which is the suite's existingAssert.Inconclusivebehaviour, not a regression).GitCli.HasUncommittedChanges, which the new path depends on, is already covered byUncommittedChangesAreDetectedfor both the clean and dirty cases.Implementation notes
ImGui.BeginDisabled/EndDisabledrather thanImGuiWidgets.ScopedDisable— the latter is not nested underImGuiWidgetsin the referenced package version and fails to compile asImGuiWidgets.ScopedDisable. The ImGui pair has no package-version risk.EndDisabled, becauseIsItemHoveredonly ever refers to the item immediately submitted. Reading it once after both buttons would have reported only Push.Caveat
This is a GUI change and I have no display here, so the popup and the disabled/tooltip behaviour are unverified at runtime — they are verified only to compile and to follow the existing
PopupSetDevDirectory/PopupAddNewGitHubOwnerpattern (field,ShowIfOpen()in the render loop,Open(...)at the call site). Worth a quick manual click-through before merging. I could not run the repo's own analyzers either: this sandbox's SDK is 10.0.111 (Roslyn5.0.0.0) andktsu.Sdk.Analyzers2.28.0 requires5.9.0.0, so CSC refuses it withCS9057.Generated by Claude Code