@@ -878,26 +878,30 @@ static int is_refname_available(const char *refname,
878878 const char * slash ;
879879 int pos ;
880880 struct strbuf dirname = STRBUF_INIT ;
881+ int ret = 0 ;
881882
882883 /*
883884 * For the sake of comments in this function, suppose that
884885 * refname is "refs/foo/bar".
885886 */
886887
888+ strbuf_grow (& dirname , strlen (refname ) + 1 );
887889 for (slash = strchr (refname , '/' ); slash ; slash = strchr (slash + 1 , '/' )) {
890+ /* Expand dirname to the new prefix, not including the trailing slash: */
891+ strbuf_add (& dirname , refname + dirname .len , slash - refname - dirname .len );
892+
888893 /*
889894 * We are still at a leading dir of the refname (e.g.,
890895 * "refs/foo"; if there is a reference with that name,
891896 * it is a conflict, *unless* it is in skip.
892897 */
893- pos = search_ref_dir (dir , refname , slash - refname );
898+ pos = search_ref_dir (dir , dirname . buf , dirname . len );
894899 if (pos >= 0 ) {
895900 /*
896901 * We found a reference whose name is a proper
897902 * prefix of refname; e.g., "refs/foo".
898903 */
899- struct ref_entry * entry = dir -> entries [pos ];
900- if (skip && string_list_has_string (skip , entry -> name )) {
904+ if (skip && string_list_has_string (skip , dirname .buf )) {
901905 /*
902906 * The reference we just found, e.g.,
903907 * "refs/foo", is also in skip, so it
@@ -910,10 +914,11 @@ static int is_refname_available(const char *refname,
910914 * "refs/foo"). So we can stop looking
911915 * now and return true.
912916 */
913- return 1 ;
917+ ret = 1 ;
918+ goto cleanup ;
914919 }
915- error ("'%s' exists; cannot create '%s'" , entry -> name , refname );
916- return 0 ;
920+ error ("'%s' exists; cannot create '%s'" , dirname . buf , refname );
921+ goto cleanup ;
917922 }
918923
919924
@@ -922,14 +927,16 @@ static int is_refname_available(const char *refname,
922927 * the next component. So try to look up the
923928 * directory, e.g., "refs/foo/".
924929 */
925- pos = search_ref_dir (dir , refname , slash + 1 - refname );
930+ strbuf_addch (& dirname , '/' );
931+ pos = search_ref_dir (dir , dirname .buf , dirname .len );
926932 if (pos < 0 ) {
927933 /*
928934 * There was no directory "refs/foo/", so
929935 * there is nothing under this whole prefix,
930936 * and we are OK.
931937 */
932- return 1 ;
938+ ret = 1 ;
939+ goto cleanup ;
933940 }
934941
935942 dir = get_ref_dir (dir -> entries [pos ]);
@@ -943,10 +950,9 @@ static int is_refname_available(const char *refname,
943950 * names are in the "refs/foo/bar/" namespace, because they
944951 * *do* conflict.
945952 */
946- strbuf_addstr (& dirname , refname );
953+ strbuf_addstr (& dirname , refname + dirname . len );
947954 strbuf_addch (& dirname , '/' );
948955 pos = search_ref_dir (dir , dirname .buf , dirname .len );
949- strbuf_release (& dirname );
950956
951957 if (pos >= 0 ) {
952958 /*
@@ -960,15 +966,21 @@ static int is_refname_available(const char *refname,
960966 dir = get_ref_dir (entry );
961967 data .skip = skip ;
962968 sort_ref_dir (dir );
963- if (!do_for_each_entry_in_dir (dir , 0 , nonmatching_ref_fn , & data ))
964- return 1 ;
969+ if (!do_for_each_entry_in_dir (dir , 0 , nonmatching_ref_fn , & data )) {
970+ ret = 1 ;
971+ goto cleanup ;
972+ }
965973
966974 error ("'%s' exists; cannot create '%s'" ,
967975 data .conflicting_refname , refname );
968- return 0 ;
976+ goto cleanup ;
969977 }
970978
971- return 1 ;
979+ ret = 1 ;
980+
981+ cleanup :
982+ strbuf_release (& dirname );
983+ return ret ;
972984}
973985
974986struct packed_ref_cache {
0 commit comments