@@ -47,6 +47,13 @@ static int score_matches(unsigned mode1, unsigned mode2, const char *path)
4747 return score ;
4848}
4949
50+ static int base_name_entries_compare (const struct name_entry * a ,
51+ const struct name_entry * b )
52+ {
53+ return base_name_compare (a -> path , tree_entry_len (a ), a -> mode ,
54+ b -> path , tree_entry_len (b ), b -> mode );
55+ }
56+
5057/*
5158 * Inspect two trees, and give a score that tells how similar they are.
5259 */
@@ -71,54 +78,35 @@ static int score_trees(const unsigned char *hash1, const unsigned char *hash2)
7178 if (type != OBJ_TREE )
7279 die ("%s is not a tree" , sha1_to_hex (hash2 ));
7380 init_tree_desc (& two , two_buf , size );
74- while (one .size | two .size ) {
75- const unsigned char * elem1 = elem1 ;
76- const unsigned char * elem2 = elem2 ;
77- const char * path1 = path1 ;
78- const char * path2 = path2 ;
79- unsigned mode1 = mode1 ;
80- unsigned mode2 = mode2 ;
81+ for (;;) {
82+ struct name_entry e1 , e2 ;
83+ int got_entry_from_one = tree_entry (& one , & e1 );
84+ int got_entry_from_two = tree_entry (& two , & e2 );
8185 int cmp ;
8286
83- if (one .size )
84- elem1 = tree_entry_extract (& one , & path1 , & mode1 );
85- if (two .size )
86- elem2 = tree_entry_extract (& two , & path2 , & mode2 );
87-
88- if (!one .size ) {
89- /* two has more entries */
90- score += score_missing (mode2 , path2 );
91- update_tree_entry (& two );
92- continue ;
93- }
94- if (!two .size ) {
87+ if (got_entry_from_one && got_entry_from_two )
88+ cmp = base_name_entries_compare (& e1 , & e2 );
89+ else if (got_entry_from_one )
9590 /* two lacks this entry */
96- score += score_missing (mode1 , path1 );
97- update_tree_entry (& one );
98- continue ;
99- }
100- cmp = base_name_compare (path1 , strlen (path1 ), mode1 ,
101- path2 , strlen (path2 ), mode2 );
102- if (cmp < 0 ) {
91+ cmp = -1 ;
92+ else if (got_entry_from_two )
93+ /* two has more entries */
94+ cmp = 1 ;
95+ else
96+ break ;
97+
98+ if (cmp < 0 )
10399 /* path1 does not appear in two */
104- score += score_missing (mode1 , path1 );
105- update_tree_entry (& one );
106- continue ;
107- }
108- else if (cmp > 0 ) {
100+ score += score_missing (e1 .mode , e1 .path );
101+ else if (cmp > 0 )
109102 /* path2 does not appear in one */
110- score += score_missing (mode2 , path2 );
111- update_tree_entry (& two );
112- continue ;
113- }
114- else if (hashcmp (elem1 , elem2 ))
103+ score += score_missing (e2 .mode , e2 .path );
104+ else if (hashcmp (e1 .sha1 , e2 .sha1 ))
115105 /* they are different */
116- score += score_differs (mode1 , mode2 , path1 );
106+ score += score_differs (e1 . mode , e2 . mode , e1 . path );
117107 else
118108 /* same subtree or blob */
119- score += score_matches (mode1 , mode2 , path1 );
120- update_tree_entry (& one );
121- update_tree_entry (& two );
109+ score += score_matches (e1 .mode , e2 .mode , e1 .path );
122110 }
123111 free (one_buf );
124112 free (two_buf );
0 commit comments