Skip to content

fix(tasks): prevent task rename from closing pull requests#2280

Merged
jschwxrz merged 2 commits into
mainfrom
jona/eng-1431-renaming-an-issue-with-an-open-pr-closes-the-pr
May 29, 2026
Merged

fix(tasks): prevent task rename from closing pull requests#2280
jschwxrz merged 2 commits into
mainfrom
jona/eng-1431-renaming-an-issue-with-an-open-pr-closes-the-pr

Conversation

@jschwxrz
Copy link
Copy Markdown
Collaborator

  • keep branch rename local-only and remove remote branch delete and push behavior
  • add an optional rename branch checkbox to RenameTaskModal
  • disable branch rename for linear-linked tasks, open pull requests and shared branches
  • update renameTask to rename task metadata by default and only rename the branch when requested
  • add backend guards so stale callers cannot rename protected branches

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented May 29, 2026

Greptile Summary

This PR prevents task renames from inadvertently closing pull requests by making branch rename opt-in (new "Rename local branch" checkbox) and keeping all git operations local-only (no remote delete/push). Backend guards in renameTask.ts enforce the same constraints the UI enforces, so stale callers cannot rename a Linear-managed, shared, or PR-backed branch.

  • GitService.renameBranch now only issues git branch -m — remote tracking-ref deletion and git push -u are removed entirely, and the return type is narrowed to Result<void>.
  • renameTask gains an options.renameBranch flag; when false (default), only the DB name record is updated and no git command runs. When true, three sequential guards (linked-issue provider, sibling-task count, open-PR query) must all pass before the local rename executes.
  • The task query is now AND-scoped by both taskId and projectId, closing a pre-existing cross-project access gap in the original implementation.

Confidence Score: 5/5

Safe to merge — the core rename flow is correctly guarded at both frontend and backend, and the only finding is a UI state edge-case that does not affect data integrity.

The structural changes are well-contained: git operations are reduced (no remote side-effects), the DB query is tightened (project-scoped), and three independent backend guards prevent the rename when conditions warrant. The test suite covers every guard path. The one finding is a useState that does not auto-reset when the MobX-derived canRenameLocalBranch flag oscillates, which could leave the checkbox pre-armed after conditions temporarily clear, but the submission guard renameBranch && canRenameLocalBranch prevents any incorrect branch rename from reaching the backend.

No files require special attention; the suggestion on rename-task-modal.tsx is minor UX hardening.

Important Files Changed

Filename Overview
src/main/core/tasks/operations/renameTask.ts Core logic refactored to opt-in branch rename with backend guards (linear, siblings, open PRs); task query now correctly scoped by projectId; renameBranch:true is silently no-op'd when sourceBranch is null or equals the task branch
src/renderer/features/tasks/rename-task-modal.tsx New Rename local branch checkbox added with MobX-derived guards; renameBranch state is not reset to false when canRenameLocalBranch transitions to false, leaving the checkbox potentially re-armed if conditions oscillate
src/main/core/git/impl/git-service.ts renameBranch simplified to local-only git branch -m; remote delete and push removed; return type narrowed to Result
src/renderer/features/tasks/stores/task-store.ts rename() now accepts RenameTaskOptions and propagates it to the RPC; MobX runInAction now also syncs taskBranch from the server response, correcting previously stale local state
src/main/core/tasks/operations/renameTask.test.ts New test file covering all guard paths: metadata-only rename, branch rename, open-PR block, Linear-linked block, shared-branch block, task-not-found

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[User submits RenameTaskModal] --> B{renameBranch &&
canRenameLocalBranch?}
    B -- No --> C[renameTask with renameBranch: false]
    B -- Yes --> D[renameTask with renameBranch: true]
    C --> E[DB: update name only]
    E --> F[Return ok task]
    D --> G{linkedIssue.provider
=== 'linear'?}
    G -- Yes --> ERR1[err: branch-managed-by-linked-issue]
    G -- No --> H{sourceBranch exists &&
taskBranch !== sourceBranch?}
    H -- No --> E
    H -- Yes --> I{sibling tasks share
same branch?}
    I -- Yes --> ERR2[err: branch-has-siblings]
    I -- No --> J{remoteUrls in
projectRemotes?}
    J -- Yes --> K{open PR for
this branch?}
    K -- Yes --> ERR3[err: branch-has-open-pr]
    K -- No --> L[git branch -m old new]
    J -- No --> L
    L --> M{rename
succeeded?}
    M -- No --> ERR4[err: branch-already-exists
or branch-rename-failed]
    M -- Yes --> N[DB: update name + taskBranch]
    N --> F
Loading
Prompt To Fix All With AI
Fix the following 1 code review issue. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 1
src/renderer/features/tasks/rename-task-modal.tsx:62
The `renameBranch` checkbox state is never reset when `canRenameLocalBranch` transitions to `false`. Because this modal is an MobX `observer`, a background PR sync that opens a PR will flip `canRenameLocalBranch` to `false` while the modal is open — disabling the checkbox but leaving it visually checked. If the PR later closes and `canRenameLocalBranch` flips back to `true`, the checkbox is pre-armed for a branch rename the user never re-confirmed. Adding a `useEffect` that resets the state when the flag turns false prevents this.

```suggestion
  const [renameBranch, setRenameBranch] = useState(false);
  useEffect(() => {
    if (!canRenameLocalBranch) setRenameBranch(false);
  }, [canRenameLocalBranch]);
```

Reviews (2): Last reviewed commit: "feat(tasks): optionally rename task bran..." | Re-trigger Greptile

Comment thread src/main/core/tasks/operations/renameTask.ts
Comment thread src/renderer/features/tasks/rename-task-modal.tsx
@jschwxrz jschwxrz force-pushed the jona/eng-1431-renaming-an-issue-with-an-open-pr-closes-the-pr branch from 4d25037 to c22e7a7 Compare May 29, 2026 00:45
@jschwxrz
Copy link
Copy Markdown
Collaborator Author

@greptileai

@jschwxrz jschwxrz merged commit b334112 into main May 29, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant