Oxen icon indicating copy to clipboard operation
Oxen copied to clipboard

Qol/force checkout

Open rpschoenburg opened this issue 2 months ago • 1 comments

Summary by CodeRabbit

  • New Features

    • Added a --force / -f option to checkout (local and remote) to allow overwriting working-directory changes and force branch/commit checkouts; remote mode updates workspace state on success.
  • Bug Fixes

    • Fixed Windows glob case-sensitivity for file pattern matching.
    • Improved error propagation for revision-not-found and other unexpected errors.
  • Tests

    • Added tests for force checkout behavior and non-destructive checkout scenarios.
  • Improvements

    • Refined checkout logging and diagnostic messages for clarity.

rpschoenburg avatar Oct 22 '25 18:10 rpschoenburg

Walkthrough

Adds a --force (-f) option to checkout at CLI, repository, and core layers; introduces force_checkout execution paths and threads a force_checkout: bool flag through checkout/traversal APIs to allow overwriting local changes. Also fixes Windows glob case-sensitivity and replaces some prints with debug logs.

Changes

Cohort / File(s) Summary
CLI checkout commands
oxen-rust/src/cli/src/cmd/checkout.rs, oxen-rust/src/cli/src/cmd/remote_mode/checkout.rs
Add --force/-f flag; CLI reads flag and routes named checkouts to force_checkout when set; logging adjusted to use debug and flag propagated.
Repository checkout API & tests
oxen-rust/src/lib/src/repositories/checkout.rs, oxen-rust/src/lib/src/repositories/remote_mode/checkout.rs
Add public force_checkout functions; delegate to core checkout with force semantics; update remote-mode workspace handling and error messaging; tests added/updated for force vs non-force behavior.
Repository branches & plumbing
oxen-rust/src/lib/src/repositories/branches.rs, oxen-rust/src/lib/src/repositories/load.rs
Thread force_checkout: bool through branch/commit checkout helpers and set_working_repo_to_commit; add force_* helpers; update call sites (load passes false).
Core checkout traversal
oxen-rust/src/lib/src/core/v_latest/branches.rs
Add force_checkout: bool parameter to checkout, checkout_subtrees, checkout_commit, set_working_repo_to_commit and recursive helpers; when true, modified files are queued/restored to allow overwrite instead of raising cannot-overwrite errors.
Windows glob fix
oxen-rust/src/lib/src/core/v_latest/add.rs
Replace glob() with glob_with() using case-insensitive MatchOptions on Windows.
Minor maintenance & tests
oxen-rust/src/lib/src/repositories/merge.rs, oxen-rust/src/lib/src/repositories/push.rs
Minor whitespace/comment alignment in merge tests; added debug/println in push test and adjusted assertion message formatting.

Sequence Diagram(s)

sequenceDiagram
    participant CLI as CLI
    participant Repo as repositories::checkout
    participant Branch as repositories::branches
    participant Core as core::v_latest::branches

    rect rgb(214,234,248)
      Note over CLI,Repo: Default (no --force)
      CLI->>Repo: checkout(name)
      Repo->>Branch: checkout_branch_from_commit(..., force_checkout=false)
      Branch->>Core: checkout(..., force_checkout=false)
      Core->>Core: r_restore_missing_or_modified_files(force=false)
      Note right of Core: Modified files → cannot_overwrite_entries → error
    end

    rect rgb(250,219,216)
      Note over CLI,Repo: Forced (--force)
      CLI->>Repo: force_checkout(name)
      Repo->>Branch: force_checkout_* (…, force_checkout=true)
      Branch->>Core: checkout_commit/checkout(..., force_checkout=true)
      Core->>Core: r_restore_missing_or_modified_files(force=true)
      Note right of Core: Modified files → queued for restoration → overwrite local
    end

    rect rgb(252,243,207)
      Note over Repo: On success update HEAD and remote-mode workspace/save
    end

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

  • Pay special attention to:
    • core/v_latest/branches.rs — recursive traversal, conflict handling, and correct propagation of force_checkout.
    • repositories/checkout.rs & repositories/remote_mode/checkout.rs — new force_checkout paths and workspace updates.
    • Call-site updates (repositories → core) to ensure boolean passed consistently and non-forced flows unchanged.

Possibly related PRs

  • Oxen-AI/Oxen#565 — Refactors modified-file detection used by r_remove_if_not_in_target / r_restore_missing_or_modified_files; strongly related to force handling changes.
  • Oxen-AI/Oxen#524 — Touches the same checkout functions and introduces overwrite/conflict handling changes; closely connected to this PR.
  • Oxen-AI/Oxen#660 — Modifies remote-mode checkout logic that this PR extends with a force_checkout path.

