@@ -632,7 +632,7 @@ static int unpack_index_entry(struct cache_entry *ce,
632632 return ret ;
633633}
634634
635- static int find_cache_pos (struct traverse_info * , const struct name_entry * );
635+ static int find_cache_pos (struct traverse_info * , const char * p , size_t len );
636636
637637static void restore_cache_bottom (struct traverse_info * info , int bottom )
638638{
@@ -651,7 +651,7 @@ static int switch_cache_bottom(struct traverse_info *info)
651651 if (o -> diff_index_cached )
652652 return 0 ;
653653 ret = o -> cache_bottom ;
654- pos = find_cache_pos (info -> prev , & info -> name );
654+ pos = find_cache_pos (info -> prev , info -> name , info -> namelen );
655655
656656 if (pos < -1 )
657657 o -> cache_bottom = -2 - pos ;
@@ -686,21 +686,19 @@ static int index_pos_by_traverse_info(struct name_entry *names,
686686 struct traverse_info * info )
687687{
688688 struct unpack_trees_options * o = info -> data ;
689- int len = traverse_path_len (info , names );
690- char * name = xmalloc (len + 1 /* slash */ + 1 /* NUL */ );
689+ struct strbuf name = STRBUF_INIT ;
691690 int pos ;
692691
693- make_traverse_path (name , info , names );
694- name [len ++ ] = '/' ;
695- name [len ] = '\0' ;
696- pos = index_name_pos (o -> src_index , name , len );
692+ strbuf_make_traverse_path (& name , info , names -> path , names -> pathlen );
693+ strbuf_addch (& name , '/' );
694+ pos = index_name_pos (o -> src_index , name .buf , name .len );
697695 if (pos >= 0 )
698696 BUG ("This is a directory and should not exist in index" );
699697 pos = - pos - 1 ;
700- if (!starts_with (o -> src_index -> cache [pos ]-> name , name ) ||
701- (pos > 0 && starts_with (o -> src_index -> cache [pos - 1 ]-> name , name )))
698+ if (!starts_with (o -> src_index -> cache [pos ]-> name , name . buf ) ||
699+ (pos > 0 && starts_with (o -> src_index -> cache [pos - 1 ]-> name , name . buf )))
702700 BUG ("pos must point at the first entry in this directory" );
703- free ( name );
701+ strbuf_release ( & name );
704702 return pos ;
705703}
706704
@@ -811,8 +809,10 @@ static int traverse_trees_recursive(int n, unsigned long dirmask,
811809 newinfo = * info ;
812810 newinfo .prev = info ;
813811 newinfo .pathspec = info -> pathspec ;
814- newinfo .name = * p ;
815- newinfo .pathlen += tree_entry_len (p ) + 1 ;
812+ newinfo .name = p -> path ;
813+ newinfo .namelen = p -> pathlen ;
814+ newinfo .mode = p -> mode ;
815+ newinfo .pathlen = st_add3 (newinfo .pathlen , tree_entry_len (p ), 1 );
816816 newinfo .df_conflicts |= df_conflicts ;
817817
818818 /*
@@ -863,14 +863,18 @@ static int traverse_trees_recursive(int n, unsigned long dirmask,
863863 * itself - the caller needs to do the final check for the cache
864864 * entry having more data at the end!
865865 */
866- static int do_compare_entry_piecewise (const struct cache_entry * ce , const struct traverse_info * info , const struct name_entry * n )
866+ static int do_compare_entry_piecewise (const struct cache_entry * ce ,
867+ const struct traverse_info * info ,
868+ const char * name , size_t namelen ,
869+ unsigned mode )
867870{
868- int len , pathlen , ce_len ;
871+ int pathlen , ce_len ;
869872 const char * ce_name ;
870873
871874 if (info -> prev ) {
872875 int cmp = do_compare_entry_piecewise (ce , info -> prev ,
873- & info -> name );
876+ info -> name , info -> namelen ,
877+ info -> mode );
874878 if (cmp )
875879 return cmp ;
876880 }
@@ -884,15 +888,15 @@ static int do_compare_entry_piecewise(const struct cache_entry *ce, const struct
884888 ce_len -= pathlen ;
885889 ce_name = ce -> name + pathlen ;
886890
887- len = tree_entry_len (n );
888- return df_name_compare (ce_name , ce_len , S_IFREG , n -> path , len , n -> mode );
891+ return df_name_compare (ce_name , ce_len , S_IFREG , name , namelen , mode );
889892}
890893
891894static int do_compare_entry (const struct cache_entry * ce ,
892895 const struct traverse_info * info ,
893- const struct name_entry * n )
896+ const char * name , size_t namelen ,
897+ unsigned mode )
894898{
895- int len , pathlen , ce_len ;
899+ int pathlen , ce_len ;
896900 const char * ce_name ;
897901 int cmp ;
898902
@@ -902,7 +906,7 @@ static int do_compare_entry(const struct cache_entry *ce,
902906 * it is quicker to use the precomputed version.
903907 */
904908 if (!info -> traverse_path )
905- return do_compare_entry_piecewise (ce , info , n );
909+ return do_compare_entry_piecewise (ce , info , name , namelen , mode );
906910
907911 cmp = strncmp (ce -> name , info -> traverse_path , info -> pathlen );
908912 if (cmp )
@@ -917,29 +921,29 @@ static int do_compare_entry(const struct cache_entry *ce,
917921 ce_len -= pathlen ;
918922 ce_name = ce -> name + pathlen ;
919923
920- len = tree_entry_len (n );
921- return df_name_compare (ce_name , ce_len , S_IFREG , n -> path , len , n -> mode );
924+ return df_name_compare (ce_name , ce_len , S_IFREG , name , namelen , mode );
922925}
923926
924927static int compare_entry (const struct cache_entry * ce , const struct traverse_info * info , const struct name_entry * n )
925928{
926- int cmp = do_compare_entry (ce , info , n );
929+ int cmp = do_compare_entry (ce , info , n -> path , n -> pathlen , n -> mode );
927930 if (cmp )
928931 return cmp ;
929932
930933 /*
931934 * Even if the beginning compared identically, the ce should
932935 * compare as bigger than a directory leading up to it!
933936 */
934- return ce_namelen (ce ) > traverse_path_len (info , n );
937+ return ce_namelen (ce ) > traverse_path_len (info , tree_entry_len ( n ) );
935938}
936939
937940static int ce_in_traverse_path (const struct cache_entry * ce ,
938941 const struct traverse_info * info )
939942{
940943 if (!info -> prev )
941944 return 1 ;
942- if (do_compare_entry (ce , info -> prev , & info -> name ))
945+ if (do_compare_entry (ce , info -> prev ,
946+ info -> name , info -> namelen , info -> mode ))
943947 return 0 ;
944948 /*
945949 * If ce (blob) is the same name as the path (which is a tree
@@ -954,7 +958,7 @@ static struct cache_entry *create_ce_entry(const struct traverse_info *info,
954958 struct index_state * istate ,
955959 int is_transient )
956960{
957- int len = traverse_path_len (info , n );
961+ size_t len = traverse_path_len (info , tree_entry_len ( n ) );
958962 struct cache_entry * ce =
959963 is_transient ?
960964 make_empty_transient_cache_entry (len ) :
@@ -964,7 +968,8 @@ static struct cache_entry *create_ce_entry(const struct traverse_info *info,
964968 ce -> ce_flags = create_ce_flags (stage );
965969 ce -> ce_namelen = len ;
966970 oidcpy (& ce -> oid , & n -> oid );
967- make_traverse_path (ce -> name , info , n );
971+ /* len+1 because the cache_entry allocates space for NUL */
972+ make_traverse_path (ce -> name , len + 1 , info , n -> path , n -> pathlen );
968973
969974 return ce ;
970975}
@@ -1057,13 +1062,12 @@ static int unpack_failed(struct unpack_trees_options *o, const char *message)
10571062 * the directory.
10581063 */
10591064static int find_cache_pos (struct traverse_info * info ,
1060- const struct name_entry * p )
1065+ const char * p , size_t p_len )
10611066{
10621067 int pos ;
10631068 struct unpack_trees_options * o = info -> data ;
10641069 struct index_state * index = o -> src_index ;
10651070 int pfxlen = info -> pathlen ;
1066- int p_len = tree_entry_len (p );
10671071
10681072 for (pos = o -> cache_bottom ; pos < index -> cache_nr ; pos ++ ) {
10691073 const struct cache_entry * ce = index -> cache [pos ];
@@ -1099,7 +1103,7 @@ static int find_cache_pos(struct traverse_info *info,
10991103 ce_len = ce_slash - ce_name ;
11001104 else
11011105 ce_len = ce_namelen (ce ) - pfxlen ;
1102- cmp = name_compare (p -> path , p_len , ce_name , ce_len );
1106+ cmp = name_compare (p , p_len , ce_name , ce_len );
11031107 /*
11041108 * Exact match; if we have a directory we need to
11051109 * delay returning it.
@@ -1114,7 +1118,7 @@ static int find_cache_pos(struct traverse_info *info,
11141118 * E.g. ce_name == "t-i", and p->path == "t"; we may
11151119 * have "t/a" in the index.
11161120 */
1117- if (p_len < ce_len && !memcmp (ce_name , p -> path , p_len ) &&
1121+ if (p_len < ce_len && !memcmp (ce_name , p , p_len ) &&
11181122 ce_name [p_len ] < '/' )
11191123 continue ; /* keep looking */
11201124 break ;
@@ -1125,7 +1129,7 @@ static int find_cache_pos(struct traverse_info *info,
11251129static struct cache_entry * find_cache_entry (struct traverse_info * info ,
11261130 const struct name_entry * p )
11271131{
1128- int pos = find_cache_pos (info , p );
1132+ int pos = find_cache_pos (info , p -> path , p -> pathlen );
11291133 struct unpack_trees_options * o = info -> data ;
11301134
11311135 if (0 <= pos )
@@ -1138,10 +1142,10 @@ static void debug_path(struct traverse_info *info)
11381142{
11391143 if (info -> prev ) {
11401144 debug_path (info -> prev );
1141- if (* info -> prev -> name . path )
1145+ if (* info -> prev -> name )
11421146 putchar ('/' );
11431147 }
1144- printf ("%s" , info -> name . path );
1148+ printf ("%s" , info -> name );
11451149}
11461150
11471151static void debug_name_entry (int i , struct name_entry * n )
0 commit comments