1#include"cache.h" 2#include"tree.h" 3#include"tree-walk.h" 4#include"object-store.h" 5 6static intscore_missing(unsigned mode) 7{ 8int score; 9 10if(S_ISDIR(mode)) 11 score = -1000; 12else if(S_ISLNK(mode)) 13 score = -500; 14else 15 score = -50; 16return score; 17} 18 19static intscore_differs(unsigned mode1,unsigned mode2) 20{ 21int score; 22 23if(S_ISDIR(mode1) !=S_ISDIR(mode2)) 24 score = -100; 25else if(S_ISLNK(mode1) !=S_ISLNK(mode2)) 26 score = -50; 27else 28 score = -5; 29return score; 30} 31 32static intscore_matches(unsigned mode1,unsigned mode2) 33{ 34int score; 35 36/* Heh, we found SHA-1 collisions between different kind of objects */ 37if(S_ISDIR(mode1) !=S_ISDIR(mode2)) 38 score = -100; 39else if(S_ISLNK(mode1) !=S_ISLNK(mode2)) 40 score = -50; 41 42else if(S_ISDIR(mode1)) 43 score =1000; 44else if(S_ISLNK(mode1)) 45 score =500; 46else 47 score =250; 48return score; 49} 50 51static void*fill_tree_desc_strict(struct tree_desc *desc, 52const struct object_id *hash) 53{ 54void*buffer; 55enum object_type type; 56unsigned long size; 57 58 buffer =read_object_file(hash, &type, &size); 59if(!buffer) 60die("unable to read tree (%s)",oid_to_hex(hash)); 61if(type != OBJ_TREE) 62die("%sis not a tree",oid_to_hex(hash)); 63init_tree_desc(desc, buffer, size); 64return buffer; 65} 66 67static intbase_name_entries_compare(const struct name_entry *a, 68const struct name_entry *b) 69{ 70returnbase_name_compare(a->path,tree_entry_len(a), a->mode, 71 b->path,tree_entry_len(b), b->mode); 72} 73 74/* 75 * Inspect two trees, and give a score that tells how similar they are. 76 */ 77static intscore_trees(const struct object_id *hash1,const struct object_id *hash2) 78{ 79struct tree_desc one; 80struct tree_desc two; 81void*one_buf =fill_tree_desc_strict(&one, hash1); 82void*two_buf =fill_tree_desc_strict(&two, hash2); 83int score =0; 84 85for(;;) { 86int cmp; 87 88if(one.size && two.size) 89 cmp =base_name_entries_compare(&one.entry, &two.entry); 90else if(one.size) 91/* two lacks this entry */ 92 cmp = -1; 93else if(two.size) 94/* two has more entries */ 95 cmp =1; 96else 97break; 98 99if(cmp <0) { 100/* path1 does not appear in two */ 101 score +=score_missing(one.entry.mode); 102update_tree_entry(&one); 103}else if(cmp >0) { 104/* path2 does not appear in one */ 105 score +=score_missing(two.entry.mode); 106update_tree_entry(&two); 107}else{ 108/* path appears in both */ 109if(!oideq(&one.entry.oid, &two.entry.oid)) { 110/* they are different */ 111 score +=score_differs(one.entry.mode, 112 two.entry.mode); 113}else{ 114/* same subtree or blob */ 115 score +=score_matches(one.entry.mode, 116 two.entry.mode); 117} 118update_tree_entry(&one); 119update_tree_entry(&two); 120} 121} 122free(one_buf); 123free(two_buf); 124return score; 125} 126 127/* 128 * Match one itself and its subtrees with two and pick the best match. 129 */ 130static voidmatch_trees(const struct object_id *hash1, 131const struct object_id *hash2, 132int*best_score, 133char**best_match, 134const char*base, 135int recurse_limit) 136{ 137struct tree_desc one; 138void*one_buf =fill_tree_desc_strict(&one, hash1); 139 140while(one.size) { 141const char*path; 142const struct object_id *elem; 143unsigned short mode; 144int score; 145 146 elem =tree_entry_extract(&one, &path, &mode); 147if(!S_ISDIR(mode)) 148goto next; 149 score =score_trees(elem, hash2); 150if(*best_score < score) { 151free(*best_match); 152*best_match =xstrfmt("%s%s", base, path); 153*best_score = score; 154} 155if(recurse_limit) { 156char*newbase =xstrfmt("%s%s/", base, path); 157match_trees(elem, hash2, best_score, best_match, 158 newbase, recurse_limit -1); 159free(newbase); 160} 161 162 next: 163update_tree_entry(&one); 164} 165free(one_buf); 166} 167 168/* 169 * A tree "oid1" has a subdirectory at "prefix". Come up with a tree object by 170 * replacing it with another tree "oid2". 171 */ 172static intsplice_tree(const struct object_id *oid1,const char*prefix, 173const struct object_id *oid2,struct object_id *result) 174{ 175char*subpath; 176int toplen; 177char*buf; 178unsigned long sz; 179struct tree_desc desc; 180unsigned char*rewrite_here; 181const struct object_id *rewrite_with; 182struct object_id subtree; 183enum object_type type; 184int status; 185 186 subpath =strchrnul(prefix,'/'); 187 toplen = subpath - prefix; 188if(*subpath) 189 subpath++; 190 191 buf =read_object_file(oid1, &type, &sz); 192if(!buf) 193die("cannot read tree%s",oid_to_hex(oid1)); 194init_tree_desc(&desc, buf, sz); 195 196 rewrite_here = NULL; 197while(desc.size) { 198const char*name; 199unsigned short mode; 200 201tree_entry_extract(&desc, &name, &mode); 202if(strlen(name) == toplen && 203!memcmp(name, prefix, toplen)) { 204if(!S_ISDIR(mode)) 205die("entry%sin tree%sis not a tree", name, 206oid_to_hex(oid1)); 207 208/* 209 * We cast here for two reasons: 210 * 211 * - to flip the "char *" (for the path) to "unsigned 212 * char *" (for the hash stored after it) 213 * 214 * - to discard the "const"; this is OK because we 215 * know it points into our non-const "buf" 216 */ 217 rewrite_here = (unsigned char*)(desc.entry.path + 218strlen(desc.entry.path) + 2191); 220break; 221} 222update_tree_entry(&desc); 223} 224if(!rewrite_here) 225die("entry %.*s not found in tree%s", toplen, prefix, 226oid_to_hex(oid1)); 227if(*subpath) { 228struct object_id tree_oid; 229hashcpy(tree_oid.hash, rewrite_here); 230 status =splice_tree(&tree_oid, subpath, oid2, &subtree); 231if(status) 232return status; 233 rewrite_with = &subtree; 234}else{ 235 rewrite_with = oid2; 236} 237hashcpy(rewrite_here, rewrite_with->hash); 238 status =write_object_file(buf, sz, tree_type, result); 239free(buf); 240return status; 241} 242 243/* 244 * We are trying to come up with a merge between one and two that 245 * results in a tree shape similar to one. The tree two might 246 * correspond to a subtree of one, in which case it needs to be 247 * shifted down by prefixing otherwise empty directories. On the 248 * other hand, it could cover tree one and we might need to pick a 249 * subtree of it. 250 */ 251voidshift_tree(const struct object_id *hash1, 252const struct object_id *hash2, 253struct object_id *shifted, 254int depth_limit) 255{ 256char*add_prefix; 257char*del_prefix; 258int add_score, del_score; 259 260/* 261 * NEEDSWORK: this limits the recursion depth to hardcoded 262 * value '2' to avoid excessive overhead. 263 */ 264if(!depth_limit) 265 depth_limit =2; 266 267 add_score = del_score =score_trees(hash1, hash2); 268 add_prefix =xcalloc(1,1); 269 del_prefix =xcalloc(1,1); 270 271/* 272 * See if one's subtree resembles two; if so we need to prefix 273 * two with a few fake trees to match the prefix. 274 */ 275match_trees(hash1, hash2, &add_score, &add_prefix,"", depth_limit); 276 277/* 278 * See if two's subtree resembles one; if so we need to 279 * pick only subtree of two. 280 */ 281match_trees(hash2, hash1, &del_score, &del_prefix,"", depth_limit); 282 283/* Assume we do not have to do any shifting */ 284oidcpy(shifted, hash2); 285 286if(add_score < del_score) { 287/* We need to pick a subtree of two */ 288unsigned short mode; 289 290if(!*del_prefix) 291return; 292 293if(get_tree_entry(hash2, del_prefix, shifted, &mode)) 294die("cannot find path%sin tree%s", 295 del_prefix,oid_to_hex(hash2)); 296return; 297} 298 299if(!*add_prefix) 300return; 301 302splice_tree(hash1, add_prefix, hash2, shifted); 303} 304 305/* 306 * The user says the trees will be shifted by this much. 307 * Unfortunately we cannot fundamentally tell which one to 308 * be prefixed, as recursive merge can work in either direction. 309 */ 310voidshift_tree_by(const struct object_id *hash1, 311const struct object_id *hash2, 312struct object_id *shifted, 313const char*shift_prefix) 314{ 315struct object_id sub1, sub2; 316unsigned short mode1, mode2; 317unsigned candidate =0; 318 319/* Can hash2 be a tree at shift_prefix in tree hash1? */ 320if(!get_tree_entry(hash1, shift_prefix, &sub1, &mode1) && 321S_ISDIR(mode1)) 322 candidate |=1; 323 324/* Can hash1 be a tree at shift_prefix in tree hash2? */ 325if(!get_tree_entry(hash2, shift_prefix, &sub2, &mode2) && 326S_ISDIR(mode2)) 327 candidate |=2; 328 329if(candidate ==3) { 330/* Both are plausible -- we need to evaluate the score */ 331int best_score =score_trees(hash1, hash2); 332int score; 333 334 candidate =0; 335 score =score_trees(&sub1, hash2); 336if(score > best_score) { 337 candidate =1; 338 best_score = score; 339} 340 score =score_trees(&sub2, hash1); 341if(score > best_score) 342 candidate =2; 343} 344 345if(!candidate) { 346/* Neither is plausible -- do not shift */ 347oidcpy(shifted, hash2); 348return; 349} 350 351if(candidate ==1) 352/* 353 * shift tree2 down by adding shift_prefix above it 354 * to match tree1. 355 */ 356splice_tree(hash1, shift_prefix, hash2, shifted); 357else 358/* 359 * shift tree2 up by removing shift_prefix from it 360 * to match tree1. 361 */ 362oidcpy(shifted, &sub2); 363}