feat: browse GitHub GitLab and Gitea pull requests
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user