Repository navigation
Offer a force push with lease when a push is rejected - #749
Conversation
f60e9ee to
c5bdef3
Compare
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
A missing SHA snapshot permits an unsafe implicit lease, while synchronous lookup and inherited test configuration need correction.
Review effort: Balanced
Findings: 1
Open (3)
What changed in this PR
Adds an in-app force-with-lease retry for rejected local-branch pushes in GitX.
Changes:
- Adds a suppressible confirmation with Cancel as the default.
- Captures the remote-tracking SHA before pushing and adds lease-aware retries.
- Adds rejection-detection and repository integration tests.
| File | Description |
|---|---|
| GitXTests/PBGitRepositoryForcePushTests.m | Tests rejection detection and lease behavior. |
| GitX.xcodeproj/project.pbxproj | Registers the new tests. |
| Classes/git/PBGitRepository.m | Implements SHA lookup, lease arguments, and rejection detection. |
| Classes/git/PBGitRepository.h | Exposes lease-related repository methods. |
| Classes/Controllers/PBGitWindowController.m | Adds confirmation and retry handling. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| { | ||
| NSTask *task = [[NSTask alloc] init]; | ||
| task.executableURL = [NSURL fileURLWithPath:@"/usr/bin/git"]; | ||
| task.arguments = [@[ @"-c", @"user.name=Test", @"-c", @"[email protected]" ] arrayByAddingObjectsFromArray:arguments]; |
|
Does the copilot suggestions make sense to you ? |
Stop sending users to the terminal after a rebase or amend: when git rejects a push as non-fast-forward, offer to retry it with a lease. - Show "Force Push (with Lease)" or "Cancel" after such a rejection. Cancel is the default button. - Reuse the existing dialog suppression, so ticking "do not show again" retries without asking and Reset Warnings brings the alert back. - Pass the remote-tracking SHA seen before the first attempt as the expected value, so a fetch while the alert is open cannot weaken the lease. Read it on the push thread, not the main thread. - Offer it for local branches with a known remote SHA only, and not after a stale lease.
c5bdef3 to
54cbdf2
Compare
|
Yes, all three make sense and I've fixed them (force-pushed into the same commit). (1) The lease is now always explicit, so a fetch while the alert is open can't loosen it, and the alert isn't offered when GitX has no remote-tracking SHA. (2) The SHA lookup now runs in the background push block instead of on the main thread. (3) The test fixtures now isolate git config like the other suites. Added a test for the no-SHA case. |
| { | ||
| NSAlert *alert = [[NSAlert alloc] init]; | ||
| alert.messageText = [NSString stringWithFormat:NSLocalizedString(@"Push of branch “%@” was rejected", @"Force push alert - message"), branchRef.shortName]; | ||
| alert.informativeText = NSLocalizedString(@"The remote has commits this branch does not have. A force push replaces them, but only if the remote is still where GitX last saw it (git push --force-with-lease).", @"Force push alert - informative text"); |
There was a problem hiding this comment.
--force-with-lease is a nice feature


Stop sending users to the terminal after a rebase or amend: when git rejects a push as non-fast-forward, offer to retry it with
--force-with-lease.(non-fast-forward)or(fetch first)rejection. Cancel is the default button.Force Push With Lease): ticking the checkbox retries without asking, and Reset Warnings in the preferences brings the alert back.--force-with-lease=<branch>:<sha>, read on the push thread), so a fetch while the alert is open cannot weaken the lease.(stale info)refusal of the lease itself.No new menu entries. Other clients were compared first: Tower has menu entries, GitKraken a banner after a diverged push; this follows the latter.
Test plan
PBGitRepositoryForcePushTests: rejection detection, plus two tests against real local repos (rewritten branch is rejected then forced through; the lease refuses after someone else pushed). All 8 pass; the fixtures isolate git config like the other suites.