* The user says the trees will be shifted by this much. * Unfortunately we cannot fundamentally tell which one to * be prefixed, as recursive merge can work in either direction. */
| 324 | * be prefixed, as recursive merge can work in either direction. |
| 325 | */ |
| 326 | void shift_tree_by(struct repository *r, |
| 327 | const struct object_id *hash1, |
| 328 | const struct object_id *hash2, |
| 329 | struct object_id *shifted, |
| 330 | const char *shift_prefix) |
| 331 | { |
| 332 | struct object_id sub1, sub2; |
| 333 | unsigned short mode1, mode2; |
| 334 | unsigned candidate = 0; |
| 335 | |
| 336 | /* Can hash2 be a tree at shift_prefix in tree hash1? */ |
| 337 | if (!get_tree_entry(r, hash1, shift_prefix, &sub1, &mode1) && |
| 338 | S_ISDIR(mode1)) |
| 339 | candidate |= 1; |
| 340 | |
| 341 | /* Can hash1 be a tree at shift_prefix in tree hash2? */ |
| 342 | if (!get_tree_entry(r, hash2, shift_prefix, &sub2, &mode2) && |
| 343 | S_ISDIR(mode2)) |
| 344 | candidate |= 2; |
| 345 | |
| 346 | if (candidate == 3) { |
| 347 | /* Both are plausible -- we need to evaluate the score */ |
| 348 | int best_score = score_trees(r, hash1, hash2); |
| 349 | int score; |
| 350 | |
| 351 | candidate = 0; |
| 352 | score = score_trees(r, &sub1, hash2); |
| 353 | if (score > best_score) { |
| 354 | candidate = 1; |
| 355 | best_score = score; |
| 356 | } |
| 357 | score = score_trees(r, &sub2, hash1); |
| 358 | if (score > best_score) |
| 359 | candidate = 2; |
| 360 | } |
| 361 | |
| 362 | if (!candidate) { |
| 363 | /* Neither is plausible -- do not shift */ |
| 364 | oidcpy(shifted, hash2); |
| 365 | return; |
| 366 | } |
| 367 | |
| 368 | if (candidate == 1) |
| 369 | /* |
| 370 | * shift tree2 down by adding shift_prefix above it |
| 371 | * to match tree1. |
| 372 | */ |
| 373 | splice_tree(r, hash1, shift_prefix, hash2, shifted); |
| 374 | else |
| 375 | /* |
| 376 | * shift tree2 up by removing shift_prefix from it |
| 377 | * to match tree1. |
| 378 | */ |
| 379 | oidcpy(shifted, &sub2); |
| 380 | } |
no test coverage detected