185
* tree object by replacing it with another tree "hash2".
186
*/
187
static int splice_tree(const unsigned char *hash1,
188
- char *prefix,
188
+ const char *prefix,
189
const unsigned char *hash2,
190
unsigned char *result)
191
{
264
char *del_prefix;
265
int add_score, del_score;
266
267
+ /*
268
+ * NEEDSWORK: this limits the recursion depth to hardcoded
269
+ * value '2' to avoid excessive overhead.
270
+ */
271
+ if (!depth_limit)
272
+ depth_limit = 2;
273
+
274
add_score = del_score = score_trees(hash1, hash2);
275
add_prefix = xcalloc(1, 1);
276
del_prefix = xcalloc(1, 1);
308
309
splice_tree(hash1, add_prefix, hash2, shifted);
310
}
311
+
312
+/*
313
+ * The user says the trees will be shifted by this much.
314
+ * Unfortunately we cannot fundamentally tell which one to
315
+ * be prefixed, as recursive merge can work in either direction.
316
+ */
317
+void shift_tree_by(const unsigned char *hash1,
318
+ const unsigned char *hash2,
319
+ unsigned char *shifted,
320
+ const char *shift_prefix)
321
+{
322
+ unsigned char sub1[20], sub2[20];
323
+ unsigned mode1, mode2;
324
+ unsigned candidate = 0;
325
+
326
+ /* Can hash2 be a tree at shift_prefix in tree hash1? */
327
+ if (!get_tree_entry(hash1, shift_prefix, sub1, &mode1) &&
328
+ S_ISDIR(mode1))
329
+ candidate |= 1;
330
+
331
+ /* Can hash1 be a tree at shift_prefix in tree hash2? */
332
+ if (!get_tree_entry(hash2, shift_prefix, sub2, &mode2) &&
333
+ S_ISDIR(mode2))
334
+ candidate |= 2;
335
+
336
+ if (candidate == 3) {
337
+ /* Both are plausible -- we need to evaluate the score */
338
+ int best_score = score_trees(hash1, hash2);
339
+ int score;
340
+
341
+ candidate = 0;
342
+ score = score_trees(sub1, hash2);
343
+ if (score > best_score) {
344
+ candidate = 1;
345
+ best_score = score;
346
+ }
347
+ score = score_trees(sub2, hash1);
348
+ if (score > best_score)
349
+ candidate = 2;
350
+ }
351
+
352
+ if (!candidate) {
353
+ /* Neither is plausible -- do not shift */
354
+ hashcpy(shifted, hash2);
355
+ return;
356
+ }
357
+
358
+ if (candidate == 1)
359
+ /*
360
+ * shift tree2 down by adding shift_prefix above it
361
+ * to match tree1.
362
+ */
363
+ splice_tree(hash1, shift_prefix, hash2, shifted);
364
+ else
365
+ /*
366
+ * shift tree2 up by removing shift_prefix from it
367
+ * to match tree1.
368
+ */
369
+ hashcpy(shifted, sub2);
370
+}