Skip to content

feat(dag): insert a change before or after a revision (jj new -B / -A) - #185

Merged
hewigovens merged 2 commits into
mainfrom
insert-change
Aug 31, 2026
Merged

feat(dag): insert a change before or after a revision (jj new -B / -A)#185
hewigovens merged 2 commits into
mainfrom
insert-change

Conversation

@hewigovens

@hewigovens hewigovens commented Aug 30, 2026

Copy link
Copy Markdown
Owner

Closes #164

Adds the jj tutorial's edit-workflow primitive to the DAG: insert an empty change before a revision (jj new -B) or between it and its children (jj new -A), with the working copy moving onto the inserted change.

Core

  • Repo::new_change_inserted(rev, InsertPosition::{Before, After}, message) in repo/mutations.rs, built on jj-lib in a single transaction: the new commit takes the target's parents (Before) or the target (After) as parents, the displaced commits are rebased through it (a merge child keeps its other parents), descendants follow, and @ moves onto it. One op-log entry, so ⌘⇧U undoes it.
  • Gates match the menus: Before refuses an immutable target, After refuses when any child is immutable (the target itself may be immutable, e.g. inserting after root()).
  • Menu eligibility lives in the model as one record, ChangeInfo.new_change { on_top, before, after }, computed per log load in core: before needs a mutable target; after needs a child and no immutable child (from parents(immutable()) — ancestor-closed — and the view heads, so a filtered revset cannot mislead the gate); on_top hides on a discardable working copy — an empty, undescribed head with no bookmarks (local or remote), tags, or other-workspace checkouts. Both shells just render the record.
  • Mutations follow rewrites: resolving a mutation target that is hidden (e.g. a divergent working copy addressed by commit id that the pre-mutation snapshot just rewrote) now follows the operation log's predecessor records to the visible successor, erroring on a fork instead of guessing (successors are aggregated across the operation ancestry, so independent rewrites on merged operation branches also refuse). Centralized in with_resolved_commit_transaction (and rebase), so every mutation gets it.
  • Inserting before the first commit works — the new change lands directly on the root (asserted in the tests).
  • InsertPosition lives in jayjay-primitives and is bridged through UniFFI; the shared change_by_description test helper moved into jj-test.

SwiftUI

  • DAG context menu gains New change before / New change after next to New change on top, gated by new_change, with a separator after the new-change group. Selection follows the inserted change and the commit-box draft is cleared like New change on top.

GPUI (second change in the stack)

  • ChangeAction::Insert { rev, at }RepoViewModel::insert_change; the change menu gets the same two entries and gates, and the context menu gains separator items (ContextMenuItem::separator()).

Tests

  • Rust: tests/insert_change.rs (Before keeps the target's content and drops it from disk, @ is the new change, +1 op; After reparents both children and a merge child keeps its unrelated parent; has_immutable_child stays true when the revset hides the child) and both gates in mutations_immutable.rs.
  • XCUITest: InsertChangeScene (own fixture copy) covers the insert-before flow; NewChangeScene keeps the draft-clearing flow on its own fixture.
  • GPUI: change_context_action_inserts_change_before_target; the menu-label test lists both entries.

Not in this PR: drag-to-rebase drop zones between rows (Roadmap), command-palette entries, user docs (release pass).

Screenshots

DAG context menu on @ (taken before the gate polish — New change after is now hidden on childless targets like this one, and a separator follows the group):

New change before / New change after in the DAG context menu

After New change before on @: the old working copy keeps its change id on top, the inserted empty change is the new @ and is selected:

Inserted change selected beneath the previous working copy

@hewigovens
hewigovens marked this pull request as ready for review August 30, 2026 04:13
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Aug 30, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-08-31T09:59:16.191202Z 4550fac New commits
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b86121225b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread shell/mac/Sources/JayJay/Repo/DAG/DAGViewModel.swift Outdated
@hewigovens
hewigovens force-pushed the insert-change branch 2 times, most recently from 52d42cc to 9814ad9 Compare August 31, 2026 03:29

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9814ad94a2

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread shell/mac/Tests/JayJayUITests/Scenes/NewChangeScene.swift Outdated
Comment thread crates/jayjay-core/src/repo/mutations.rs Outdated
Comment thread shell/mac/Sources/JayJay/Shared/ChangeIdentity.swift Outdated
Comment thread crates/jayjay-primitives/src/change.rs Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b83c6fc6fc

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread crates/jayjay-core/src/repo/mutations.rs

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d797c3cbf3

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread crates/jayjay-core/src/repo/resolve/changes.rs
Comment thread crates/jayjay-core/src/repo/resolve/rewrites.rs Outdated
Comment thread shell/mac/Sources/JayJay/Repo/DAG/DAGView+ContextMenu.swift
Comment thread crates/jayjay-core/src/repo/mutations.rs
Adds Repo::new_change_inserted with InsertPosition::{Before, After}: the new empty change takes the target's parents (Before) or the target (After) as parents, the displaced commits are rebased through it in the same transaction, and the working copy moves onto it. Inserting before the first commit lands the new change directly on the root.

Menu eligibility is computed in core as ChangeInfo::new_change { on_top, before, after }: before needs a mutable target, after needs a child and no immutable child (from parents(immutable()) and the view heads, so filtered revsets cannot mislead the gate), and on top hides on a discardable working copy (empty, undescribed head with no local or remote bookmarks, tags, or other-workspace checkouts). Shells render the record.

Mutations follow rewrites: a hidden target (e.g. rewritten by the pre-mutation snapshot) is mapped through the operation log's predecessor records to its visible successor, refusing forks.

The DAG context menu gains New change before / New change after next to New change on top, with a separator after the group; selection follows the inserted change.

Refs #164
Adds New change before / New change after to the GPUI change menu with the same gates as the SwiftUI shell, dispatching Repo::new_change_inserted and selecting the inserted working copy. The context menu gains separator items to group the new-change actions.

Refs #164

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4550fac9de

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread agents/design.md
@hewigovens
hewigovens merged commit c0a199f into main Aug 31, 2026
5 checks passed
@hewigovens
hewigovens deleted the insert-change branch August 31, 2026 11:47
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.

Insert a change before/after a revision (jj new -B / -A)

1 participant