@@ -632,7 +632,7 @@ static int unpack_index_entry(struct cache_entry *ce,
632
632
return ret ;
633
633
}
634
634
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 );
636
636
637
637
static void restore_cache_bottom (struct traverse_info * info , int bottom )
638
638
{
@@ -651,7 +651,7 @@ static int switch_cache_bottom(struct traverse_info *info)
651
651
if (o -> diff_index_cached )
652
652
return 0 ;
653
653
ret = o -> cache_bottom ;
654
- pos = find_cache_pos (info -> prev , & info -> name );
654
+ pos = find_cache_pos (info -> prev , info -> name , info -> namelen );
655
655
656
656
if (pos < -1 )
657
657
o -> cache_bottom = -2 - pos ;
@@ -686,21 +686,19 @@ static int index_pos_by_traverse_info(struct name_entry *names,
686
686
struct traverse_info * info )
687
687
{
688
688
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 ;
691
690
int pos ;
692
691
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 );
697
695
if (pos >= 0 )
698
696
BUG ("This is a directory and should not exist in index" );
699
697
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 )))
702
700
BUG ("pos must point at the first entry in this directory" );
703
- free ( name );
701
+ strbuf_release ( & name );
704
702
return pos ;
705
703
}
706
704
@@ -811,8 +809,10 @@ static int traverse_trees_recursive(int n, unsigned long dirmask,
811
809
newinfo = * info ;
812
810
newinfo .prev = info ;
813
811
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 );
816
816
newinfo .df_conflicts |= df_conflicts ;
817
817
818
818
/*
@@ -863,14 +863,18 @@ static int traverse_trees_recursive(int n, unsigned long dirmask,
863
863
* itself - the caller needs to do the final check for the cache
864
864
* entry having more data at the end!
865
865
*/
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 )
867
870
{
868
- int len , pathlen , ce_len ;
871
+ int pathlen , ce_len ;
869
872
const char * ce_name ;
870
873
871
874
if (info -> prev ) {
872
875
int cmp = do_compare_entry_piecewise (ce , info -> prev ,
873
- & info -> name );
876
+ info -> name , info -> namelen ,
877
+ info -> mode );
874
878
if (cmp )
875
879
return cmp ;
876
880
}
@@ -884,15 +888,15 @@ static int do_compare_entry_piecewise(const struct cache_entry *ce, const struct
884
888
ce_len -= pathlen ;
885
889
ce_name = ce -> name + pathlen ;
886
890
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 );
889
892
}
890
893
891
894
static int do_compare_entry (const struct cache_entry * ce ,
892
895
const struct traverse_info * info ,
893
- const struct name_entry * n )
896
+ const char * name , size_t namelen ,
897
+ unsigned mode )
894
898
{
895
- int len , pathlen , ce_len ;
899
+ int pathlen , ce_len ;
896
900
const char * ce_name ;
897
901
int cmp ;
898
902
@@ -902,7 +906,7 @@ static int do_compare_entry(const struct cache_entry *ce,
902
906
* it is quicker to use the precomputed version.
903
907
*/
904
908
if (!info -> traverse_path )
905
- return do_compare_entry_piecewise (ce , info , n );
909
+ return do_compare_entry_piecewise (ce , info , name , namelen , mode );
906
910
907
911
cmp = strncmp (ce -> name , info -> traverse_path , info -> pathlen );
908
912
if (cmp )
@@ -917,29 +921,29 @@ static int do_compare_entry(const struct cache_entry *ce,
917
921
ce_len -= pathlen ;
918
922
ce_name = ce -> name + pathlen ;
919
923
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 );
922
925
}
923
926
924
927
static int compare_entry (const struct cache_entry * ce , const struct traverse_info * info , const struct name_entry * n )
925
928
{
926
- int cmp = do_compare_entry (ce , info , n );
929
+ int cmp = do_compare_entry (ce , info , n -> path , n -> pathlen , n -> mode );
927
930
if (cmp )
928
931
return cmp ;
929
932
930
933
/*
931
934
* Even if the beginning compared identically, the ce should
932
935
* compare as bigger than a directory leading up to it!
933
936
*/
934
- return ce_namelen (ce ) > traverse_path_len (info , n );
937
+ return ce_namelen (ce ) > traverse_path_len (info , tree_entry_len ( n ) );
935
938
}
936
939
937
940
static int ce_in_traverse_path (const struct cache_entry * ce ,
938
941
const struct traverse_info * info )
939
942
{
940
943
if (!info -> prev )
941
944
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 ))
943
947
return 0 ;
944
948
/*
945
949
* 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,
954
958
struct index_state * istate ,
955
959
int is_transient )
956
960
{
957
- int len = traverse_path_len (info , n );
961
+ size_t len = traverse_path_len (info , tree_entry_len ( n ) );
958
962
struct cache_entry * ce =
959
963
is_transient ?
960
964
make_empty_transient_cache_entry (len ) :
@@ -964,7 +968,8 @@ static struct cache_entry *create_ce_entry(const struct traverse_info *info,
964
968
ce -> ce_flags = create_ce_flags (stage );
965
969
ce -> ce_namelen = len ;
966
970
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 );
968
973
969
974
return ce ;
970
975
}
@@ -1057,13 +1062,12 @@ static int unpack_failed(struct unpack_trees_options *o, const char *message)
1057
1062
* the directory.
1058
1063
*/
1059
1064
static int find_cache_pos (struct traverse_info * info ,
1060
- const struct name_entry * p )
1065
+ const char * p , size_t p_len )
1061
1066
{
1062
1067
int pos ;
1063
1068
struct unpack_trees_options * o = info -> data ;
1064
1069
struct index_state * index = o -> src_index ;
1065
1070
int pfxlen = info -> pathlen ;
1066
- int p_len = tree_entry_len (p );
1067
1071
1068
1072
for (pos = o -> cache_bottom ; pos < index -> cache_nr ; pos ++ ) {
1069
1073
const struct cache_entry * ce = index -> cache [pos ];
@@ -1099,7 +1103,7 @@ static int find_cache_pos(struct traverse_info *info,
1099
1103
ce_len = ce_slash - ce_name ;
1100
1104
else
1101
1105
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 );
1103
1107
/*
1104
1108
* Exact match; if we have a directory we need to
1105
1109
* delay returning it.
@@ -1114,7 +1118,7 @@ static int find_cache_pos(struct traverse_info *info,
1114
1118
* E.g. ce_name == "t-i", and p->path == "t"; we may
1115
1119
* have "t/a" in the index.
1116
1120
*/
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 ) &&
1118
1122
ce_name [p_len ] < '/' )
1119
1123
continue ; /* keep looking */
1120
1124
break ;
@@ -1125,7 +1129,7 @@ static int find_cache_pos(struct traverse_info *info,
1125
1129
static struct cache_entry * find_cache_entry (struct traverse_info * info ,
1126
1130
const struct name_entry * p )
1127
1131
{
1128
- int pos = find_cache_pos (info , p );
1132
+ int pos = find_cache_pos (info , p -> path , p -> pathlen );
1129
1133
struct unpack_trees_options * o = info -> data ;
1130
1134
1131
1135
if (0 <= pos )
@@ -1138,10 +1142,10 @@ static void debug_path(struct traverse_info *info)
1138
1142
{
1139
1143
if (info -> prev ) {
1140
1144
debug_path (info -> prev );
1141
- if (* info -> prev -> name . path )
1145
+ if (* info -> prev -> name )
1142
1146
putchar ('/' );
1143
1147
}
1144
- printf ("%s" , info -> name . path );
1148
+ printf ("%s" , info -> name );
1145
1149
}
1146
1150
1147
1151
static void debug_name_entry (int i , struct name_entry * n )
0 commit comments