#16606

Code review follows symbolic links and reports referent contents as added code

OpenArman19941113opened 9d ago

Pre-submit Checks

  • Searched existing Warp issues; no duplicate found for this local Code review behavior.
  • Checked the known issues page; this behavior is not listed.

Describe the bug

When a Warp tab is open in a local Git repository, adding a symbolic link can make Code review count and display the referenced file's contents as newly added code. Linking to a 3,000-line file can show thousands of added lines even though Git stores only the link target path.

Directory and dangling links also need to remain reviewable without opening their referents.

To reproduce

  1. In a local Warp tab, prepare a clean repository with a large referent outside it:
repro_root="$(mktemp -d)"
mkdir -p "$repro_root/repo" "$repro_root/targets/directory"
git -C "$repro_root/repo" init -b main
git -C "$repro_root/repo" -c user.name=Test -c user.email=test@example.com -c commit.gpgsign=false commit --allow-empty -m "Initial commit"
python3 -c 'import pathlib, sys; pathlib.Path(sys.argv[1]).write_text("code\n" * 3000)' "$repro_root/targets/large.txt"
cd "$repro_root/repo"
  1. Keep this tab in the repository, then add the links:
ln -s ../targets/large.txt file-link
ln -s ../targets/directory directory-link
ln -s ../targets/missing dangling-link
  1. Open or refresh the Code review panel.
  2. Compare its counts and displayed content with Git's symlink representation.
  3. Stage the links with git add file-link directory-link dangling-link and compare with git diff --cached --stat.

Expected behavior

Each link displays its target path. These three single-line targets contribute three additions, both before and after staging. The 3,000-line referent is not displayed as newly added code.

Changing a link target refreshes its review content. Reviewing or commenting on a link leaves its referent unchanged.

Screenshots, videos, and logs

The initial fix's Linux GUI verification is recorded in #16589. This screenshot shows the expected three target paths and +3/-0 totals:

This is evidence from an earlier patch revision, not a new manual run of the latest commit.

Operating system (OS)

macOS

Operating system and version

Local development and regression-test environment: macOS 26.6.2, Apple Silicon. Earlier GUI evidence: Debian 13 with Xvfb and Mesa llvmpipe.

Shell Version

zsh 5.9 (arm64-apple-darwin25.0)

Current Warp version

A released build number was not recorded in the original report. Source baseline: 9b499e02961ba2ea48f1e3837b7655589920aff0.

Regression

Unknown; no last working release has been identified.

Additional context

The affected local paths are in app/src/code_review/diff_state/local.rs and the Code review editor's global-buffer loading path. Git stores a symlink's target path, while opening it as an ordinary file follows the referent.

Implementation: #16608 (draft), submitted from Arman19941113:Arman19941113/fix-code-review-symlinks after merging upstream master and validating the candidate.

Does this block you from using Warp daily?

Daily-use severity was not reported. It makes review counts and content misleading for repositories containing these links.

Is this an issue only in Warp?

The observed mismatch is in Warp Code review. Git records the link target path; other terminals' graphical review interfaces were not compared.

Activity

1
warp-for-oss[bot]9d ago

@Arman19941113

Here's what I found while triaging this issue:

Thanks for the detailed repro. This looks like a local Code Review bug where symlink entries are opened through their targets instead of being rendered as Git symlink target paths.

I've flagged this for the factory auto-implement queue.

Maintainer details

I concluded that code Review appears to open symlink diff entries through the shared file buffer, causing symlink referents to be displayed instead of the Git symlink target path..

Triage summary

This is a local Code Review bug involving symlink entries in Git diffs. The report provides a concrete minimal reproduction with file, directory, and dangling symlinks, plus the expected Git behavior: symlinks should render as their target path rather than the referent's contents.

Evidence and likely root cause

  • app/src/code_review/diff_state/local.rs builds diffs for new/untracked files and supplies content_at_head = Some("") when repo_path.join(file_path).is_file() is true. Path::is_file() follows symlinks, so a symlink to a file is treated like an ordinary file that can receive a global-buffer editor.
  • app/src/code_review/code_review_view.rs creates Code Review editors through create_code_review_model_with_global_buffer, which opens repo_path.join(file_path) via LocalCodeEditorView::new_with_global_buffer for non-deleted files with content_at_head.
  • app/src/code/global_buffer_model.rs delegates local opens to FileModel::open; crates/warp_files/src/lib.rs then reads the path with async_fs::read_to_string, while LocalFile::new also canonicalizes the path. That load path can read a symlink referent rather than the symlink blob/target text.
  • A local Git command check confirms git diff --no-index -- /dev/null file-link reports a file symlink as a one-line target-path diff, matching git diff --cached. This makes the editor/global-buffer load path the most likely source of referent content appearing in the rendered review.

Duplicate check

I fetched all open repository issues with pagination and excluded pull requests plus #16606. Open symlink-related and Code Review/diff-related issues exist, but I did not find two existing issues with the same symptom of Code Review following a symlink and showing/counting referent contents as added code.

Suggested next step

A likely fix is to special-case symlink paths before constructing Code Review editor buffers: detect symlinks with symlink_metadata/read_link, render the link target text as the working content, and avoid opening the symlink through GlobalBufferModel. Directory and dangling symlinks should remain representable as link-target text rather than being followed or dropped.

This is my automated analysis and may be incorrect. A maintainer will verify the details.

Powered by Oz