diff --git a/crates/project/src/git.rs b/crates/project/src/git.rs index 1cf2ca3505..4be911deaf 100644 --- a/crates/project/src/git.rs +++ b/crates/project/src/git.rs @@ -40,6 +40,7 @@ pub struct Repository { pub worktree_id: WorktreeId, pub repository_entry: RepositoryEntry, pub git_repo: GitRepo, + pub merge_message: Option, update_sender: mpsc::UnboundedSender<(Message, oneshot::Sender>)>, } @@ -138,22 +139,29 @@ impl GitStore { worktree.update(cx, |worktree, cx| { let snapshot = worktree.snapshot(); for repo in snapshot.repositories().iter() { - let git_repo = worktree + let git_data = worktree .as_local() .and_then(|local_worktree| local_worktree.get_local_repo(repo)) - .map(|local_repo| local_repo.repo().clone()) - .map(GitRepo::Local) + .map(|local_repo| { + ( + GitRepo::Local(local_repo.repo().clone()), + local_repo.merge_message.clone(), + ) + }) .or_else(|| { let client = client.clone()?; let project_id = project_id?; - Some(GitRepo::Remote { - project_id, - client, - worktree_id: worktree.id(), - work_directory_id: repo.work_directory_id(), - }) + Some(( + GitRepo::Remote { + project_id, + client, + worktree_id: worktree.id(), + work_directory_id: repo.work_directory_id(), + }, + None, + )) }); - let Some(git_repo) = git_repo else { + let Some((git_repo, merge_message)) = git_data else { continue; }; let worktree_id = worktree.id(); @@ -169,10 +177,24 @@ impl GitStore { if self.active_index == Some(index) { new_active_index = Some(new_repositories.len()); } - // Update the statuses but keep everything else. + // Update the statuses and merge message but keep everything else. let existing_handle = handle.clone(); - existing_handle.update(cx, |existing_handle, _| { + existing_handle.update(cx, |existing_handle, cx| { existing_handle.repository_entry = repo.clone(); + if matches!(git_repo, GitRepo::Local { .. }) + && existing_handle.merge_message != merge_message + { + if let (Some(merge_message), Some(buffer)) = + (&merge_message, &existing_handle.commit_message_buffer) + { + buffer.update(cx, |buffer, cx| { + if buffer.is_empty() { + buffer.set_text(merge_message.as_str(), cx); + } + }) + } + existing_handle.merge_message = merge_message; + } }); existing_handle } else { @@ -182,6 +204,7 @@ impl GitStore { repository_entry: repo.clone(), git_repo, update_sender: self.update_sender.clone(), + merge_message, commit_message_buffer: None, }) }; @@ -751,6 +774,7 @@ impl Repository { buffer_store: Entity, cx: &mut Context, ) -> Task>> { + let merge_message = self.merge_message.clone(); cx.spawn(|repository, mut cx| async move { let buffer = buffer_store .update(&mut cx, |buffer_store, cx| buffer_store.create_buffer(cx))? @@ -763,6 +787,12 @@ impl Repository { })?; } + if let Some(merge_message) = merge_message { + buffer.update(&mut cx, |buffer, cx| { + buffer.set_text(merge_message.as_str(), cx) + })?; + } + repository.update(&mut cx, |repository, _| { repository.commit_message_buffer = Some(buffer.clone()); })?; diff --git a/crates/worktree/src/worktree.rs b/crates/worktree/src/worktree.rs index 16f9a27ceb..1cf9f29b12 100644 --- a/crates/worktree/src/worktree.rs +++ b/crates/worktree/src/worktree.rs @@ -576,6 +576,7 @@ pub struct LocalRepositoryEntry { /// Absolute path to the .git file, if we're in a git worktree. pub(crate) dot_git_worktree_abs_path: Option>, pub current_merge_head_shas: Vec, + pub merge_message: Option, } impl sum_tree::Item for LocalRepositoryEntry { @@ -3524,6 +3525,7 @@ impl BackgroundScannerState { dot_git_dir_abs_path: actual_dot_git_dir_abs_path.into(), dot_git_worktree_abs_path, current_merge_head_shas: Default::default(), + merge_message: None, }; self.snapshot @@ -5491,6 +5493,10 @@ impl BackgroundScanner { &local_repository.work_directory_id, |entry| { entry.current_merge_head_shas = merge_head_shas; + entry.merge_message = std::fs::read_to_string( + local_repository.dot_git_dir_abs_path.join("MERGE_MSG"), + ) + .ok(); entry.status_scan_id += 1; }, );