Detailed changes
@@ -435,6 +435,7 @@ impl Server {
.add_request_handler(forward_mutating_project_request::<proto::GitCreateRemote>)
.add_request_handler(forward_mutating_project_request::<proto::GitRemoveRemote>)
.add_request_handler(forward_read_only_project_request::<proto::GitGetWorktrees>)
+ .add_request_handler(forward_read_only_project_request::<proto::GitGetHeadSha>)
.add_request_handler(forward_mutating_project_request::<proto::GitCreateWorktree>)
.add_request_handler(disallow_guest_request::<proto::GitRemoveWorktree>)
.add_request_handler(disallow_guest_request::<proto::GitRenameWorktree>)
@@ -424,6 +424,58 @@ async fn test_remote_git_worktrees(
);
}
+#[gpui::test]
+async fn test_remote_git_head_sha(
+ executor: BackgroundExecutor,
+ cx_a: &mut TestAppContext,
+ cx_b: &mut TestAppContext,
+) {
+ let mut server = TestServer::start(executor.clone()).await;
+ let client_a = server.create_client(cx_a, "user_a").await;
+ let client_b = server.create_client(cx_b, "user_b").await;
+ server
+ .create_room(&mut [(&client_a, cx_a), (&client_b, cx_b)])
+ .await;
+ let active_call_a = cx_a.read(ActiveCall::global);
+
+ client_a
+ .fs()
+ .insert_tree(
+ path!("/project"),
+ json!({ ".git": {}, "file.txt": "content" }),
+ )
+ .await;
+
+ let (project_a, _) = client_a.build_local_project(path!("/project"), cx_a).await;
+ let local_head_sha = cx_a.update(|cx| {
+ project_a
+ .read(cx)
+ .active_repository(cx)
+ .unwrap()
+ .update(cx, |repository, _| repository.head_sha())
+ });
+ let local_head_sha = local_head_sha.await.unwrap().unwrap();
+
+ let project_id = active_call_a
+ .update(cx_a, |call, cx| call.share_project(project_a.clone(), cx))
+ .await
+ .unwrap();
+ let project_b = client_b.join_remote_project(project_id, cx_b).await;
+
+ executor.run_until_parked();
+
+ let remote_head_sha = cx_b.update(|cx| {
+ project_b
+ .read(cx)
+ .active_repository(cx)
+ .unwrap()
+ .update(cx, |repository, _| repository.head_sha())
+ });
+ let remote_head_sha = remote_head_sha.await.unwrap();
+
+ assert_eq!(remote_head_sha.unwrap(), local_head_sha);
+}
+
#[gpui::test]
async fn test_linked_worktrees_sync(
executor: BackgroundExecutor,
@@ -594,6 +594,7 @@ impl GitStore {
client.add_entity_request_handler(Self::handle_create_worktree);
client.add_entity_request_handler(Self::handle_remove_worktree);
client.add_entity_request_handler(Self::handle_rename_worktree);
+ client.add_entity_request_handler(Self::handle_get_head_sha);
}
pub fn is_local(&self) -> bool {
@@ -2466,6 +2467,21 @@ impl GitStore {
Ok(proto::Ack {})
}
+ async fn handle_get_head_sha(
+ this: Entity<Self>,
+ envelope: TypedEnvelope<proto::GitGetHeadSha>,
+ mut cx: AsyncApp,
+ ) -> Result<proto::GitGetHeadShaResponse> {
+ let repository_id = RepositoryId::from_proto(envelope.payload.repository_id);
+ let repository_handle = Self::repository_for_request(&this, repository_id, &mut cx)?;
+
+ let head_sha = repository_handle
+ .update(&mut cx, |repository_handle, _| repository_handle.head_sha())
+ .await??;
+
+ Ok(proto::GitGetHeadShaResponse { sha: head_sha })
+ }
+
async fn handle_get_branches(
this: Entity<Self>,
envelope: TypedEnvelope<proto::GitGetBranches>,
@@ -6052,13 +6068,21 @@ impl Repository {
}
pub fn head_sha(&mut self) -> oneshot::Receiver<Result<Option<String>>> {
+ let id = self.id;
self.send_job(None, move |repo, _cx| async move {
match repo {
RepositoryState::Local(LocalRepositoryState { backend, .. }) => {
Ok(backend.head_sha().await)
}
- RepositoryState::Remote(_) => {
- anyhow::bail!("head_sha is not supported for remote repositories")
+ RepositoryState::Remote(RemoteRepositoryState { project_id, client }) => {
+ let response = client
+ .request(proto::GitGetHeadSha {
+ project_id: project_id.0,
+ repository_id: id.to_proto(),
+ })
+ .await?;
+
+ Ok(response.sha)
}
}
})
@@ -568,6 +568,15 @@ message GitGetWorktrees {
uint64 repository_id = 2;
}
+message GitGetHeadSha {
+ uint64 project_id = 1;
+ uint64 repository_id = 2;
+}
+
+message GitGetHeadShaResponse {
+ optional string sha = 1;
+}
+
message GitWorktreesResponse {
repeated Worktree worktrees = 1;
}
@@ -474,7 +474,9 @@ message Envelope {
GitCompareCheckpoints git_compare_checkpoints = 436;
GitCompareCheckpointsResponse git_compare_checkpoints_response = 437;
GitDiffCheckpoints git_diff_checkpoints = 438;
- GitDiffCheckpointsResponse git_diff_checkpoints_response = 439; // current max
+ GitDiffCheckpointsResponse git_diff_checkpoints_response = 439;
+ GitGetHeadSha git_get_head_sha = 440;
+ GitGetHeadShaResponse git_get_head_sha_response = 441; // current max
}
reserved 87 to 88;
@@ -351,6 +351,8 @@ messages!(
(NewExternalAgentVersionAvailable, Background),
(RemoteStarted, Background),
(GitGetWorktrees, Background),
+ (GitGetHeadSha, Background),
+ (GitGetHeadShaResponse, Background),
(GitWorktreesResponse, Background),
(GitCreateWorktree, Background),
(GitRemoveWorktree, Background),
@@ -558,6 +560,7 @@ request_messages!(
(GetContextServerCommand, ContextServerCommand),
(RemoteStarted, Ack),
(GitGetWorktrees, GitWorktreesResponse),
+ (GitGetHeadSha, GitGetHeadShaResponse),
(GitCreateWorktree, Ack),
(GitRemoveWorktree, Ack),
(GitRenameWorktree, Ack),
@@ -749,6 +752,7 @@ entity_messages!(
ExternalAgentLoadingStatusUpdated,
NewExternalAgentVersionAvailable,
GitGetWorktrees,
+ GitGetHeadSha,
GitCreateWorktree,
GitRemoveWorktree,
GitRenameWorktree,