@@ -235,22 +235,23 @@ static int ambiguous_path(const char *path, int len)
235235 return slash ;
236236}
237237
238+ static const char * ref_fmt [] = {
239+ "%.*s" ,
240+ "refs/%.*s" ,
241+ "refs/tags/%.*s" ,
242+ "refs/heads/%.*s" ,
243+ "refs/remotes/%.*s" ,
244+ "refs/remotes/%.*s/HEAD" ,
245+ NULL
246+ };
247+
238248int dwim_ref (const char * str , int len , unsigned char * sha1 , char * * ref )
239249{
240- static const char * fmt [] = {
241- "%.*s" ,
242- "refs/%.*s" ,
243- "refs/tags/%.*s" ,
244- "refs/heads/%.*s" ,
245- "refs/remotes/%.*s" ,
246- "refs/remotes/%.*s/HEAD" ,
247- NULL
248- };
249250 const char * * p , * r ;
250251 int refs_found = 0 ;
251252
252253 * ref = NULL ;
253- for (p = fmt ; * p ; p ++ ) {
254+ for (p = ref_fmt ; * p ; p ++ ) {
254255 unsigned char sha1_from_ref [20 ];
255256 unsigned char * this_result ;
256257
@@ -266,6 +267,28 @@ int dwim_ref(const char *str, int len, unsigned char *sha1, char **ref)
266267 return refs_found ;
267268}
268269
270+ static int dwim_log (const char * str , int len , unsigned char * sha1 , char * * log )
271+ {
272+ const char * * p ;
273+ int logs_found = 0 ;
274+
275+ * log = NULL ;
276+ for (p = ref_fmt ; * p ; p ++ ) {
277+ struct stat st ;
278+ char * path = mkpath (* p , len , str );
279+ if (!stat (git_path ("logs/%s" , path ), & st ) &&
280+ S_ISREG (st .st_mode )) {
281+ if (!logs_found ++ ) {
282+ * log = xstrdup (path );
283+ resolve_ref (path , sha1 , 0 , NULL );
284+ }
285+ if (!warn_ambiguous_refs )
286+ break ;
287+ }
288+ }
289+ return logs_found ;
290+ }
291+
269292static int get_sha1_basic (const char * str , int len , unsigned char * sha1 )
270293{
271294 static const char * warning = "warning: refname '%.*s' is ambiguous.\n" ;
@@ -295,7 +318,9 @@ static int get_sha1_basic(const char *str, int len, unsigned char *sha1)
295318 if (!len && reflog_len ) {
296319 /* allow "@{...}" to mean the current branch reflog */
297320 refs_found = dwim_ref ("HEAD" , 4 , sha1 , & real_ref );
298- } else
321+ } else if (reflog_len )
322+ refs_found = dwim_log (str , len , sha1 , & real_ref );
323+ else
299324 refs_found = dwim_ref (str , len , sha1 , & real_ref );
300325
301326 if (!refs_found )
@@ -310,21 +335,6 @@ static int get_sha1_basic(const char *str, int len, unsigned char *sha1)
310335 unsigned long co_time ;
311336 int co_tz , co_cnt ;
312337
313- /*
314- * We'll have an independent reflog for "HEAD" eventually
315- * which won't be a synonym for the current branch reflog.
316- * In the mean time prevent people from getting used to
317- * such a synonym until the work is completed.
318- */
319- if (len && !strncmp ("HEAD" , str , len ) &&
320- !strncmp (real_ref , "refs/" , 5 )) {
321- error ("reflog for HEAD has not been implemented yet\n"
322- "Maybe you could try %s%s instead, "
323- "or just %s for current branch.." ,
324- strchr (real_ref + 5 , '/' )+ 1 , str + len , str + len );
325- exit (-1 );
326- }
327-
328338 /* Is it asking for N-th entry, or approxidate? */
329339 for (i = nth = 0 ; 0 <= nth && i < reflog_len ; i ++ ) {
330340 char ch = str [at + 2 + i ];
0 commit comments