git: Don't call git2::Repository::find_remote for every blamed buffer (#44107)

We already store the remote URLs for `origin` and `upstream` in the
`RepositorySnapshot`, so just use that data. Follow-up to #44092.

Release Notes:

- N/A
This commit is contained in:
Cole Miller
2025-12-04 13:25:30 -05:00
committed by GitHub
parent 74a1b5d14d
commit d5ed9d3e3a
11 changed files with 51 additions and 52 deletions
@@ -121,6 +121,8 @@ CREATE TABLE "project_repositories" (
"merge_message" VARCHAR,
"branch_summary" VARCHAR,
"head_commit_details" VARCHAR,
"remote_upstream_url" VARCHAR,
"remote_origin_url" VARCHAR,
PRIMARY KEY (project_id, id)
);
@@ -0,0 +1,2 @@
ALTER TABLE "project_repositories" ADD COLUMN "remote_upstream_url" VARCHAR;
ALTER TABLE "project_repositories" ADD COLUMN "remote_origin_url" VARCHAR;
+6
View File
@@ -362,6 +362,8 @@ impl Database {
entry_ids: ActiveValue::set("[]".into()),
head_commit_details: ActiveValue::set(None),
merge_message: ActiveValue::set(None),
remote_upstream_url: ActiveValue::set(None),
remote_origin_url: ActiveValue::set(None),
}
}),
)
@@ -511,6 +513,8 @@ impl Database {
serde_json::to_string(&update.current_merge_conflicts).unwrap(),
)),
merge_message: ActiveValue::set(update.merge_message.clone()),
remote_upstream_url: ActiveValue::set(update.remote_upstream_url.clone()),
remote_origin_url: ActiveValue::set(update.remote_origin_url.clone()),
})
.on_conflict(
OnConflict::columns([
@@ -1005,6 +1009,8 @@ impl Database {
is_last_update: true,
merge_message: db_repository_entry.merge_message,
stash_entries: Vec::new(),
remote_upstream_url: db_repository_entry.remote_upstream_url.clone(),
remote_origin_url: db_repository_entry.remote_origin_url.clone(),
});
}
}
+2
View File
@@ -796,6 +796,8 @@ impl Database {
is_last_update: true,
merge_message: db_repository.merge_message,
stash_entries: Vec::new(),
remote_upstream_url: db_repository.remote_upstream_url.clone(),
remote_origin_url: db_repository.remote_origin_url.clone(),
});
}
}
@@ -22,6 +22,8 @@ pub struct Model {
pub branch_summary: Option<String>,
// A JSON object representing the current Head commit values
pub head_commit_details: Option<String>,
pub remote_upstream_url: Option<String>,
pub remote_origin_url: Option<String>,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
-5
View File
@@ -3518,7 +3518,6 @@ async fn test_git_blame_is_forwarded(cx_a: &mut TestAppContext, cx_b: &mut TestA
.into_iter()
.map(|(sha, message)| (sha.parse().unwrap(), message.into()))
.collect(),
remote_url: Some("git@github.com:zed-industries/zed.git".to_string()),
};
client_a.fs().set_blame_for_repo(
Path::new(path!("/my-repo/.git")),
@@ -3603,10 +3602,6 @@ async fn test_git_blame_is_forwarded(cx_a: &mut TestAppContext, cx_b: &mut TestA
for (idx, (buffer, entry)) in entries.iter().flatten().enumerate() {
let details = blame.details_for_entry(*buffer, entry).unwrap();
assert_eq!(details.message, format!("message for idx-{}", idx));
assert_eq!(
details.permalink.unwrap().to_string(),
format!("https://github.com/zed-industries/zed/commit/{}", entry.sha)
);
}
});
});
+15 -7
View File
@@ -508,7 +508,19 @@ impl GitBlame {
let buffer_edits = buffer.update(cx, |buffer, _| buffer.subscribe());
let blame_buffer = project.blame_buffer(&buffer, None, cx);
Some(async move { (id, snapshot, buffer_edits, blame_buffer.await) })
let remote_url = project
.git_store()
.read(cx)
.repository_and_path_for_buffer_id(buffer.read(cx).remote_id(), cx)
.and_then(|(repo, _)| {
repo.read(cx)
.remote_upstream_url
.clone()
.or(repo.read(cx).remote_origin_url.clone())
});
Some(
async move { (id, snapshot, buffer_edits, blame_buffer.await, remote_url) },
)
})
.collect::<Vec<_>>()
});
@@ -524,13 +536,9 @@ impl GitBlame {
.await;
let mut res = vec![];
let mut errors = vec![];
for (id, snapshot, buffer_edits, blame) in blame {
for (id, snapshot, buffer_edits, blame, remote_url) in blame {
match blame {
Ok(Some(Blame {
entries,
messages,
remote_url,
})) => {
Ok(Some(Blame { entries, messages })) => {
let entries = build_blame_entry_sum_tree(
entries,
snapshot.max_point().row,
+1 -7
View File
@@ -19,7 +19,6 @@ pub use git2 as libgit;
pub struct Blame {
pub entries: Vec<BlameEntry>,
pub messages: HashMap<Oid, String>,
pub remote_url: Option<String>,
}
#[derive(Clone, Debug, Default)]
@@ -36,7 +35,6 @@ impl Blame {
working_directory: &Path,
path: &RepoPath,
content: &Rope,
remote_url: Option<String>,
) -> Result<Self> {
let output = run_git_blame(git_binary, working_directory, path, content).await?;
let mut entries = parse_git_blame(&output)?;
@@ -53,11 +51,7 @@ impl Blame {
.await
.context("failed to get commit messages")?;
Ok(Self {
entries,
messages,
remote_url,
})
Ok(Self { entries, messages })
}
}
+10 -21
View File
@@ -1494,28 +1494,17 @@ impl GitRepository for RealGitRepository {
let git_binary_path = self.any_git_binary_path.clone();
let executor = self.executor.clone();
async move {
let remote_url = if let Some(remote_url) = self.remote_url("upstream").await {
Some(remote_url)
} else if let Some(remote_url) = self.remote_url("origin").await {
Some(remote_url)
} else {
None
};
executor
.spawn(async move {
crate::blame::Blame::for_path(
&git_binary_path,
&working_directory?,
&path,
&content,
remote_url,
)
.await
})
executor
.spawn(async move {
crate::blame::Blame::for_path(
&git_binary_path,
&working_directory?,
&path,
&content,
)
.await
}
.boxed()
})
.boxed()
}
fn file_history(&self, path: RepoPath) -> BoxFuture<'_, Result<FileHistory>> {
+8 -11
View File
@@ -3296,6 +3296,8 @@ impl RepositorySnapshot {
.iter()
.map(stash_to_proto)
.collect(),
remote_upstream_url: self.remote_upstream_url.clone(),
remote_origin_url: self.remote_origin_url.clone(),
}
}
@@ -3365,6 +3367,8 @@ impl RepositorySnapshot {
.iter()
.map(stash_to_proto)
.collect(),
remote_upstream_url: self.remote_upstream_url.clone(),
remote_origin_url: self.remote_origin_url.clone(),
}
}
@@ -5395,6 +5399,8 @@ impl Repository {
cx.emit(RepositoryEvent::StashEntriesChanged)
}
self.snapshot.stash_entries = new_stash_entries;
self.snapshot.remote_upstream_url = update.remote_upstream_url;
self.snapshot.remote_origin_url = update.remote_origin_url;
let edits = update
.removed_statuses
@@ -5954,11 +5960,7 @@ fn serialize_blame_buffer_response(blame: Option<git::blame::Blame>) -> proto::B
.collect::<Vec<_>>();
proto::BlameBufferResponse {
blame_response: Some(proto::blame_buffer_response::BlameResponse {
entries,
messages,
remote_url: blame.remote_url,
}),
blame_response: Some(proto::blame_buffer_response::BlameResponse { entries, messages }),
}
}
@@ -5995,11 +5997,7 @@ fn deserialize_blame_buffer_response(
.filter_map(|message| Some((git::Oid::from_bytes(&message.oid).ok()?, message.message)))
.collect::<HashMap<_, _>>();
Some(Blame {
entries,
messages,
remote_url: response.remote_url,
})
Some(Blame { entries, messages })
}
fn branch_to_proto(branch: &git::repository::Branch) -> proto::Branch {
@@ -6147,7 +6145,6 @@ async fn compute_snapshot(
events.push(RepositoryEvent::BranchChanged);
}
// Used by edit prediction data collection
let remote_origin_url = backend.remote_url("origin").await;
let remote_upstream_url = backend.remote_url("upstream").await;
+3 -1
View File
@@ -124,6 +124,8 @@ message UpdateRepository {
optional GitCommitDetails head_commit_details = 11;
optional string merge_message = 12;
repeated StashEntry stash_entries = 13;
optional string remote_upstream_url = 14;
optional string remote_origin_url = 15;
}
message RemoveRepository {
@@ -500,8 +502,8 @@ message BlameBufferResponse {
message BlameResponse {
repeated BlameEntry entries = 1;
repeated CommitMessage messages = 2;
optional string remote_url = 4;
reserved 3;
reserved 4;
}
optional BlameResponse blame_response = 5;