44#include "tag.h"
55#include "dir.h"
66
7- /* ISSYMREF=01 and ISPACKED=02 are public interfaces */
8- #define REF_KNOWS_PEELED 04
9- #define REF_BROKEN 010
7+ /* ISSYMREF=0x01, ISPACKED=0x02 and ISBROKEN=0x04 are public interfaces */
8+ #define REF_KNOWS_PEELED 0x10
109
1110struct ref_entry {
1211 unsigned char flag ; /* ISSYMREF? ISPACKED? */
@@ -332,12 +331,12 @@ static void get_ref_dir(const char *submodule, const char *base,
332331 flag = 0 ;
333332 if (resolve_gitlink_ref (submodule , ref , sha1 ) < 0 ) {
334333 hashclr (sha1 );
335- flag |= REF_BROKEN ;
334+ flag |= REF_ISBROKEN ;
336335 }
337336 } else
338337 if (!resolve_ref (ref , sha1 , 1 , & flag )) {
339338 hashclr (sha1 );
340- flag |= REF_BROKEN ;
339+ flag |= REF_ISBROKEN ;
341340 }
342341 add_ref (ref , sha1 , flag , array , NULL );
343342 }
@@ -504,7 +503,6 @@ const char *resolve_ref(const char *ref, unsigned char *sha1, int reading, int *
504503 ssize_t len ;
505504 char buffer [256 ];
506505 static char ref_buffer [256 ];
507- char path [PATH_MAX ];
508506
509507 if (flag )
510508 * flag = 0 ;
@@ -513,6 +511,7 @@ const char *resolve_ref(const char *ref, unsigned char *sha1, int reading, int *
513511 return NULL ;
514512
515513 for (;;) {
514+ char path [PATH_MAX ];
516515 struct stat st ;
517516 char * buf ;
518517 int fd ;
@@ -585,21 +584,22 @@ const char *resolve_ref(const char *ref, unsigned char *sha1, int reading, int *
585584 */
586585 if (prefixcmp (buffer , "ref:" ))
587586 break ;
587+ if (flag )
588+ * flag |= REF_ISSYMREF ;
588589 buf = buffer + 4 ;
589590 while (isspace (* buf ))
590591 buf ++ ;
591592 if (check_refname_format (buf , REFNAME_ALLOW_ONELEVEL )) {
592- warning ( "symbolic reference in %s is formatted incorrectly" ,
593- path ) ;
593+ if ( flag )
594+ * flag |= REF_ISBROKEN ;
594595 return NULL ;
595596 }
596597 ref = strcpy (ref_buffer , buf );
597- if (flag )
598- * flag |= REF_ISSYMREF ;
599598 }
600599 /* Please note that FETCH_HEAD has a second line containing other data. */
601600 if (get_sha1_hex (buffer , sha1 ) || (buffer [40 ] != '\0' && !isspace (buffer [40 ]))) {
602- warning ("reference in %s is formatted incorrectly" , path );
601+ if (flag )
602+ * flag |= REF_ISBROKEN ;
603603 return NULL ;
604604 }
605605 return ref ;
@@ -627,8 +627,8 @@ static int do_one_ref(const char *base, each_ref_fn fn, int trim,
627627 return 0 ;
628628
629629 if (!(flags & DO_FOR_EACH_INCLUDE_BROKEN )) {
630- if (entry -> flag & REF_BROKEN )
631- return 0 ; /* ignore dangling symref */
630+ if (entry -> flag & REF_ISBROKEN )
631+ return 0 ; /* ignore broken refs e.g. dangling symref */
632632 if (!has_sha1_file (entry -> sha1 )) {
633633 error ("%s does not point to a valid object!" , entry -> name );
634634 return 0 ;
@@ -1078,6 +1078,94 @@ static int is_refname_available(const char *ref, const char *oldref,
10781078 return 1 ;
10791079}
10801080
1081+ /*
1082+ * *string and *len will only be substituted, and *string returned (for
1083+ * later free()ing) if the string passed in is a magic short-hand form
1084+ * to name a branch.
1085+ */
1086+ static char * substitute_branch_name (const char * * string , int * len )
1087+ {
1088+ struct strbuf buf = STRBUF_INIT ;
1089+ int ret = interpret_branch_name (* string , & buf );
1090+
1091+ if (ret == * len ) {
1092+ size_t size ;
1093+ * string = strbuf_detach (& buf , & size );
1094+ * len = size ;
1095+ return (char * )* string ;
1096+ }
1097+
1098+ return NULL ;
1099+ }
1100+
1101+ int dwim_ref (const char * str , int len , unsigned char * sha1 , char * * ref )
1102+ {
1103+ char * last_branch = substitute_branch_name (& str , & len );
1104+ const char * * p , * r ;
1105+ int refs_found = 0 ;
1106+
1107+ * ref = NULL ;
1108+ for (p = ref_rev_parse_rules ; * p ; p ++ ) {
1109+ char fullref [PATH_MAX ];
1110+ unsigned char sha1_from_ref [20 ];
1111+ unsigned char * this_result ;
1112+ int flag ;
1113+
1114+ this_result = refs_found ? sha1_from_ref : sha1 ;
1115+ mksnpath (fullref , sizeof (fullref ), * p , len , str );
1116+ r = resolve_ref (fullref , this_result , 1 , & flag );
1117+ if (r ) {
1118+ if (!refs_found ++ )
1119+ * ref = xstrdup (r );
1120+ if (!warn_ambiguous_refs )
1121+ break ;
1122+ } else if ((flag & REF_ISSYMREF ) && strcmp (fullref , "HEAD" )) {
1123+ warning ("ignoring dangling symref %s." , fullref );
1124+ } else if ((flag & REF_ISBROKEN ) && strchr (fullref , '/' )) {
1125+ warning ("ignoring broken ref %s." , fullref );
1126+ }
1127+ }
1128+ free (last_branch );
1129+ return refs_found ;
1130+ }
1131+
1132+ int dwim_log (const char * str , int len , unsigned char * sha1 , char * * log )
1133+ {
1134+ char * last_branch = substitute_branch_name (& str , & len );
1135+ const char * * p ;
1136+ int logs_found = 0 ;
1137+
1138+ * log = NULL ;
1139+ for (p = ref_rev_parse_rules ; * p ; p ++ ) {
1140+ struct stat st ;
1141+ unsigned char hash [20 ];
1142+ char path [PATH_MAX ];
1143+ const char * ref , * it ;
1144+
1145+ mksnpath (path , sizeof (path ), * p , len , str );
1146+ ref = resolve_ref (path , hash , 1 , NULL );
1147+ if (!ref )
1148+ continue ;
1149+ if (!stat (git_path ("logs/%s" , path ), & st ) &&
1150+ S_ISREG (st .st_mode ))
1151+ it = path ;
1152+ else if (strcmp (ref , path ) &&
1153+ !stat (git_path ("logs/%s" , ref ), & st ) &&
1154+ S_ISREG (st .st_mode ))
1155+ it = ref ;
1156+ else
1157+ continue ;
1158+ if (!logs_found ++ ) {
1159+ * log = xstrdup (it );
1160+ hashcpy (sha1 , hash );
1161+ }
1162+ if (!warn_ambiguous_refs )
1163+ break ;
1164+ }
1165+ free (last_branch );
1166+ return logs_found ;
1167+ }
1168+
10811169static struct ref_lock * lock_ref_sha1_basic (const char * ref , const unsigned char * old_sha1 , int flags , int * type_p )
10821170{
10831171 char * ref_file ;
0 commit comments