Desktop Projects: pull request "Files changed" is empty on a local checkout — local_ref_exists accepts any 40-hex SHA, and the PR head is never fetched
- Dominant language
- Rust
- Stars
- 32.7k
- Forks
- 4.3k
- Avg merge
- 1d 13h
- Merged PRs (30d)
- 253
Description
**Describe the bug**
In Desktop → Projects, opening a pull request against a **local checkout** shows no
file diff. The "Files changed" view stays empty.
Two defects combine to cause it.
**1. `local_ref_exists` never reports a missing commit.**
`desktop/src-tauri/src/commands/project_git_diff.rs` (`main` @ `59328d5ae`):
```rust
fn local_ref_exists(repo_dir: &std::path::Path, auth: &GitAuthConfig, ref_name: &str) -> bool {
run_git(
&["rev-parse", "--verify", "--quiet", ref_name],
Some(repo_dir),
auth,
)
.is_ok()
}
```
`git rev-parse --verify` accepts any well-formed 40-hex string without checking that
the object is present. `pullRequest.commit` is always a full 40-hex SHA, so this
helper returns `true` for a commit the repository does not have:
```
$ git --version
git version 2.55.0
$ git rev-parse --verify --quiet 0123456789abcdef0123456789abcdef01234567
0123456789abcdef0123456789abcdef01234567 # rc=0, object is absent
$ git rev-parse --verify --quiet 0123456789abcdef0123456789abcdef01234567^{commit}
# rc=1, correct answer
```
`local_target_ref` therefore returns the absent SHA, and `local_diff_range` builds a
range git cannot resolve:
```
$ git diff --name-status "HEAD...0123456789abcdef0123456789abcdef01234567"
fatal: Invalid symmetric difference expression HEAD...0123456789abcdef...
```
The same helper backs `local_base_ref` and the `base_commit` check inside
`local_diff_range`, so all five call sites share the defect.
**2. The pull request head is never fetched into a local checkout.**
`get_project_local_repo_diff` takes `target_commit` but no target branch, and it never
fetches. A personal checkout that has only ever fetched its default branch simply does
not contain the review head. Even with defect 1 fixed, the diff stays empty until the
user fetches the branch by hand.
**Steps to reproduce**
1. Clone a repository yourself, outside Buzz (`git clone ~/code/`), and
fetch only the default branch.
2. Point a Buzz project at that checkout.
3. Open a pull request whose head branch was never fetched locally.
4. Open "Files changed".
5. The diff is empty. No error explains why.
**Expected behavior**
Buzz either shows the diff — fetching the pull request head branch from the checkout's
already-configured `origin` — or reports that the commit is not present locally.
Silently rendering an empty diff is the worst of the three.
**Version and platform**
- Buzz version: reproduced on a local build of `822c5ab23` (0.5.18). The code path is
byte-identical on `main` @ `59328d5ae` (0.5.20), so this is not fixed there.
- OS: Arch Linux, Hyprland (Wayland), git 2.55.0. The `rev-parse` defect is
platform-independent.
**Logs / additional context**
Suggested fix for defect 1 — peel to `^{commit}` so git performs a real object lookup.
One change in the shared helper covers all five call sites:
```rust
fn local_ref_exists(repo_dir: &Path, auth: &GitAuthConfig, ref_name: &str) -> bool {
// `git rev-parse --verify` accepts any well-formed 40-hex string without
// checking that the object is present, so a bare pull request head SHA
// always looks resolvable. Peeling to `^{commit}` forces the object lookup.
let peeled = format!("{ref_name}^{{commit}}");
run_git(&["rev-parse", "--verify", "--quiet", &peeled], Some(repo_dir), auth).is_ok()
}
```
Peeling stays correct for the branch and `origin/` call sites.
For defect 2, passing the pull request head branch down and fetching
`refs/heads/` from the existing local `origin` is enough. Two notes on that:
- The fetch must not pass `--depth`. Every other `--depth=100` in this file runs against
clones Buzz created in `reposDir`. A shallow fetch into a user's own full clone turns
it shallow, and only `git fetch --unshallow` undoes that.
- The clone URL from the relay must not be used here — the checkout's own `origin`
already carries the user's remote and credentials.
I have a working patch for both defects and am happy to open a PR if the direction
looks right. Related but distinct: the "Open in Terminal" defects filed separately.
Contributor guide
Assessment
This issue has not been assessed yet.