4
4
#include "tag.h"
5
5
#include "dir.h"
6
6
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
10
9
11
10
struct ref_entry {
12
11
unsigned char flag ; /* ISSYMREF? ISPACKED? */
@@ -332,12 +331,12 @@ static void get_ref_dir(const char *submodule, const char *base,
332
331
flag = 0 ;
333
332
if (resolve_gitlink_ref (submodule , ref , sha1 ) < 0 ) {
334
333
hashclr (sha1 );
335
- flag |= REF_BROKEN ;
334
+ flag |= REF_ISBROKEN ;
336
335
}
337
336
} else
338
337
if (!resolve_ref (ref , sha1 , 1 , & flag )) {
339
338
hashclr (sha1 );
340
- flag |= REF_BROKEN ;
339
+ flag |= REF_ISBROKEN ;
341
340
}
342
341
add_ref (ref , sha1 , flag , array , NULL );
343
342
}
@@ -504,7 +503,6 @@ const char *resolve_ref(const char *ref, unsigned char *sha1, int reading, int *
504
503
ssize_t len ;
505
504
char buffer [256 ];
506
505
static char ref_buffer [256 ];
507
- char path [PATH_MAX ];
508
506
509
507
if (flag )
510
508
* flag = 0 ;
@@ -513,6 +511,7 @@ const char *resolve_ref(const char *ref, unsigned char *sha1, int reading, int *
513
511
return NULL ;
514
512
515
513
for (;;) {
514
+ char path [PATH_MAX ];
516
515
struct stat st ;
517
516
char * buf ;
518
517
int fd ;
@@ -585,21 +584,22 @@ const char *resolve_ref(const char *ref, unsigned char *sha1, int reading, int *
585
584
*/
586
585
if (prefixcmp (buffer , "ref:" ))
587
586
break ;
587
+ if (flag )
588
+ * flag |= REF_ISSYMREF ;
588
589
buf = buffer + 4 ;
589
590
while (isspace (* buf ))
590
591
buf ++ ;
591
592
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 ;
594
595
return NULL ;
595
596
}
596
597
ref = strcpy (ref_buffer , buf );
597
- if (flag )
598
- * flag |= REF_ISSYMREF ;
599
598
}
600
599
/* Please note that FETCH_HEAD has a second line containing other data. */
601
600
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 ;
603
603
return NULL ;
604
604
}
605
605
return ref ;
@@ -627,8 +627,8 @@ static int do_one_ref(const char *base, each_ref_fn fn, int trim,
627
627
return 0 ;
628
628
629
629
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 */
632
632
if (!has_sha1_file (entry -> sha1 )) {
633
633
error ("%s does not point to a valid object!" , entry -> name );
634
634
return 0 ;
@@ -1078,6 +1078,94 @@ static int is_refname_available(const char *ref, const char *oldref,
1078
1078
return 1 ;
1079
1079
}
1080
1080
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
+
1081
1169
static struct ref_lock * lock_ref_sha1_basic (const char * ref , const unsigned char * old_sha1 , int flags , int * type_p )
1082
1170
{
1083
1171
char * ref_file ;
0 commit comments