feat: browse GitHub GitLab and Gitea pull requests

This commit is contained in:
Valdemar Lorenzen
2026-10-14 13:22:09 +02:00
parent 15968a328c
commit af6496bd5a
11 changed files with 1349 additions and 47 deletions
+77
View File
@@ -1929,3 +1929,80 @@ fn branch_changes_rejects_missing_and_multiple_merge_bases_without_snapshot_fall
}
assert_eq!(disk_state(&root), state);
}
#[test]
fn pull_request_refs_fetch_pinned_fork_heads_privately_for_git_and_jj() {
let fixture = Fixture::new();
let source = fixture.dir("source");
init_git(&source);
fs::write(source.join("common"), "base\n").unwrap();
git(&source, &["add", "."]);
git(&source, &["commit", "-m", "base"]);
let base = git(&source, &["rev-parse", "HEAD"]);
fs::write(source.join("target-only"), "not part of the PR\n").unwrap();
git(&source, &["add", "."]);
git(&source, &["commit", "-m", "target advanced"]);
let target = git(&source, &["rev-parse", "HEAD"]);
git(&source, &["checkout", "--detach", &base]);
fs::write(source.join("common"), "fork change\n").unwrap();
git(&source, &["add", "."]);
git(&source, &["commit", "-m", "fork tip"]);
let head = git(&source, &["rev-parse", "HEAD"]);
git(&source, &["update-ref", "refs/pull/7/head", &head]);
for (index, kind) in [RepoKind::Git, RepoKind::Jujutsu, RepoKind::Jujutsu]
.into_iter()
.enumerate()
{
let root = fixture.dir(&format!("active-{index}"));
if kind == RepoKind::Git {
init_git(&root);
fs::write(root.join("unrelated"), "local\n").unwrap();
git(&root, &["add", "."]);
git(&root, &["commit", "-m", "unrelated local"]);
git(
&root,
&["remote", "add", "origin", source.to_str().unwrap()],
);
} else {
init_jj(&root, index == 2);
jj(
&root,
&["git", "remote", "add", "origin", source.to_str().unwrap()],
);
}
fs::write(root.join("unsaved"), "keep\n").unwrap();
let state = disk_state(&root);
let pinned = |reference: &str, id: &str| Revision {
target: RevisionTarget::RemoteCommit {
remote: "origin".into(),
reference: reference.into(),
id: id.into(),
},
..revision(id, kind)
};
let before = pinned("refs/heads/local", &target);
let after = pinned("refs/pull/7/head", &head);
let mut repository = open(&root);
let comparison = repository
.compare(70, &before, &after, ComparisonMode::BranchChanges, &[])
.unwrap();
assert!(comparison.before.ends_with(&base));
assert_eq!(comparison.files.len(), 1);
assert_eq!(comparison.files[0].path, Path::new("common"));
assert!(comparison.editable_paths.is_empty());
let file = repository.load_file(70, 0).unwrap();
assert_eq!(file.before, ["base"]);
assert_eq!(file.after, ["fork change"]);
assert_eq!(disk_state(&root), state);
// A force-push cannot silently replace the immutable tip selected in the picker.
let absent = pinned("refs/pull/7/head", &"f".repeat(40));
assert!(
repository
.compare(71, &before, &absent, ComparisonMode::BranchChanges, &[])
.unwrap_err()
.contains("reopen :pull_requests")
);
assert_eq!(disk_state(&root), state);
}
}