collin/anvil · c6b9364e
fix: don't render a repo as empty when HEAD names an unborn branch
Collin Richards · 2026-06-10 08:28 UTC · c6b9364e2b06a28f484dbb530c10cacbe6282153 · parent 0bfd5861 · browse files
modifiedcrates/anvil-git/src/browse.rs+30 −2
| ⋯ 39 unchanged lines | |||
| 40 | 40 | /// Summarize a repository's default branch, branches, and tags. | |
| 41 | 41 | pub fn overview(repo_path: &Path) -> Result<Overview> { | |
| 42 | 42 | let repo = gix::open(repo_path).map_err(read)?; | |
| 43 | - | let default_branch = repo | |
| 43 | + | let mut default_branch = repo | |
| 44 | 44 | .head_name() | |
| 45 | 45 | .ok() | |
| 46 | 46 | .flatten() | |
| 47 | 47 | .map(|n| n.shorten().to_string()); | |
| 48 | - | let is_empty = repo.head_id().is_err(); | |
| 49 | 48 | ||
| 50 | 49 | let refs = repo.references().map_err(read)?; | |
| 51 | 50 | let mut branches = Vec::new(); | |
| ⋯ 7 unchanged lines | |||
| 59 | 58 | branches.sort(); | |
| 60 | 59 | tags.sort(); | |
| 61 | 60 | ||
| 61 | + | // HEAD can point at an unborn branch (e.g. `main`) while pushes created | |
| 62 | + | // only other branches; fall back so the repo doesn't render as empty. | |
| 63 | + | let head_unborn = repo.head_id().is_err(); | |
| 64 | + | if head_unborn && !branches.is_empty() { | |
| 65 | + | default_branch = ["main", "master"] | |
| 66 | + | .into_iter() | |
| 67 | + | .find(|n| branches.iter().any(|b| b == n)) | |
| 68 | + | .map(str::to_string) | |
| 69 | + | .or_else(|| branches.first().cloned()); | |
| 70 | + | } | |
| 71 | + | let is_empty = head_unborn && branches.is_empty(); | |
| 72 | + | ||
| 62 | 73 | Ok(Overview { | |
| 63 | 74 | default_branch, | |
| 64 | 75 | branches, | |
| ⋯ 436 unchanged lines | |||
| 501 | 512 | assert!(latest.contains_key("a.txt")); | |
| 502 | 513 | assert!(!latest.contains_key("sub")); | |
| 503 | 514 | } | |
| 515 | + | ||
| 516 | + | #[test] | |
| 517 | + | fn overview_falls_back_when_head_is_unborn() { | |
| 518 | + | let tmp = tempfile::tempdir().unwrap(); | |
| 519 | + | let dir = tmp.path(); | |
| 520 | + | // HEAD points at `main`, but the only branch pushed is `master`. | |
| 521 | + | git(dir, &["init", "-q", "-b", "main"]); | |
| 522 | + | git(dir, &["checkout", "-qb", "master"]); | |
| 523 | + | std::fs::write(dir.join("a.txt"), "one").unwrap(); | |
| 524 | + | git(dir, &["add", "."]); | |
| 525 | + | git(dir, &["commit", "-qm", "first"]); | |
| 526 | + | git(dir, &["symbolic-ref", "HEAD", "refs/heads/main"]); | |
| 527 | + | ||
| 528 | + | let ov = overview(dir).unwrap(); | |
| 529 | + | assert!(!ov.is_empty, "repo with a branch is not empty"); | |
| 530 | + | assert_eq!(ov.default_branch.as_deref(), Some("master")); | |
| 531 | + | } | |
| 504 | 532 | } | |