Merge branch 'jc/reflog' into lj/refs
authorJunio C Hamano <junkio@cox.net>
Fri, 27 Oct 2006 01:48:30 +0000 (18:48 -0700)
committerJunio C Hamano <junkio@cox.net>
Fri, 27 Oct 2006 01:48:30 +0000 (18:48 -0700)
* jc/reflog:
  sha1_name.c: avoid compilation warnings.
  ref-log: allow ref@{count} syntax.

refs.c
refs.h
sha1_name.c

diff --git a/refs.c b/refs.c
index ed2e3b1..f003a0b 100644 (file)
--- a/refs.c
+++ b/refs.c
@@ -806,7 +806,7 @@ int write_ref_sha1(struct ref_lock *lock,
        return 0;
 }
 
-int read_ref_at(const char *ref, unsigned long at_time, unsigned char *sha1)
+int read_ref_at(const char *ref, unsigned long at_time, int cnt, unsigned char *sha1)
 {
        const char *logfile, *logdata, *logend, *rec, *lastgt, *lastrec;
        char *tz_c;
@@ -839,7 +839,7 @@ int read_ref_at(const char *ref, unsigned long at_time, unsigned char *sha1)
                if (!lastgt)
                        die("Log %s is corrupt.", logfile);
                date = strtoul(lastgt + 1, &tz_c, 10);
-               if (date <= at_time) {
+               if (date <= at_time || cnt == 0) {
                        if (lastrec) {
                                if (get_sha1_hex(lastrec, logged_sha1))
                                        die("Log %s is corrupt.", logfile);
@@ -870,6 +870,8 @@ int read_ref_at(const char *ref, unsigned long at_time, unsigned char *sha1)
                        return 0;
                }
                lastrec = rec;
+               if (cnt > 0)
+                       cnt--;
        }
 
        rec = logdata;
diff --git a/refs.h b/refs.h
index 0d4d79e..a57d437 100644 (file)
--- a/refs.h
+++ b/refs.h
@@ -39,7 +39,7 @@ extern void unlock_ref(struct ref_lock *lock);
 extern int write_ref_sha1(struct ref_lock *lock, const unsigned char *sha1, const char *msg);
 
 /** Reads log for the value of ref during at_time. **/
-extern int read_ref_at(const char *ref, unsigned long at_time, unsigned char *sha1);
+extern int read_ref_at(const char *ref, unsigned long at_time, int cnt, unsigned char *sha1);
 
 /** Returns 0 if target has the right format for a ref. **/
 extern int check_ref_format(const char *target);
index ed711f2..5cf5578 100644 (file)
@@ -249,24 +249,23 @@ static int get_sha1_basic(const char *str, int len, unsigned char *sha1)
        static const char *warning = "warning: refname '%.*s' is ambiguous.\n";
        const char **p, *ref;
        char *real_ref = NULL;
-       int refs_found = 0, am;
-       unsigned long at_time = (unsigned long)-1;
+       int refs_found = 0;
+       int at, reflog_len;
        unsigned char *this_result;
        unsigned char sha1_from_ref[20];
 
        if (len == 40 && !get_sha1_hex(str, sha1))
                return 0;
 
-       /* At a given period of time? "@{2 hours ago}" */
-       for (am = 1; am < len - 1; am++) {
-               if (str[am] == '@' && str[am+1] == '{' && str[len-1] == '}') {
-                       int date_len = len - am - 3;
-                       char *date_spec = xmalloc(date_len + 1);
-                       strlcpy(date_spec, str + am + 2, date_len + 1);
-                       at_time = approxidate(date_spec);
-                       free(date_spec);
-                       len = am;
-                       break;
+       /* basic@{time or number} format to query ref-log */
+       reflog_len = at = 0;
+       if (str[len-1] == '}') {
+               for (at = 1; at < len - 1; at++) {
+                       if (str[at] == '@' && str[at+1] == '{') {
+                               reflog_len = (len-1) - (at+2);
+                               len = at;
+                               break;
+                       }
                }
        }
 
@@ -291,11 +290,22 @@ static int get_sha1_basic(const char *str, int len, unsigned char *sha1)
        if (warn_ambiguous_refs && refs_found > 1)
                fprintf(stderr, warning, len, str);
 
-       if (at_time != (unsigned long)-1) {
-               read_ref_at(
-                       real_ref,
-                       at_time,
-                       sha1);
+       if (reflog_len) {
+               /* Is it asking for N-th entry, or approxidate? */
+               int nth, i;
+               unsigned long at_time;
+               for (i = nth = 0; 0 <= nth && i < reflog_len; i++) {
+                       char ch = str[at+2+i];
+                       if ('0' <= ch && ch <= '9')
+                               nth = nth * 10 + ch - '0';
+                       else
+                               nth = -1;
+               }
+               if (0 <= nth)
+                       at_time = 0;
+               else
+                       at_time = approxidate(str + at + 2);
+               read_ref_at(real_ref, at_time, nth, sha1);
        }
 
        free(real_ref);