Assume merged diffs are squashed and diff against parent (#446)
This commit is contained in:
committed by
GitHub
parent
9130ac46fd
commit
7ed537d6d7
@@ -462,14 +462,12 @@ impl LocalContainerService {
|
||||
&self,
|
||||
project_repo_path: &Path,
|
||||
merge_commit_id: &str,
|
||||
base_branch: &str,
|
||||
) -> Result<futures::stream::BoxStream<'static, Result<Event, std::io::Error>>, ContainerError>
|
||||
{
|
||||
let diffs = self.git().get_diffs(
|
||||
DiffTarget::Commit {
|
||||
repo_path: project_repo_path,
|
||||
commit_sha: merge_commit_id,
|
||||
base_branch,
|
||||
},
|
||||
None,
|
||||
)?;
|
||||
@@ -481,6 +479,9 @@ impl LocalContainerService {
|
||||
let event = LogMsg::JsonPatch(patch).to_sse_event();
|
||||
Ok::<_, std::io::Error>(event)
|
||||
}))
|
||||
.chain(futures::stream::once(async {
|
||||
Ok::<_, std::io::Error>(LogMsg::Finished.to_sse_event())
|
||||
}))
|
||||
.boxed();
|
||||
|
||||
Ok(stream)
|
||||
@@ -847,11 +848,7 @@ impl ContainerService for LocalContainerService {
|
||||
|
||||
// Handle merged attempts (static diff)
|
||||
if let Some(merge_commit_id) = &task_attempt.merge_commit {
|
||||
return self.create_merged_diff_stream(
|
||||
&project_repo_path,
|
||||
merge_commit_id,
|
||||
&task_attempt.base_branch,
|
||||
);
|
||||
return self.create_merged_diff_stream(&project_repo_path, merge_commit_id);
|
||||
}
|
||||
|
||||
let task_branch = task_attempt
|
||||
|
||||
@@ -73,7 +73,6 @@ pub enum DiffTarget<'p> {
|
||||
Commit {
|
||||
repo_path: &'p Path,
|
||||
commit_sha: &'p str,
|
||||
base_branch: &'p str,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -253,39 +252,44 @@ impl GitService {
|
||||
DiffTarget::Commit {
|
||||
repo_path,
|
||||
commit_sha,
|
||||
base_branch,
|
||||
} => {
|
||||
let repo = self.open_repo(repo_path)?;
|
||||
let base_tree = repo
|
||||
.find_branch(base_branch, BranchType::Local)
|
||||
.map_err(|_| GitServiceError::BranchNotFound(base_branch.to_string()))?
|
||||
.get()
|
||||
.peel_to_commit()?
|
||||
.tree()?;
|
||||
|
||||
// Resolve commit and its baseline (the parent before the squash landed)
|
||||
let commit_oid = git2::Oid::from_str(commit_sha).map_err(|_| {
|
||||
GitServiceError::InvalidRepository(format!("Invalid commit SHA: {commit_sha}"))
|
||||
})?;
|
||||
let commit_tree = repo.find_commit(commit_oid)?.tree()?;
|
||||
let commit = repo.find_commit(commit_oid)?;
|
||||
let parent = commit.parent(0).map_err(|_| {
|
||||
GitServiceError::InvalidRepository(
|
||||
"Commit has no parent; cannot diff a squash merge without a baseline"
|
||||
.into(),
|
||||
)
|
||||
})?;
|
||||
|
||||
let mut diff_opts = DiffOptions::new();
|
||||
let parent_tree = parent.tree()?;
|
||||
let commit_tree = commit.tree()?;
|
||||
|
||||
// Diff options
|
||||
let mut diff_opts = git2::DiffOptions::new();
|
||||
diff_opts.include_typechange(true);
|
||||
|
||||
// Add path filtering if specified
|
||||
// Optional path filtering
|
||||
if let Some(paths) = path_filter {
|
||||
for path in paths {
|
||||
diff_opts.pathspec(*path);
|
||||
}
|
||||
}
|
||||
|
||||
// Compute the diff parent -> commit
|
||||
let mut diff = repo.diff_tree_to_tree(
|
||||
Some(&base_tree),
|
||||
Some(&parent_tree),
|
||||
Some(&commit_tree),
|
||||
Some(&mut diff_opts),
|
||||
)?;
|
||||
|
||||
// Enable rename detection
|
||||
let mut find_opts = DiffFindOptions::new();
|
||||
let mut find_opts = git2::DiffFindOptions::new();
|
||||
diff.find_similar(Some(&mut find_opts))?;
|
||||
|
||||
self.convert_diff_to_file_diffs(diff, &repo)
|
||||
|
||||
Reference in New Issue
Block a user