Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 42 additions & 1 deletion crates/workspace-host/src/alerts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,8 @@ impl PullScan {
}
/// Scans the next commit on the head's first-parent line after `mark`, with any commits a
/// merge brought, oldest first: where the mark goes, `None` when it is at the head. Walking
/// that line keeps the mark an ancestor of what is left, so it always moves forward.
/// that line keeps the mark an ancestor of what is left, so it always moves forward. A head
/// behind the mark, such as a kept clone's before its first fetch, has nothing new yet.
fn advance(
&self,
check: &str,
Expand All @@ -214,6 +215,9 @@ impl PullScan {
) -> std::result::Result<Option<String>, String> {
let failed = |error: anyhow::Error| format!("{error:#}");
let clone = self.clone.as_path();
if publish::is_ancestor(clone, &self.head, mark) {
return Ok(None);
}
let start = self.start(mark);
let range = format!("{start}..{}", self.head);
let walk = ["rev-list", "--first-parent", "--reverse", &range];
Expand Down Expand Up @@ -1050,6 +1054,43 @@ mod tests {
});
}

#[test]
fn a_kept_clones_first_scan_waits_for_its_fetch_and_scans_no_old_history() {
let (_folder, github) = fixture();
let mut mac = Mac::join(&github);
let sage = crate::storage::tests::space_named(&mac.host, "Sage");
mac.host.remove_space(&sage.id).unwrap();
github.commit(&in_folder(NOTE), PHONE);
join_sage(&mut mac.host, &github).unwrap();
mac.scan();
assert_eq!(mac.mark(SENSITIVE_INFO), head(&github), "the mark waits");
mac.pull(&github);
assert_eq!(mac.alerts(), [], "what it missed is old history");
assert_eq!(mac.mark(SENSITIVE_INFO), head(&github));
}

#[test]
fn a_rewrite_before_a_kept_clones_first_fetch_scans_what_follows() {
let (_folder, github) = fixture();
let mut mac = Mac::join(&github);
let base = head(&github);
let sage = crate::storage::tests::space_named(&mac.host, "Sage");
mac.host.remove_space(&sage.id).unwrap();
github.commit(&in_folder(NOTE), PHONE);
join_sage(&mut mac.host, &github).unwrap();
git(&github.bare, &["update-ref", "refs/heads/main", &base]);
let rewritten = in_folder("second-brain/notes/Rewritten.md");
github.commit(&rewritten, PHONE);
mac.pull(&github);
let alerts = mac.alerts();
assert_eq!(alerts.len(), 1, "{alerts:?}");
assert_eq!(
alerts[0].path, rewritten,
"the dropped commit is not scanned"
);
assert_eq!(mac.mark(SENSITIVE_INFO), head(&github));
}

#[test]
fn a_rewrite_restarts_at_the_merge_base() {
let (_folder, github) = fixture();
Expand Down
5 changes: 5 additions & 0 deletions crates/workspace-host/src/storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1639,6 +1639,11 @@ impl Host {
if !clone.exists() {
fs::create_dir_all(clone.parent().context("A clone is in a folder")?)?;
fs::rename(staged.staging.keep(), &clone)?;
} else if joined_at.is_some() {
// A kept clone takes the head it joined at, where its pull scan starts.
let staging = (staged.staging.path().to_str()).context("A staging path is UTF-8")?;
let fetch = ["fetch", "--quiet", "--no-tags", "--recurse-submodules=no"];
runtime::git_output(&clone, &[&fetch[..], &[staging, "HEAD"]].concat())?;
}
let head = runtime::git_output(&clone, &["rev-parse", "HEAD"])?;
let head = head.trim();
Expand Down
Loading