@@ -1176,15 +1176,16 @@ static int interpret_empty_at(const char *name, int namelen, int len, struct str
11761176 return 1 ;
11771177}
11781178
1179- static int reinterpret (const char * name , int namelen , int len , struct strbuf * buf )
1179+ static int reinterpret (const char * name , int namelen , int len ,
1180+ struct strbuf * buf , unsigned allowed )
11801181{
11811182 /* we have extra data, which might need further processing */
11821183 struct strbuf tmp = STRBUF_INIT ;
11831184 int used = buf -> len ;
11841185 int ret ;
11851186
11861187 strbuf_add (buf , name + len , namelen - len );
1187- ret = interpret_branch_name (buf -> buf , buf -> len , & tmp );
1188+ ret = interpret_branch_name (buf -> buf , buf -> len , & tmp , allowed );
11881189 /* that data was not interpreted, remove our cruft */
11891190 if (ret < 0 ) {
11901191 strbuf_setlen (buf , used );
@@ -1205,11 +1206,27 @@ static void set_shortened_ref(struct strbuf *buf, const char *ref)
12051206 free (s );
12061207}
12071208
1209+ static int branch_interpret_allowed (const char * refname , unsigned allowed )
1210+ {
1211+ if (!allowed )
1212+ return 1 ;
1213+
1214+ if ((allowed & INTERPRET_BRANCH_LOCAL ) &&
1215+ starts_with (refname , "refs/heads/" ))
1216+ return 1 ;
1217+ if ((allowed & INTERPRET_BRANCH_REMOTE ) &&
1218+ starts_with (refname , "refs/remotes/" ))
1219+ return 1 ;
1220+
1221+ return 0 ;
1222+ }
1223+
12081224static int interpret_branch_mark (const char * name , int namelen ,
12091225 int at , struct strbuf * buf ,
12101226 int (* get_mark )(const char * , int ),
12111227 const char * (* get_data )(struct branch * ,
1212- struct strbuf * ))
1228+ struct strbuf * ),
1229+ unsigned allowed )
12131230{
12141231 int len ;
12151232 struct branch * branch ;
@@ -1234,87 +1251,75 @@ static int interpret_branch_mark(const char *name, int namelen,
12341251 if (!value )
12351252 die ("%s" , err .buf );
12361253
1254+ if (!branch_interpret_allowed (value , allowed ))
1255+ return -1 ;
1256+
12371257 set_shortened_ref (buf , value );
12381258 return len + at ;
12391259}
12401260
1241- /*
1242- * This reads short-hand syntax that not only evaluates to a commit
1243- * object name, but also can act as if the end user spelled the name
1244- * of the branch from the command line.
1245- *
1246- * - "@{-N}" finds the name of the Nth previous branch we were on, and
1247- * places the name of the branch in the given buf and returns the
1248- * number of characters parsed if successful.
1249- *
1250- * - "<branch>@{upstream}" finds the name of the other ref that
1251- * <branch> is configured to merge with (missing <branch> defaults
1252- * to the current branch), and places the name of the branch in the
1253- * given buf and returns the number of characters parsed if
1254- * successful.
1255- *
1256- * If the input is not of the accepted format, it returns a negative
1257- * number to signal an error.
1258- *
1259- * If the input was ok but there are not N branch switches in the
1260- * reflog, it returns 0.
1261- */
1262- int interpret_branch_name (const char * name , int namelen , struct strbuf * buf )
1261+ int interpret_branch_name (const char * name , int namelen , struct strbuf * buf ,
1262+ unsigned allowed )
12631263{
12641264 char * at ;
12651265 const char * start ;
1266- int len = interpret_nth_prior_checkout ( name , namelen , buf ) ;
1266+ int len ;
12671267
12681268 if (!namelen )
12691269 namelen = strlen (name );
12701270
1271- if (!len ) {
1272- return len ; /* syntax Ok, not enough switches */
1273- } else if (len > 0 ) {
1274- if (len == namelen )
1275- return len ; /* consumed all */
1276- else
1277- return reinterpret (name , namelen , len , buf );
1271+ if (!allowed || (allowed & INTERPRET_BRANCH_LOCAL )) {
1272+ len = interpret_nth_prior_checkout (name , namelen , buf );
1273+ if (!len ) {
1274+ return len ; /* syntax Ok, not enough switches */
1275+ } else if (len > 0 ) {
1276+ if (len == namelen )
1277+ return len ; /* consumed all */
1278+ else
1279+ return reinterpret (name , namelen , len , buf , allowed );
1280+ }
12781281 }
12791282
12801283 for (start = name ;
12811284 (at = memchr (start , '@' , namelen - (start - name )));
12821285 start = at + 1 ) {
12831286
1284- len = interpret_empty_at (name , namelen , at - name , buf );
1285- if (len > 0 )
1286- return reinterpret (name , namelen , len , buf );
1287+ if (!allowed || (allowed & INTERPRET_BRANCH_HEAD )) {
1288+ len = interpret_empty_at (name , namelen , at - name , buf );
1289+ if (len > 0 )
1290+ return reinterpret (name , namelen , len , buf ,
1291+ allowed );
1292+ }
12871293
12881294 len = interpret_branch_mark (name , namelen , at - name , buf ,
1289- upstream_mark , branch_get_upstream );
1295+ upstream_mark , branch_get_upstream ,
1296+ allowed );
12901297 if (len > 0 )
12911298 return len ;
12921299
12931300 len = interpret_branch_mark (name , namelen , at - name , buf ,
1294- push_mark , branch_get_push );
1301+ push_mark , branch_get_push ,
1302+ allowed );
12951303 if (len > 0 )
12961304 return len ;
12971305 }
12981306
12991307 return -1 ;
13001308}
13011309
1302- int strbuf_branchname (struct strbuf * sb , const char * name )
1310+ void strbuf_branchname (struct strbuf * sb , const char * name , unsigned allowed )
13031311{
13041312 int len = strlen (name );
1305- int used = interpret_branch_name (name , len , sb );
1313+ int used = interpret_branch_name (name , len , sb , allowed );
13061314
1307- if (used == len )
1308- return 0 ;
13091315 if (used < 0 )
13101316 used = 0 ;
13111317 strbuf_add (sb , name + used , len - used );
1312- return len ;
13131318}
13141319
13151320int strbuf_check_branch_ref (struct strbuf * sb , const char * name )
13161321{
1317- strbuf_branchname (sb , name );
1322+ strbuf_branchname (sb , name , INTERPRET_BRANCH_LOCAL );
13181323 if (name [0 ] == '-' )
13191324 return -1 ;
13201325 strbuf_splice (sb , 0 , 0 , "refs/heads/" , 11 );
0 commit comments