* Inspect two trees, and give a score that tells how similar they are. */
| 83 | * Inspect two trees, and give a score that tells how similar they are. |
| 84 | */ |
| 85 | static int score_trees(struct repository *r, |
| 86 | const struct object_id *hash1, const struct object_id *hash2) |
| 87 | { |
| 88 | struct tree_desc one; |
| 89 | struct tree_desc two; |
| 90 | void *one_buf = fill_tree_desc_strict(r, &one, hash1); |
| 91 | void *two_buf = fill_tree_desc_strict(r, &two, hash2); |
| 92 | int score = 0; |
| 93 | |
| 94 | for (;;) { |
| 95 | int cmp; |
| 96 | |
| 97 | if (one.size && two.size) |
| 98 | cmp = base_name_entries_compare(&one.entry, &two.entry); |
| 99 | else if (one.size) |
| 100 | /* two lacks this entry */ |
| 101 | cmp = -1; |
| 102 | else if (two.size) |
| 103 | /* two has more entries */ |
| 104 | cmp = 1; |
| 105 | else |
| 106 | break; |
| 107 | |
| 108 | if (cmp < 0) { |
| 109 | /* path1 does not appear in two */ |
| 110 | score += score_missing(one.entry.mode); |
| 111 | update_tree_entry(&one); |
| 112 | } else if (cmp > 0) { |
| 113 | /* path2 does not appear in one */ |
| 114 | score += score_missing(two.entry.mode); |
| 115 | update_tree_entry(&two); |
| 116 | } else { |
| 117 | /* path appears in both */ |
| 118 | if (!oideq(&one.entry.oid, &two.entry.oid)) { |
| 119 | /* they are different */ |
| 120 | score += score_differs(one.entry.mode, |
| 121 | two.entry.mode); |
| 122 | } else { |
| 123 | /* same subtree or blob */ |
| 124 | score += score_matches(one.entry.mode, |
| 125 | two.entry.mode); |
| 126 | } |
| 127 | update_tree_entry(&one); |
| 128 | update_tree_entry(&two); |
| 129 | } |
| 130 | } |
| 131 | free(one_buf); |
| 132 | free(two_buf); |
| 133 | return score; |
| 134 | } |
| 135 | |
| 136 | /* |
| 137 | * Match one itself and its subtrees with two and pick the best match. |
no test coverage detected