Extend read_ref_at() to be usable from places other than sha1_name.
authorJunio C Hamano <junkio@cox.net>
Fri, 19 Jan 2007 09:19:05 +0000 (01:19 -0800)
committerJunio C Hamano <junkio@cox.net>
Sat, 20 Jan 2007 01:57:53 +0000 (17:57 -0800)
You can pass an extra argument to the function to receive the
reflog message information.  Also when the log does not go back
beyond the point the user asked, the cut-off time and count are
given back to the caller for emitting the error messages as
appropriately.

We could later add configuration for get_sha1_basic() to make it
an error instead of it being just a warning.

Signed-off-by: Junio C Hamano <junkio@cox.net>
refs.c
refs.h
sha1_name.c
t/t1400-update-ref.sh

diff --git a/refs.c b/refs.c
index 6310cf46e0500cce2338f50b5bfeba622bce52d4..60375a786f859a1cb9a4899bbad917740d41e29e 100644 (file)
--- a/refs.c
+++ b/refs.c
@@ -1017,7 +1017,21 @@ int write_ref_sha1(struct ref_lock *lock,
        return 0;
 }
 
-int read_ref_at(const char *ref, unsigned long at_time, int cnt, unsigned char *sha1)
+static char *ref_msg(const char *line, const char *endp)
+{
+       const char *ep;
+       char *msg;
+
+       line += 82;
+       for (ep = line; ep < endp && *ep != '\n'; ep++)
+               ;
+       msg = xmalloc(ep - line + 1);
+       memcpy(msg, line, ep - line);
+       msg[ep - line] = 0;
+       return msg;
+}
+
+int read_ref_at(const char *ref, unsigned long at_time, int cnt, unsigned char *sha1, char **msg, unsigned long *cutoff_time, int *cutoff_tz, int *cutoff_cnt)
 {
        const char *logfile, *logdata, *logend, *rec, *lastgt, *lastrec;
        char *tz_c;
@@ -1054,6 +1068,14 @@ int read_ref_at(const char *ref, unsigned long at_time, int cnt, unsigned char *
                        die("Log %s is corrupt.", logfile);
                date = strtoul(lastgt + 1, &tz_c, 10);
                if (date <= at_time || cnt == 0) {
+                       if (msg)
+                               *msg = ref_msg(rec, logend);
+                       if (cutoff_time)
+                               *cutoff_time = date;
+                       if (cutoff_tz)
+                               *cutoff_tz = tz;
+                       if (cutoff_cnt)
+                               *cutoff_cnt = reccnt;
                        if (lastrec) {
                                if (get_sha1_hex(lastrec, logged_sha1))
                                        die("Log %s is corrupt.", logfile);
@@ -1097,14 +1119,17 @@ int read_ref_at(const char *ref, unsigned long at_time, int cnt, unsigned char *
        tz = strtoul(tz_c, NULL, 10);
        if (get_sha1_hex(logdata, sha1))
                die("Log %s is corrupt.", logfile);
+       if (msg)
+               *msg = ref_msg(logdata, logend);
        munmap(log_mapped, st.st_size);
-       if (at_time)
-               fprintf(stderr, "warning: Log %s only goes back to %s.\n",
-                       logfile, show_rfc2822_date(date, tz));
-       else
-               fprintf(stderr, "warning: Log %s only has %d entries.\n",
-                       logfile, reccnt);
-       return 0;
+
+       if (cutoff_time)
+               *cutoff_time = date;
+       if (cutoff_tz)
+               *cutoff_tz = tz;
+       if (cutoff_cnt)
+               *cutoff_cnt = reccnt;
+       return 1;
 }
 
 int for_each_reflog_ent(const char *ref, each_reflog_ent_fn fn, void *cb_data)
diff --git a/refs.h b/refs.h
index 0e877e82ee1346c3d9d965581c62b337d596336f..33450f13e781b5ab60956082c7d8b2dc31f64286 100644 (file)
--- a/refs.h
+++ b/refs.h
@@ -42,7 +42,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, int cnt, unsigned char *sha1);
+extern int read_ref_at(const char *ref, unsigned long at_time, int cnt, unsigned char *sha1, char **msg, unsigned long *cutoff_time, int *cutoff_tz, int *cutoff_cnt);
 
 /* iterate over reflog entries */
 typedef int each_reflog_ent_fn(unsigned char *osha1, unsigned char *nsha1, const char *, unsigned long, int, const char *, void *);
index ae31851900cd3b7ef753e1a2254f9a4f1a5fcc8d..9dfb3ac57403793e6c6f78f2f75fb61c0a56c4bc 100644 (file)
@@ -304,6 +304,9 @@ static int get_sha1_basic(const char *str, int len, unsigned char *sha1)
                /* Is it asking for N-th entry, or approxidate? */
                int nth, i;
                unsigned long at_time;
+               unsigned long co_time;
+               int co_tz, co_cnt;
+
                for (i = nth = 0; 0 <= nth && i < reflog_len; i++) {
                        char ch = str[at+2+i];
                        if ('0' <= ch && ch <= '9')
@@ -315,7 +318,18 @@ static int get_sha1_basic(const char *str, int len, unsigned char *sha1)
                        at_time = 0;
                else
                        at_time = approxidate(str + at + 2);
-               read_ref_at(real_ref, at_time, nth, sha1);
+               if (read_ref_at(real_ref, at_time, nth, sha1, NULL,
+                               &co_time, &co_tz, &co_cnt)) {
+                       if (at_time)
+                               fprintf(stderr,
+                                       "warning: Log for '%.*s' only goes "
+                                       "back to %s.\n", len, str,
+                                       show_rfc2822_date(co_time, co_tz));
+                       else
+                               fprintf(stderr,
+                                       "warning: Log for '%.*s' only has "
+                                       "%d entries.\n", len, str, co_cnt);
+               }
        }
 
        free(real_ref);
index 5637cb5eac2fa77ec3882263418c363a4da8a69a..e48e2b7189c5cd21cdef65eb7b93314f1c4b1909 100755 (executable)
@@ -138,19 +138,19 @@ test_expect_success \
        'rm -f o e
         git-rev-parse --verify "master@{May 25 2005}" >o 2>e &&
         test '"$C"' = $(cat o) &&
-        test "warning: Log .git/logs/'"$m only goes back to $ed"'." = "$(cat e)"'
+        test "warning: Log for '\'master\'' only goes back to $ed." = "$(cat e)"'
 test_expect_success \
        "Query master@{2005-05-25} (before history)" \
        'rm -f o e
         git-rev-parse --verify master@{2005-05-25} >o 2>e &&
         test '"$C"' = $(cat o) &&
-        echo test "warning: Log .git/logs/'"$m only goes back to $ed"'." = "$(cat e)"'
+        echo test "warning: Log for '\'master\'' only goes back to $ed." = "$(cat e)"'
 test_expect_success \
        'Query "master@{May 26 2005 23:31:59}" (1 second before history)' \
        'rm -f o e
         git-rev-parse --verify "master@{May 26 2005 23:31:59}" >o 2>e &&
         test '"$C"' = $(cat o) &&
-        test "warning: Log .git/logs/'"$m only goes back to $ed"'." = "$(cat e)"'
+        test "warning: Log for '\''master'\'' only goes back to $ed." = "$(cat e)"'
 test_expect_success \
        'Query "master@{May 26 2005 23:32:00}" (exactly history start)' \
        'rm -f o e