Suggested reviewers

  • jcelliott
  • subygan

Poem

🐰 I hopped through trees of code at night,
Gave checkout a flag to make things right.
Force clears the path, restores with cheer,
Globs on Windows now see far and near.
Rabbit hums: a clean branch — hoppity-hop here!

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 74.14% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Title check ❓ Inconclusive The title 'Qol/force checkout' is vague and generic. While it references 'force checkout,' it uses the non-descriptive 'Qol' prefix that doesn't clearly convey what quality-of-life improvement is being made or the specific nature of the feature. Consider a more specific title like 'Add --force flag to checkout command to overwrite local changes' that clearly describes the feature being added rather than using shorthand like 'Qol/force checkout'.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing touches
  • [ ] 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • [ ] Create PR with unit tests
  • [ ] Post copyable unit tests in a comment
  • [ ] Commit unit tests in branch qol/force_checkout

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ae12dfddc60854f91281a5e528669d7d4283fd8c and 5f0df94bdd3cb4eb42c468d381659e769853938e.

📒 Files selected for processing (4)
  • oxen-rust/src/lib/src/core/v_latest/branches.rs (21 hunks)
  • oxen-rust/src/lib/src/repositories/checkout.rs (4 hunks)
  • oxen-rust/src/lib/src/repositories/push.rs (2 hunks)
  • oxen-rust/src/lib/src/repositories/remote_mode/checkout.rs (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • oxen-rust/src/lib/src/repositories/push.rs
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-09-18T19:11:42.443Z
Learnt from: Lilianxr
Repo: Oxen-AI/Oxen PR: 146
File: oxen-rust/src/benches/oxen/download.rs:176-179
Timestamp: 2025-09-18T19:11:42.443Z
Learning: In oxen-rust/src/benches/oxen/download.rs, the setup_repo_for_download_benchmark function always stages files under a "files" directory structure in the repository, regardless of whether data_path is provided or not. The hardcoded Path::new("files") in the repositories::download call is correct because of this consistent setup.

Applied to files:

  • oxen-rust/src/lib/src/repositories/checkout.rs
🧬 Code graph analysis (3)
oxen-rust/src/lib/src/repositories/checkout.rs (7)
oxen-rust/src/lib/src/repositories/remote_mode/checkout.rs (3)
  • force_checkout (35-56)
  • create_checkout (58-85)
  • checkout (12-33)
oxen-rust/src/cli/src/cmd/checkout.rs (3)
  • force_checkout (106-126)
  • checkout (88-104)
  • name (13-15)
oxen-rust/src/lib/src/repositories/branches.rs (9)
  • exists (59-64)
  • is_checked_out (168-177)
  • get_by_name (27-29)
  • force_checkout_subtrees_to_commit (353-368)
  • set_head (394-400)
  • force_checkout_commit_from_commit (383-392)
  • update (116-132)
  • current_branch (67-69)
  • create_checkout (102-113)
oxen-rust/src/lib/src/repositories/commits.rs (3)
  • commit (49-54)
  • head_commit_maybe (85-90)
  • util (630-630)
oxen-rust/src/lib/src/model/repository/local_repository.rs (2)
  • subtree_paths (252-265)
  • depth (271-273)
oxen-rust/src/lib/src/test.rs (1)
  • run_empty_local_repo_test_async (292-317)
oxen-rust/src/lib/src/util/fs.rs (6)
  • write_to_path (295-315)
  • result (1469-1469)
  • result (1499-1499)
  • result (1525-1525)
  • result (1549-1549)
  • read_from_path (280-293)
oxen-rust/src/lib/src/repositories/remote_mode/checkout.rs (2)
oxen-rust/src/cli/src/cmd/checkout.rs (3)
  • name (13-15)
  • force_checkout (106-126)
  • checkout (88-104)
oxen-rust/src/lib/src/repositories/checkout.rs (2)
  • force_checkout (73-134)
  • checkout (17-69)
oxen-rust/src/lib/src/core/v_latest/branches.rs (3)
oxen-rust/src/lib/src/repositories/checkout.rs (1)
  • force_checkout (73-134)
oxen-rust/src/lib/src/repositories/branches.rs (1)
  • set_working_repo_to_commit (461-481)
oxen-rust/src/lib/src/util/fs.rs (1)
  • is_modified_from_node (1797-1799)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Test Suite / Test Suite (windows-latest)
  • GitHub Check: Test Suite / Test Suite (ubuntu-latest)
  • GitHub Check: Test Suite / Test Suite (macos-latest)
  • GitHub Check: Lint / Cargo check, format, clippy + Ruff

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

coderabbitai[bot] avatar Oct 22 '25 18:10 coderabbitai[bot]