Skip to content

fix: apply the diff's target file mode in sub-PR worktrees - #90

Closed
vitali87 wants to merge 4 commits into
fix/emptied-file-not-deletedfrom
fix/apply-file-modes
Closed

vitali87 wants to merge 4 commits into
fix/emptied-file-not-deletedfrom
fix/apply-file-modes

Conversation

@vitali87

Copy link
Copy Markdown
Owner

Problem

A chmod +x (or -x) that arrives together with a content change passes validation, but the worker only ever wrote file content: materialize_group_files returns text and the worktree write is write_text. The mode bit never reached the sub-PR branch — git ls-tree on the sub-PR showed 100644 run.sh where the feature branch had 100755. No error anywhere. (Hunk-less mode-only entries are rejected up front by #79; this handles the common case where the mode change comes with edits.)

Fix

  • target_file_modes(parsed_diff, group) reads new mode NNNNNN / new file mode NNNNNN from each assigned file's diff header (unidiff keeps them in patch_info) and returns the mode for regular files only (mode & 0o170000 == 0o100000), so a symlink's 120000 is never masked to 000.
  • The worker chmods each written file to mode & 0o777 after writing it.

Verified end to end in a real repo: +x with content, -x with content, and a new executable file all land with the right mode in the committed sub-PR branch; stacked children and merge nodes (which re-materialise from the merge base) get it too; a symlink in the same group keeps its pre-existing (plain-file) behaviour instead of aborting the group.

Tests

target_file_modes: mode+content, new executable, -x, unassigned/plain files ignored, deleted files ignored, symlink ignored. Worker: executable bit applied only to the file the diff marks.

Local review: 5/5. 451 tests pass, ruff clean.

Follow-up: symlinks are still materialised as regular files (pre-existing); separate PR.

@coderabbitai

coderabbitai Bot commented Aug 30, 2026 •

Copy link
Copy Markdown

Warning

Review limit reached

Next included review available in 49 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: 73e3915f-ceac-4014-b065-6e78bd7220f6

📥 Commits

Reviewing files that changed from the base of the PR and between 8a7f17e and a0d19ba.

📒 Files selected for processing (5)
  • pr_split/cli.py
  • pr_split/diff_ops/__init__.py
  • pr_split/diff_ops/reconstructor.py
  • tests/test_cli_helpers.py
  • tests/test_reconstructor.py

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.

A chmod that came with a content change passed validation but the
worker only wrote file content, so the executable bit never reached
the sub-PR. Read new mode / new file mode from the diff header and
chmod the materialized file.
@vitali87
vitali87 force-pushed the fix/apply-file-modes branch from 9d7fe0f to fe6a533 Compare August 30, 2026 14:00
@vitali87
vitali87 changed the base branch from main to fix/emptied-file-not-deleted August 30, 2026 14:00
…file-modes

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015rnEEjXWDBdePRhKMmZr1w

Copy link
Copy Markdown
Owner Author

This change is already in main: it landed via the merge train #243, which includes this PR's head commit. GitHub can't mark a stacked PR merged when it lands that way, so I'm closing it as done.


Generated by Claude Code

@vitali87 vitali87 closed this Sep 27, 2026
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.

2 participants