~ knotless Search/
↑↓ move↵ open⇧↵ all results

chadtmiller.com/knotless

git that lives in your Atmosphere account

knotless.dev
1 collaborator

knotless 0.13.0 Latest 2 packages, 1 image

1
10

Who vouched for a commit is found in process, not a git each merged pull

Merged chadtmiller.com asked to merge into main from chadtmiller.com/knotless:serve/vouched-in-process
crates/knotless-serve/src/objects.rs+18−0
@@ -575,6 +575,18 @@ impl Objects {
}
Ok(out)
}
/// The commits `to` reaches that `from` does not, as `git rev-list
/// from..to` lists them, by id. An error when either is not here.
pub fn between(&self, from: &str, to: &str) -> Result<HashSet<String>> {
let tip = self.commit(to)?.id;
let hidden = self.commit(from)?.id;
let mut out = HashSet::new();
for info in self.0.rev_walk([tip]).with_hidden([hidden]).all()? {
out.insert(info?.id.to_string());
}
Ok(out)
}
}
fn summary(commit: &gix::Commit<'_>) -> Result<Commit> {
@@ -728,6 +740,12 @@ mod tests {
assert_eq!(o.brought("main", &[], 2).unwrap().len(), 2);
assert!(o.brought("main", &["main"], 10).unwrap().is_empty());
assert!(o.brought("nope", &[], 10).is_err());
let past_side = o.brought("main", &["side"], 10).unwrap();
let past_side: HashSet<String> = past_side.into_iter().map(|c| c.sha).collect();
assert_eq!(o.between("side", "main").unwrap(), past_side);
assert!(o.between("main", "main").unwrap().is_empty());
assert!(o.between("gone", "main").is_err());
assert!(o.between("side", "nope").is_err());
run(vec!["checkout", "-q", "--detach"]);
assert_eq!(open(&d.join(".git")).unwrap().head(), None);
crates/knotless-serve/src/web.rs+44−37
@@ -1100,35 +1100,41 @@ fn coauthor(line: &str) -> Option<(String, String)> {
Some((name.trim().to_string(), email.trim().to_string()))
}
/// What a merge as `merged` brought in, as `git rev-list` takes it: from
/// where the base was before it, or, for a merge recorded without that, a
/// merge commit's second parent less its first, which names nothing for
/// any other kind of merge.
fn brought(merged: &str, from: Option<&str>) -> String {
/// What a merge as `merged` brought in, as the ends of a range of
/// history: from where the base was before it, or, for a merge recorded
/// without that, a merge commit's second parent less its first, which
/// names nothing for any other kind of merge.
fn brought(merged: &str, from: Option<&str>) -> (String, String) {
match from {
Some(from) => format!("{from}..{merged}"),
None => format!("{merged}^1..{merged}^2"),
Some(from) => (from.to_string(), merged.to_string()),
None => (format!("{merged}^1"), format!("{merged}^2")),
}
}
static BROUGHT: LazyLock<Mutex<HashMap<String, HashSet<String>>>> = LazyLock::new(Mutex::default);
type Range = (String, String);
/// The commits `range` names in `repo`, kept once git has found them: a
/// merge never changes what it brought in.
async fn brought_in(repo: &Repo, range: String) -> HashSet<String> {
if let Some(known) = BROUGHT.lock().unwrap().get(&range) {
return known.clone();
}
let listed = repo.git.text(&["rev-list", &range], None).await;
let shas: HashSet<String> = listed
.iter()
.flat_map(|l| l.lines())
.map(String::from)
.collect();
if listed.is_ok() {
BROUGHT.lock().unwrap().insert(range, shas.clone());
}
shas
static BROUGHT: LazyLock<Mutex<HashMap<Range, HashSet<String>>>> = LazyLock::new(Mutex::default);
/// The commits each of `ranges` names in the mirror at `dir`, kept once
/// found: a merge never changes what it brought in. Read in this process,
/// all with the one repository opened, as a repository's merged pulls are
/// many and a git process for each, all at once, took seconds.
fn brought_in(dir: &std::path::Path, ranges: Vec<Option<Range>>) -> Vec<Option<HashSet<String>>> {
let objects = crate::objects::open(dir).ok();
let find = |(from, to): Range| {
if let Some(known) = BROUGHT.lock().unwrap().get(&(from.clone(), to.clone())) {
return known.clone();
}
// Not found, as a commit the mirror has yet to fetch, it is looked
// for again next time.
let found = objects.as_ref().map(|o| o.between(&from, &to));
let found = found.and_then(|f| f.ok());
if let Some(shas) = &found {
BROUGHT.lock().unwrap().insert((from, to), shas.clone());
}
found.unwrap_or_default()
};
ranges.into_iter().map(|r| r.map(find)).collect()
}
/// Whose claims `repo`'s pages believe, and where: its owner, its
@@ -1141,7 +1147,7 @@ async fn vouched(app: &App, repo: &Repo, record: RepoRecord, items: &[Item]) ->
});
let writers: Vec<String> = record.writers().map(String::from).collect();
let everywhere = std::iter::once(repo.did.clone()).chain(writers);
let people: Vec<(String, Option<String>)> = everywhere
let people: Vec<(String, Option<Range>)> = everywhere
.map(|did| (did, None))
.chain(merged.map(|(did, range)| (did, Some(range))))
.collect();
@@ -1154,17 +1160,17 @@ async fn vouched(app: &App, repo: &Repo, record: RepoRecord, items: &[Item]) ->
});
let claimed: HashMap<String, Vec<String>> =
futures::future::join_all(read).await.into_iter().collect();
futures::future::join_all(people.into_iter().map(|(did, range)| {
let hashes = claimed.get(&did).cloned().unwrap_or_default();
async move {
let only = match range {
Some(range) => Some(brought_in(repo, range).await),
None => None,
};
let (dids, ranges): (Vec<String>, Vec<Option<Range>>) = people.into_iter().unzip();
let dir = repo.git.dir.clone();
let found = tokio::task::spawn_blocking(move || brought_in(&dir, ranges));
let found = found.await.expect("a walk does not panic");
dids.into_iter()
.zip(found)
.map(|(did, only)| {
let hashes = claimed.get(&did).cloned().unwrap_or_default();
Vouched { did, hashes, only }
}
}))
.await
})
.collect()
}
/// `commits`, as the pages show them, each with the accounts that wrote it
@@ -3038,8 +3044,9 @@ mod tests {
#[test]
fn what_merges_brought() {
assert_eq!(brought("m", Some("f")), "f..m");
assert_eq!(brought("m", None), "m^1..m^2");
let range = |from: &str, to: &str| (from.to_string(), to.to_string());
assert_eq!(brought("m", Some("f")), range("f", "m"));
assert_eq!(brought("m", None), range("m^1", "m^2"));
}
#[test]