Raw
1 /*
2 * Helper functions for tree diff generation
3 */
4
5 #define DISABLE_SIGN_COMPARE_WARNINGS
6
7 #include "git-compat-util.h"
8 #include "diff.h"
9 #include "diffcore.h"
10 #include "hash.h"
11 #include "tree.h"
12 #include "tree-walk.h"
13 #include "repository.h"
14 #include "dir.h"
15
16 /*
17 * Some mode bits are also used internally for computations.
18 *
19 * They *must* not overlap with any valid modes, and they *must* not be emitted
20 * to outside world - i.e. appear on disk or network. In other words, it's just
21 * temporary fields, which we internally use, but they have to stay in-house.
22 *
23 * ( such approach is valid, as standard S_IF* fits into 16 bits, and in Git
24 * codebase mode is `unsigned int` which is assumed to be at least 32 bits )
25 */
26
27 #define S_DIFFTREE_IFXMIN_NEQ 0x80000000
28
29 /*
30 * internal mode marker, saying a tree entry != entry of tp[imin]
31 * (see ll_diff_tree_paths for what it means there)
32 *
33 * we will update/use/emit entry for diff only with it unset.
34 */
35 #define S_IFXMIN_NEQ S_DIFFTREE_IFXMIN_NEQ
36
37 #define FAST_ARRAY_ALLOC(x, nr) do { \
38 if ((nr) <= 2) \
39 (x) = xalloca((nr) * sizeof(*(x))); \
40 else \
41 ALLOC_ARRAY((x), nr); \
42 } while(0)
43 #define FAST_ARRAY_FREE(x, nr) do { \
44 if ((nr) <= 2) \
45 xalloca_free((x)); \
46 else \
47 free((x)); \
48 } while(0)
49
50 /* Returns true if and only if "dir" is a leading directory of "path" */
51 static int is_dir_prefix(const char *path, const char *dir, int dirlen)
52 {
53 return !strncmp(path, dir, dirlen) &&
54 (!path[dirlen] || path[dirlen] == '/');
55 }
56
57 static int check_recursion_depth(const struct strbuf *name,
58 const struct pathspec *ps,
59 int max_depth)
60 {
61 int i;
62
63 if (!ps->nr)
64 return within_depth(name->buf, name->len, 1, max_depth);
65
66 /*
67 * We look through the pathspecs in reverse-sorted order, because we
68 * want to find the longest match first (e.g., "a/b" is better for
69 * checking depth than "a/b/c").
70 */
71 for (i = ps->nr - 1; i >= 0; i--) {
72 const struct pathspec_item *item = ps->items+i;
73
74 /*
75 * If the name to match is longer than the pathspec, then we
76 * are only interested if the pathspec matches and we are
77 * within the allowed depth.
78 */
79 if (name->len >= item->len) {
80 if (!is_dir_prefix(name->buf, item->match, item->len))
81 continue;
82 return within_depth(name->buf + item->len,
83 name->len - item->len,
84 1, max_depth);
85 }
86
87 /*
88 * Otherwise, our name is shorter than the pathspec. We need to
89 * check if it is a prefix of the pathspec; if so, we must
90 * always recurse in order to process further (the resulting
91 * paths we find might or might not match our pathspec, but we
92 * cannot know until we recurse).
93 */
94 if (is_dir_prefix(item->match, name->buf, name->len))
95 return 1;
96 }
97 return 0;
98 }
99
100 static int should_recurse(const struct strbuf *name, struct diff_options *opt)
101 {
102 if (!opt->flags.recursive)
103 return 0;
104 if (!opt->max_depth_valid)
105 return 1;
106
107 /*
108 * We catch this during diff_setup_done, but let's double-check
109 * against any internal munging.
110 */
111 if (opt->pathspec.has_wildcard)
112 BUG("wildcard pathspecs are incompatible with max-depth");
113
114 return check_recursion_depth(name, &opt->pathspec, opt->max_depth);
115 }
116
117 static void ll_diff_tree_paths(
118 struct combine_diff_path ***tail, const struct object_id *oid,
119 const struct object_id **parents_oid, int nparent,
120 struct strbuf *base, struct diff_options *opt,
121 int depth);
122 static void ll_diff_tree_oid(const struct object_id *old_oid,
123 const struct object_id *new_oid,
124 struct strbuf *base, struct diff_options *opt);
125
126 /*
127 * Compare two tree entries, taking into account only path/S_ISDIR(mode),
128 * but not their sha1's.
129 *
130 * NOTE files and directories *always* compare differently, even when having
131 * the same name - thanks to base_name_compare().
132 *
133 * NOTE empty (=invalid) descriptor(s) take part in comparison as +infty,
134 * so that they sort *after* valid tree entries.
135 *
136 * Due to this convention, if trees are scanned in sorted order, all
137 * non-empty descriptors will be processed first.
138 */
139 static int tree_entry_pathcmp(struct tree_desc *t1, struct tree_desc *t2)
140 {
141 struct name_entry *e1, *e2;
142 int cmp;
143
144 /* empty descriptors sort after valid tree entries */
145 if (!t1->size)
146 return t2->size ? 1 : 0;
147 else if (!t2->size)
148 return -1;
149
150 e1 = &t1->entry;
151 e2 = &t2->entry;
152 cmp = base_name_compare(e1->path, tree_entry_len(e1), e1->mode,
153 e2->path, tree_entry_len(e2), e2->mode);
154 return cmp;
155 }
156
157
158 /*
159 * convert path -> opt->diff_*() callbacks
160 *
161 * emits diff to first parent only, and tells diff tree-walker that we are done
162 * with p and it can be freed.
163 */
164 static int emit_diff_first_parent_only(struct diff_options *opt, struct combine_diff_path *p)
165 {
166 struct combine_diff_parent *p0 = &p->parent[0];
167 if (p->mode && p0->mode) {
168 opt->change(opt, p0->mode, p->mode, &p0->oid, &p->oid,
169 1, 1, p->path, 0, 0);
170 }
171 else {
172 const struct object_id *oid;
173 unsigned int mode;
174 int addremove;
175
176 if (p->mode) {
177 addremove = '+';
178 oid = &p->oid;
179 mode = p->mode;
180 } else {
181 addremove = '-';
182 oid = &p0->oid;
183 mode = p0->mode;
184 }
185
186 opt->add_remove(opt, addremove, mode, oid, 1, p->path, 0);
187 }
188
189 return 0; /* we are done with p */
190 }
191
192
193 /*
194 * new path should be added to combine diff
195 *
196 * 3 cases on how/when it should be called and behaves:
197 *
198 * t, !tp -> path added, all parents lack it
199 * !t, tp -> path removed from all parents
200 * t, tp -> path modified/added
201 * (M for tp[i]=tp[imin], A otherwise)
202 */
203 static void emit_path(struct combine_diff_path ***tail,
204 struct strbuf *base, struct diff_options *opt,
205 int nparent, struct tree_desc *t, struct tree_desc *tp,
206 int imin, int depth)
207 {
208 unsigned short mode;
209 const char *path;
210 const struct object_id *oid;
211 int pathlen;
212 int old_baselen = base->len;
213 int i, isdir, recurse = 0, emitthis = 1;
214
215 /* at least something has to be valid */
216 assert(t || tp);
217
218 if (t) {
219 /* path present in resulting tree */
220 oid = tree_entry_extract(t, &path, &mode);
221 pathlen = tree_entry_len(&t->entry);
222 isdir = S_ISDIR(mode);
223 } else {
224 /*
225 * a path was removed - take path from imin parent. Also take
226 * mode from that parent, to decide on recursion(1).
227 *
228 * 1) all modes for tp[i]=tp[imin] should be the same wrt
229 * S_ISDIR, thanks to base_name_compare().
230 */
231 tree_entry_extract(&tp[imin], &path, &mode);
232 pathlen = tree_entry_len(&tp[imin].entry);
233
234 isdir = S_ISDIR(mode);
235 oid = NULL;
236 mode = 0;
237 }
238
239 if (isdir) {
240 strbuf_add(base, path, pathlen);
241 if (should_recurse(base, opt)) {
242 recurse = 1;
243 emitthis = opt->flags.tree_in_recursive;
244 }
245 strbuf_setlen(base, old_baselen);
246 }
247
248 if (emitthis) {
249 int keep;
250 struct combine_diff_path *p;
251
252 strbuf_add(base, path, pathlen);
253 p = combine_diff_path_new(base->buf, base->len, mode,
254 oid ? oid : null_oid(opt->repo->hash_algo),
255 nparent);
256 strbuf_setlen(base, old_baselen);
257
258 for (i = 0; i < nparent; ++i) {
259 /*
260 * tp[i] is valid, if present and if tp[i]==tp[imin] -
261 * otherwise, we should ignore it.
262 */
263 int tpi_valid = tp && !(tp[i].entry.mode & S_IFXMIN_NEQ);
264
265 const struct object_id *oid_i;
266 unsigned mode_i;
267
268 p->parent[i].status =
269 !t ? DIFF_STATUS_DELETED :
270 tpi_valid ?
271 DIFF_STATUS_MODIFIED :
272 DIFF_STATUS_ADDED;
273
274 if (tpi_valid) {
275 oid_i = &tp[i].entry.oid;
276 mode_i = tp[i].entry.mode;
277 }
278 else {
279 oid_i = null_oid(opt->repo->hash_algo);
280 mode_i = 0;
281 }
282
283 p->parent[i].mode = mode_i;
284 oidcpy(&p->parent[i].oid, oid_i);
285 }
286
287 keep = 1;
288 if (opt->pathchange)
289 keep = opt->pathchange(opt, p);
290
291 if (keep) {
292 **tail = p;
293 *tail = &p->next;
294 } else {
295 free(p);
296 }
297 }
298
299 if (recurse) {
300 const struct object_id **parents_oid;
301
302 FAST_ARRAY_ALLOC(parents_oid, nparent);
303 for (i = 0; i < nparent; ++i) {
304 /* same rule as in emitthis */
305 int tpi_valid = tp && !(tp[i].entry.mode & S_IFXMIN_NEQ);
306
307 parents_oid[i] = tpi_valid ? &tp[i].entry.oid : NULL;
308 }
309
310 strbuf_add(base, path, pathlen);
311 strbuf_addch(base, '/');
312 ll_diff_tree_paths(tail, oid, parents_oid, nparent, base, opt,
313 depth + 1);
314 FAST_ARRAY_FREE(parents_oid, nparent);
315 }
316
317 strbuf_setlen(base, old_baselen);
318 }
319
320 static void skip_uninteresting(struct tree_desc *t, struct strbuf *base,
321 struct diff_options *opt)
322 {
323 enum interesting match;
324
325 while (t->size) {
326 match = tree_entry_interesting(opt->repo->index, &t->entry,
327 base, &opt->pathspec);
328 if (match) {
329 if (match == all_entries_not_interesting)
330 t->size = 0;
331 break;
332 }
333 update_tree_entry(t);
334 }
335 }
336
337
338 /*
339 * generate paths for combined diff D(sha1,parents_oid[])
340 *
341 * Resulting paths are appended to combine_diff_path linked list, and also, are
342 * emitted on the go via opt->pathchange() callback, so it is possible to
343 * process the result as batch or incrementally.
344 *
345 * The paths are generated scanning new tree and all parents trees
346 * simultaneously, similarly to what diff_tree() was doing for 2 trees.
347 * The theory behind such scan is as follows:
348 *
349 *
350 * D(T,P1...Pn) calculation scheme
351 * -------------------------------
352 *
353 * D(T,P1...Pn) = D(T,P1) ^ ... ^ D(T,Pn) (regarding resulting paths set)
354 *
355 * D(T,Pj) - diff between T..Pj
356 * D(T,P1...Pn) - combined diff from T to parents P1,...,Pn
357 *
358 *
359 * We start from all trees, which are sorted, and compare their entries in
360 * lock-step:
361 *
362 * T P1 Pn
363 * - - -
364 * |t| |p1| |pn|
365 * |-| |--| ... |--| imin = argmin(p1...pn)
366 * | | | | | |
367 * |-| |--| |--|
368 * |.| |. | |. |
369 * . . .
370 * . . .
371 *
372 * at any time there could be 3 cases:
373 *
374 * 1) t < p[imin];
375 * 2) t > p[imin];
376 * 3) t = p[imin].
377 *
378 * Schematic deduction of what every case means, and what to do, follows:
379 *
380 * 1) t < p[imin] -> ∀j t ∉ Pj -> "+t" ∈ D(T,Pj) -> D += "+t"; t↓
381 *
382 * 2) t > p[imin]
383 *
384 * 2.1) ∃j: pj > p[imin] -> "-p[imin]" ∉ D(T,Pj) -> D += ø; ∀ pi=p[imin] pi↓
385 * 2.2) ∀i pi = p[imin] -> pi ∉ T -> "-pi" ∈ D(T,Pi) -> D += "-p[imin]"; ∀i pi↓
386 *
387 * 3) t = p[imin]
388 *
389 * 3.1) ∃j: pj > p[imin] -> "+t" ∈ D(T,Pj) -> only pi=p[imin] remains to investigate
390 * 3.2) pi = p[imin] -> investigate δ(t,pi)
391 * |
392 * |
393 * v
394 *
395 * 3.1+3.2) looking at δ(t,pi) ∀i: pi=p[imin] - if all != ø ->
396 *
397 * ⎧δ(t,pi) - if pi=p[imin]
398 * -> D += ⎨
399 * ⎩"+t" - if pi>p[imin]
400 *
401 *
402 * in any case t↓ ∀ pi=p[imin] pi↓
403 *
404 *
405 * ~~~~~~~~
406 *
407 * NOTE
408 *
409 * Usual diff D(A,B) is by definition the same as combined diff D(A,[B]),
410 * so this diff paths generator can, and is used, for plain diffs
411 * generation too.
412 *
413 * Please keep attention to the common D(A,[B]) case when working on the
414 * code, in order not to slow it down.
415 *
416 * NOTE
417 * nparent must be > 0.
418 */
419
420
421 /* ∀ pi=p[imin] pi↓ */
422 static inline void update_tp_entries(struct tree_desc *tp, int nparent)
423 {
424 int i;
425 for (i = 0; i < nparent; ++i)
426 if (!(tp[i].entry.mode & S_IFXMIN_NEQ))
427 update_tree_entry(&tp[i]);
428 }
429
430 static void ll_diff_tree_paths(
431 struct combine_diff_path ***tail, const struct object_id *oid,
432 const struct object_id **parents_oid, int nparent,
433 struct strbuf *base, struct diff_options *opt,
434 int depth)
435 {
436 struct tree_desc t, *tp;
437 void *ttree, **tptree;
438 int i;
439
440 if (depth > opt->repo->settings.max_allowed_tree_depth)
441 die("exceeded maximum allowed tree depth");
442
443 FAST_ARRAY_ALLOC(tp, nparent);
444 FAST_ARRAY_ALLOC(tptree, nparent);
445
446 /*
447 * load parents first, as they are probably already cached.
448 *
449 * ( log_tree_diff() parses commit->parent before calling here via
450 * diff_tree_oid(parent, commit) )
451 */
452 for (i = 0; i < nparent; ++i)
453 tptree[i] = fill_tree_descriptor(opt->repo, &tp[i], parents_oid[i]);
454 ttree = fill_tree_descriptor(opt->repo, &t, oid);
455
456 /* Enable recursion indefinitely */
457 opt->pathspec.recursive = opt->flags.recursive;
458
459 for (;;) {
460 int imin, cmp;
461
462 if (diff_can_quit_early(opt))
463 break;
464
465 if (opt->max_changes && diff_queued_diff.nr > opt->max_changes)
466 break;
467
468 if (opt->pathspec.nr) {
469 skip_uninteresting(&t, base, opt);
470 for (i = 0; i < nparent; i++)
471 skip_uninteresting(&tp[i], base, opt);
472 }
473
474 /* comparing is finished when all trees are done */
475 if (!t.size) {
476 int done = 1;
477 for (i = 0; i < nparent; ++i)
478 if (tp[i].size) {
479 done = 0;
480 break;
481 }
482 if (done)
483 break;
484 }
485
486 /*
487 * lookup imin = argmin(p1...pn),
488 * mark entries whether they =p[imin] along the way
489 */
490 imin = 0;
491 tp[0].entry.mode &= ~S_IFXMIN_NEQ;
492
493 for (i = 1; i < nparent; ++i) {
494 cmp = tree_entry_pathcmp(&tp[i], &tp[imin]);
495 if (cmp < 0) {
496 imin = i;
497 tp[i].entry.mode &= ~S_IFXMIN_NEQ;
498 }
499 else if (cmp == 0) {
500 tp[i].entry.mode &= ~S_IFXMIN_NEQ;
501 }
502 else {
503 tp[i].entry.mode |= S_IFXMIN_NEQ;
504 }
505 }
506
507 /* fixup markings for entries before imin */
508 for (i = 0; i < imin; ++i)
509 tp[i].entry.mode |= S_IFXMIN_NEQ; /* pi > p[imin] */
510
511
512
513 /* compare t vs p[imin] */
514 cmp = tree_entry_pathcmp(&t, &tp[imin]);
515
516 /* t = p[imin] */
517 if (cmp == 0) {
518 /* are either pi > p[imin] or diff(t,pi) != ø ? */
519 if (!opt->flags.find_copies_harder) {
520 for (i = 0; i < nparent; ++i) {
521 /* p[i] > p[imin] */
522 if (tp[i].entry.mode & S_IFXMIN_NEQ)
523 continue;
524
525 /* diff(t,pi) != ø */
526 if (!oideq(&t.entry.oid, &tp[i].entry.oid) ||
527 (t.entry.mode != tp[i].entry.mode))
528 continue;
529
530 goto skip_emit_t_tp;
531 }
532 }
533
534 /* D += {δ(t,pi) if pi=p[imin]; "+a" if pi > p[imin]} */
535 emit_path(tail, base, opt, nparent,
536 &t, tp, imin, depth);
537
538 skip_emit_t_tp:
539 /* t↓, ∀ pi=p[imin] pi↓ */
540 update_tree_entry(&t);
541 update_tp_entries(tp, nparent);
542 }
543
544 /* t < p[imin] */
545 else if (cmp < 0) {
546 /* D += "+t" */
547 emit_path(tail, base, opt, nparent,
548 &t, /*tp=*/NULL, -1, depth);
549
550 /* t↓ */
551 update_tree_entry(&t);
552 }
553
554 /* t > p[imin] */
555 else {
556 /* ∀i pi=p[imin] -> D += "-p[imin]" */
557 if (!opt->flags.find_copies_harder) {
558 for (i = 0; i < nparent; ++i)
559 if (tp[i].entry.mode & S_IFXMIN_NEQ)
560 goto skip_emit_tp;
561 }
562
563 emit_path(tail, base, opt, nparent,
564 /*t=*/NULL, tp, imin, depth);
565
566 skip_emit_tp:
567 /* ∀ pi=p[imin] pi↓ */
568 update_tp_entries(tp, nparent);
569 }
570 }
571
572 free(ttree);
573 for (i = nparent-1; i >= 0; i--)
574 free(tptree[i]);
575 FAST_ARRAY_FREE(tptree, nparent);
576 FAST_ARRAY_FREE(tp, nparent);
577 }
578
579 struct combine_diff_path *diff_tree_paths(
580 const struct object_id *oid,
581 const struct object_id **parents_oid, int nparent,
582 struct strbuf *base, struct diff_options *opt)
583 {
584 struct combine_diff_path *head = NULL, **tail = &head;
585 ll_diff_tree_paths(&tail, oid, parents_oid, nparent, base, opt, 0);
586 return head;
587 }
588
589 /*
590 * Does it look like the resulting diff might be due to a rename?
591 * - single entry
592 * - not a valid previous file
593 */
594 static inline int diff_might_be_rename(void)
595 {
596 return diff_queued_diff.nr == 1 &&
597 !DIFF_FILE_VALID(diff_queued_diff.queue[0]->one);
598 }
599
600 static void try_to_follow_renames(const struct object_id *old_oid,
601 const struct object_id *new_oid,
602 struct strbuf *base, struct diff_options *opt)
603 {
604 struct diff_options diff_opts;
605 struct diff_queue_struct *q = &diff_queued_diff;
606 struct diff_filepair *choice;
607 int i;
608
609 /*
610 * follow-rename code is very specific, we need exactly one
611 * path. Magic that matches more than one path is not
612 * supported.
613 */
614 GUARD_PATHSPEC(&opt->pathspec, PATHSPEC_FROMTOP | PATHSPEC_LITERAL);
615 #if 0
616 /*
617 * We should reject wildcards as well. Unfortunately we
618 * haven't got a reliable way to detect that 'foo\*bar' in
619 * fact has no wildcards. nowildcard_len is merely a hint for
620 * optimization. Let it slip for now until wildmatch is taught
621 * about dry-run mode and returns wildcard info.
622 */
623 if (opt->pathspec.has_wildcard)
624 BUG("wildcards are not supported");
625 #endif
626
627 /* Remove the file creation entry from the diff queue, and remember it */
628 choice = q->queue[0];
629 q->nr = 0;
630
631 repo_diff_setup(opt->repo, &diff_opts);
632 diff_opts.flags.recursive = 1;
633 diff_opts.flags.find_copies_harder = 1;
634 diff_opts.output_format = DIFF_FORMAT_NO_OUTPUT;
635 diff_opts.single_follow = opt->pathspec.items[0].match;
636 diff_opts.break_opt = opt->break_opt;
637 diff_opts.rename_score = opt->rename_score;
638 diff_setup_done(&diff_opts);
639 ll_diff_tree_oid(old_oid, new_oid, base, &diff_opts);
640 diffcore_std(&diff_opts);
641 clear_pathspec(&diff_opts.pathspec);
642
643 /* Go through the new set of filepairing, and see if we find a more interesting one */
644 opt->found_follow = 0;
645 for (i = 0; i < q->nr; i++) {
646 struct diff_filepair *p = q->queue[i];
647
648 /*
649 * Found a source? Not only do we use that for the new
650 * diff_queued_diff, we will also use that as the path in
651 * the future!
652 */
653 if ((p->status == 'R' || p->status == 'C') &&
654 !strcmp(p->two->path, opt->pathspec.items[0].match)) {
655 const char *path[2];
656
657 /* Switch the file-pairs around */
658 q->queue[i] = choice;
659 choice = p;
660
661 /* Update the path we use from now on.. */
662 path[0] = p->one->path;
663 path[1] = NULL;
664 clear_pathspec(&opt->pathspec);
665 parse_pathspec(&opt->pathspec,
666 PATHSPEC_ALL_MAGIC & ~PATHSPEC_LITERAL,
667 PATHSPEC_LITERAL_PATH, "", path);
668
669 /*
670 * The caller expects us to return a set of vanilla
671 * filepairs to let a later call to diffcore_std()
672 * it makes to sort the renames out (among other
673 * things), but we already have found renames
674 * ourselves; signal diffcore_std() not to muck with
675 * rename information.
676 */
677 opt->found_follow = 1;
678 break;
679 }
680 }
681
682 /*
683 * Then, discard all the non-relevant file pairs...
684 */
685 for (i = 0; i < q->nr; i++) {
686 struct diff_filepair *p = q->queue[i];
687 diff_free_filepair(p);
688 }
689
690 /*
691 * .. and re-instate the one we want (which might be either the
692 * original one, or the rename/copy we found)
693 */
694 q->queue[0] = choice;
695 q->nr = 1;
696 }
697
698 static void ll_diff_tree_oid(const struct object_id *old_oid,
699 const struct object_id *new_oid,
700 struct strbuf *base, struct diff_options *opt)
701 {
702 struct combine_diff_path *paths, *p;
703 pathchange_fn_t pathchange_old = opt->pathchange;
704
705 opt->pathchange = emit_diff_first_parent_only;
706 paths = diff_tree_paths(new_oid, &old_oid, 1, base, opt);
707
708 for (p = paths; p;) {
709 struct combine_diff_path *pprev = p;
710 p = p->next;
711 free(pprev);
712 }
713
714 opt->pathchange = pathchange_old;
715 }
716
717 void diff_tree_oid(const struct object_id *old_oid,
718 const struct object_id *new_oid,
719 const char *base_str, struct diff_options *opt)
720 {
721 struct strbuf base;
722
723 strbuf_init(&base, PATH_MAX);
724 strbuf_addstr(&base, base_str);
725
726 ll_diff_tree_oid(old_oid, new_oid, &base, opt);
727 if (!*base_str && opt->flags.follow_renames && diff_might_be_rename())
728 try_to_follow_renames(old_oid, new_oid, &base, opt);
729
730 strbuf_release(&base);
731 }
732
733 void diff_root_tree_oid(const struct object_id *new_oid,
734 const char *base,
735 struct diff_options *opt)
736 {
737 diff_tree_oid(NULL, new_oid, base, opt);
738 }