22
33#include "git-compat-util.h"
44#include "environment.h"
5+ #include "gettext.h"
56#include "hex.h"
67#include "lockfile.h"
78#include "tree.h"
@@ -864,15 +865,15 @@ int cache_tree_matches_traversal(struct cache_tree *root,
864865 return 0 ;
865866}
866867
867- static void verify_one_sparse (struct index_state * istate ,
868- struct strbuf * path ,
869- int pos )
868+ static int verify_one_sparse (struct index_state * istate ,
869+ struct strbuf * path ,
870+ int pos )
870871{
871872 struct cache_entry * ce = istate -> cache [pos ];
872-
873873 if (!S_ISSPARSEDIR (ce -> ce_mode ))
874- BUG ("directory '%s' is present in index, but not sparse" ,
875- path -> buf );
874+ return error (_ ("directory '%s' is present in index, but not sparse" ),
875+ path -> buf );
876+ return 0 ;
876877}
877878
878879/*
@@ -881,6 +882,7 @@ static void verify_one_sparse(struct index_state *istate,
881882 * 1 - Restart verification - a call to ensure_full_index() freed the cache
882883 * tree that is being verified and verification needs to be restarted from
883884 * the new toplevel cache tree.
885+ * -1 - Verification failed.
884886 */
885887static int verify_one (struct repository * r ,
886888 struct index_state * istate ,
@@ -890,18 +892,23 @@ static int verify_one(struct repository *r,
890892 int i , pos , len = path -> len ;
891893 struct strbuf tree_buf = STRBUF_INIT ;
892894 struct object_id new_oid ;
895+ int ret ;
893896
894897 for (i = 0 ; i < it -> subtree_nr ; i ++ ) {
895898 strbuf_addf (path , "%s/" , it -> down [i ]-> name );
896- if (verify_one (r , istate , it -> down [i ]-> cache_tree , path ))
897- return 1 ;
899+ ret = verify_one (r , istate , it -> down [i ]-> cache_tree , path );
900+ if (ret )
901+ goto out ;
902+
898903 strbuf_setlen (path , len );
899904 }
900905
901906 if (it -> entry_count < 0 ||
902907 /* no verification on tests (t7003) that replace trees */
903- lookup_replace_object (r , & it -> oid ) != & it -> oid )
904- return 0 ;
908+ lookup_replace_object (r , & it -> oid ) != & it -> oid ) {
909+ ret = 0 ;
910+ goto out ;
911+ }
905912
906913 if (path -> len ) {
907914 /*
@@ -911,12 +918,14 @@ static int verify_one(struct repository *r,
911918 */
912919 int is_sparse = istate -> sparse_index ;
913920 pos = index_name_pos (istate , path -> buf , path -> len );
914- if (is_sparse && !istate -> sparse_index )
915- return 1 ;
921+ if (is_sparse && !istate -> sparse_index ) {
922+ ret = 1 ;
923+ goto out ;
924+ }
916925
917926 if (pos >= 0 ) {
918- verify_one_sparse (istate , path , pos );
919- return 0 ;
927+ ret = verify_one_sparse (istate , path , pos );
928+ goto out ;
920929 }
921930
922931 pos = - pos - 1 ;
@@ -934,16 +943,23 @@ static int verify_one(struct repository *r,
934943 unsigned mode ;
935944 int entlen ;
936945
937- if (ce -> ce_flags & (CE_STAGEMASK | CE_INTENT_TO_ADD | CE_REMOVE ))
938- BUG ("%s with flags 0x%x should not be in cache-tree" ,
939- ce -> name , ce -> ce_flags );
946+ if (ce -> ce_flags & (CE_STAGEMASK | CE_INTENT_TO_ADD | CE_REMOVE )) {
947+ ret = error (_ ("%s with flags 0x%x should not be in cache-tree" ),
948+ ce -> name , ce -> ce_flags );
949+ goto out ;
950+ }
951+
940952 name = ce -> name + path -> len ;
941953 slash = strchr (name , '/' );
942954 if (slash ) {
943955 entlen = slash - name ;
956+
944957 sub = find_subtree (it , ce -> name + path -> len , entlen , 0 );
945- if (!sub || sub -> cache_tree -> entry_count < 0 )
946- BUG ("bad subtree '%.*s'" , entlen , name );
958+ if (!sub || sub -> cache_tree -> entry_count < 0 ) {
959+ ret = error (_ ("bad subtree '%.*s'" ), entlen , name );
960+ goto out ;
961+ }
962+
947963 oid = & sub -> cache_tree -> oid ;
948964 mode = S_IFDIR ;
949965 i += sub -> cache_tree -> entry_count ;
@@ -956,27 +972,50 @@ static int verify_one(struct repository *r,
956972 strbuf_addf (& tree_buf , "%o %.*s%c" , mode , entlen , name , '\0' );
957973 strbuf_add (& tree_buf , oid -> hash , r -> hash_algo -> rawsz );
958974 }
975+
959976 hash_object_file (r -> hash_algo , tree_buf .buf , tree_buf .len , OBJ_TREE ,
960977 & new_oid );
961- if (!oideq (& new_oid , & it -> oid ))
962- BUG ("cache-tree for path %.*s does not match. "
963- "Expected %s got %s" , len , path -> buf ,
964- oid_to_hex (& new_oid ), oid_to_hex (& it -> oid ));
978+
979+ if (!oideq (& new_oid , & it -> oid )) {
980+ ret = error (_ ("cache-tree for path %.*s does not match. "
981+ "Expected %s got %s" ), len , path -> buf ,
982+ oid_to_hex (& new_oid ), oid_to_hex (& it -> oid ));
983+ goto out ;
984+ }
985+
986+ ret = 0 ;
987+ out :
965988 strbuf_setlen (path , len );
966989 strbuf_release (& tree_buf );
967- return 0 ;
990+ return ret ;
968991}
969992
970- void cache_tree_verify (struct repository * r , struct index_state * istate )
993+ int cache_tree_verify (struct repository * r , struct index_state * istate )
971994{
972995 struct strbuf path = STRBUF_INIT ;
996+ int ret ;
973997
974- if (!istate -> cache_tree )
975- return ;
976- if (verify_one (r , istate , istate -> cache_tree , & path )) {
998+ if (!istate -> cache_tree ) {
999+ ret = 0 ;
1000+ goto out ;
1001+ }
1002+
1003+ ret = verify_one (r , istate , istate -> cache_tree , & path );
1004+ if (ret < 0 )
1005+ goto out ;
1006+ if (ret > 0 ) {
9771007 strbuf_reset (& path );
978- if (verify_one (r , istate , istate -> cache_tree , & path ))
1008+
1009+ ret = verify_one (r , istate , istate -> cache_tree , & path );
1010+ if (ret < 0 )
1011+ goto out ;
1012+ if (ret > 0 )
9791013 BUG ("ensure_full_index() called twice while verifying cache tree" );
9801014 }
1015+
1016+ ret = 0 ;
1017+
1018+ out :
9811019 strbuf_release (& path );
1020+ return ret ;
9821021}
0 commit comments