MCPcopy Index your code
hub / github.com/AI45Lab/Code / apply_hunks

Function apply_hunks

core/src/tools/builtin/patch.rs:124–192  ·  view source on GitHub ↗

Apply hunks to file content. Hunks are applied bottom-to-top to preserve line numbers.

(content: &str, hunks: &[Hunk])

Source from the content-addressed store, hash-verified

122
123/// Apply hunks to file content. Hunks are applied bottom-to-top to preserve line numbers.
124fn apply_hunks(content: &str, hunks: &[Hunk]) -> Result<String, String> {
125 let mut file_lines: Vec<String> = content.lines().map(|s| s.to_string()).collect();
126
127 // Sort hunks by old_start descending (apply bottom-to-top)
128 let mut sorted_hunks: Vec<&Hunk> = hunks.iter().collect();
129 sorted_hunks.sort_by_key(|h| std::cmp::Reverse(h.old_start));
130
131 for hunk in sorted_hunks {
132 let start_idx = hunk.old_start.saturating_sub(1); // Convert 1-indexed to 0-indexed
133
134 // Verify context lines match (basic verification)
135 for (offset, ctx_line) in &hunk.context {
136 let line_idx = start_idx + offset;
137 if line_idx < file_lines.len() && file_lines[line_idx].trim() != ctx_line.trim() {
138 tracing::warn!(
139 "Context mismatch at line {}: expected {:?}, found {:?}",
140 line_idx + 1,
141 ctx_line,
142 file_lines[line_idx]
143 );
144 }
145 }
146
147 // Find and remove the old lines, then insert new lines
148 let mut lines_to_remove: Vec<usize> = Vec::new();
149 let mut search_idx = start_idx;
150
151 for removal in &hunk.removals {
152 // Find the line to remove starting from search_idx
153 let found_idx = file_lines[search_idx..]
154 .iter()
155 .position(|line| line.trim() == removal.trim())
156 .map(|pos| search_idx + pos);
157 match found_idx {
158 Some(idx) => {
159 lines_to_remove.push(idx);
160 search_idx = idx + 1;
161 }
162 None => {
163 return Err(format!(
164 "Could not find line to remove: {:?} near line {}",
165 removal,
166 start_idx + 1
167 ));
168 }
169 }
170 }
171
172 // Remove lines bottom-to-top
173 lines_to_remove.sort_unstable();
174 lines_to_remove.reverse();
175 for idx in &lines_to_remove {
176 file_lines.remove(*idx);
177 }
178
179 // Insert additions at the position of the first removal (or at start_idx)
180 let insert_at = lines_to_remove
181 .last()

Callers 2

executeMethod · 0.85
test_apply_hunks_simpleFunction · 0.85

Calls 4

removeMethod · 0.80
lenMethod · 0.45
insertMethod · 0.45
cloneMethod · 0.45

Tested by 1

test_apply_hunks_simpleFunction · 0.68