{"thread":{"id":"6444","subject":"[PATCH 2/3] Extend read_ref_at() to be usable from places other than sha1_name.","startedAt":"2007-01-19T23:51:06Z","lastAt":"2007-01-19T23:51:06Z","messageCount":1,"participants":["Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":3},"messages":[{"id":"32102","messageId":"7vodoud191.fsf@assigned-by-dhcp.cox.net","threadId":"6444","inReplyTo":null,"subject":"[PATCH 2/3] Extend read_ref_at() to be usable from places other than sha1_name.","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2007-01-19T23:51:06Z","receivedAt":"2007-01-19T23:51:06Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"You can pass an extra argument to the function to receive the\nreflog message information.  Also when the log does not go back\nbeyond the point the user asked, the cut-off time and count are\ngiven back to the caller for emitting the error messages as\nappropriately.\n\nWe could later add configuration for get_sha1_basic() to make it\nan error instead of it being just a warning.\n\nSigned-off-by: Junio C Hamano <junkio@cox.net>\n---\n refs.c                |   41 +++++++++++++++++++++++++++++++++--------\n refs.h                |    2 +-\n sha1_name.c           |   16 +++++++++++++++-\n t/t1400-update-ref.sh |    6 +++---\n 4 files changed, 52 insertions(+), 13 deletions(-)\n\ndiff --git a/refs.c b/refs.c\nindex 6310cf4..60375a7 100644\n--- a/refs.c\n+++ b/refs.c\n@@ -1017,7 +1017,21 @@ int write_ref_sha1(struct ref_lock *lock,\n \treturn 0;\n }\n \n-int read_ref_at(const char *ref, unsigned long at_time, int cnt, unsigned char *sha1)\n+static char *ref_msg(const char *line, const char *endp)\n+{\n+\tconst char *ep;\n+\tchar *msg;\n+\n+\tline += 82;\n+\tfor (ep = line; ep < endp && *ep != '\\n'; ep++)\n+\t\t;\n+\tmsg = xmalloc(ep - line + 1);\n+\tmemcpy(msg, line, ep - line);\n+\tmsg[ep - line] = 0;\n+\treturn msg;\n+}\n+\n+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)\n {\n \tconst char *logfile, *logdata, *logend, *rec, *lastgt, *lastrec;\n \tchar *tz_c;\n@@ -1054,6 +1068,14 @@ int read_ref_at(const char *ref, unsigned long at_time, int cnt, unsigned char *\n \t\t\tdie(\"Log %s is corrupt.\", logfile);\n \t\tdate = strtoul(lastgt + 1, &tz_c, 10);\n \t\tif (date <= at_time || cnt == 0) {\n+\t\t\tif (msg)\n+\t\t\t\t*msg = ref_msg(rec, logend);\n+\t\t\tif (cutoff_time)\n+\t\t\t\t*cutoff_time = date;\n+\t\t\tif (cutoff_tz)\n+\t\t\t\t*cutoff_tz = tz;\n+\t\t\tif (cutoff_cnt)\n+\t\t\t\t*cutoff_cnt = reccnt;\n \t\t\tif (lastrec) {\n \t\t\t\tif (get_sha1_hex(lastrec, logged_sha1))\n \t\t\t\t\tdie(\"Log %s is corrupt.\", logfile);\n@@ -1097,14 +1119,17 @@ int read_ref_at(const char *ref, unsigned long at_time, int cnt, unsigned char *\n \ttz = strtoul(tz_c, NULL, 10);\n \tif (get_sha1_hex(logdata, sha1))\n \t\tdie(\"Log %s is corrupt.\", logfile);\n+\tif (msg)\n+\t\t*msg = ref_msg(logdata, logend);\n \tmunmap(log_mapped, st.st_size);\n-\tif (at_time)\n-\t\tfprintf(stderr, \"warning: Log %s only goes back to %s.\\n\",\n-\t\t\tlogfile, show_rfc2822_date(date, tz));\n-\telse\n-\t\tfprintf(stderr, \"warning: Log %s only has %d entries.\\n\",\n-\t\t\tlogfile, reccnt);\n-\treturn 0;\n+\n+\tif (cutoff_time)\n+\t\t*cutoff_time = date;\n+\tif (cutoff_tz)\n+\t\t*cutoff_tz = tz;\n+\tif (cutoff_cnt)\n+\t\t*cutoff_cnt = reccnt;\n+\treturn 1;\n }\n \n int for_each_reflog_ent(const char *ref, each_reflog_ent_fn fn, void *cb_data)\ndiff --git a/refs.h b/refs.h\nindex 0e877e8..33450f1 100644\n--- a/refs.h\n+++ b/refs.h\n@@ -42,7 +42,7 @@ extern void unlock_ref(struct ref_lock *lock);\n extern int write_ref_sha1(struct ref_lock *lock, const unsigned char *sha1, const char *msg);\n \n /** Reads log for the value of ref during at_time. **/\n-extern int read_ref_at(const char *ref, unsigned long at_time, int cnt, unsigned char *sha1);\n+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);\n \n /* iterate over reflog entries */\n typedef int each_reflog_ent_fn(unsigned char *osha1, unsigned char *nsha1, const char *, unsigned long, int, const char *, void *);\ndiff --git a/sha1_name.c b/sha1_name.c\nindex ae31851..9dfb3ac 100644\n--- a/sha1_name.c\n+++ b/sha1_name.c\n@@ -304,6 +304,9 @@ static int get_sha1_basic(const char *str, int len, unsigned char *sha1)\n \t\t/* Is it asking for N-th entry, or approxidate? */\n \t\tint nth, i;\n \t\tunsigned long at_time;\n+\t\tunsigned long co_time;\n+\t\tint co_tz, co_cnt;\n+\n \t\tfor (i = nth = 0; 0 <= nth && i < reflog_len; i++) {\n \t\t\tchar ch = str[at+2+i];\n \t\t\tif ('0' <= ch && ch <= '9')\n@@ -315,7 +318,18 @@ static int get_sha1_basic(const char *str, int len, unsigned char *sha1)\n \t\t\tat_time = 0;\n \t\telse\n \t\t\tat_time = approxidate(str + at + 2);\n-\t\tread_ref_at(real_ref, at_time, nth, sha1);\n+\t\tif (read_ref_at(real_ref, at_time, nth, sha1, NULL,\n+\t\t\t\t&co_time, &co_tz, &co_cnt)) {\n+\t\t\tif (at_time)\n+\t\t\t\tfprintf(stderr,\n+\t\t\t\t\t\"warning: Log for '%.*s' only goes \"\n+\t\t\t\t\t\"back to %s.\\n\", len, str,\n+\t\t\t\t\tshow_rfc2822_date(co_time, co_tz));\n+\t\t\telse\n+\t\t\t\tfprintf(stderr,\n+\t\t\t\t\t\"warning: Log for '%.*s' only has \"\n+\t\t\t\t\t\"%d entries.\\n\", len, str, co_cnt);\n+\t\t}\n \t}\n \n \tfree(real_ref);\ndiff --git a/t/t1400-update-ref.sh b/t/t1400-update-ref.sh\nindex 5637cb5..e48e2b7 100755\n--- a/t/t1400-update-ref.sh\n+++ b/t/t1400-update-ref.sh\n@@ -138,19 +138,19 @@ test_expect_success \\\n \t'rm -f o e\n \t git-rev-parse --verify \"master@{May 25 2005}\" >o 2>e &&\n \t test '\"$C\"' = $(cat o) &&\n-\t test \"warning: Log .git/logs/'\"$m only goes back to $ed\"'.\" = \"$(cat e)\"'\n+\t test \"warning: Log for '\\'master\\'' only goes back to $ed.\" = \"$(cat e)\"'\n test_expect_success \\\n \t\"Query master@{2005-05-25} (before history)\" \\\n \t'rm -f o e\n \t git-rev-parse --verify master@{2005-05-25} >o 2>e &&\n \t test '\"$C\"' = $(cat o) &&\n-\t echo test \"warning: Log .git/logs/'\"$m only goes back to $ed\"'.\" = \"$(cat e)\"'\n+\t echo test \"warning: Log for '\\'master\\'' only goes back to $ed.\" = \"$(cat e)\"'\n test_expect_success \\\n \t'Query \"master@{May 26 2005 23:31:59}\" (1 second before history)' \\\n \t'rm -f o e\n \t git-rev-parse --verify \"master@{May 26 2005 23:31:59}\" >o 2>e &&\n \t test '\"$C\"' = $(cat o) &&\n-\t test \"warning: Log .git/logs/'\"$m only goes back to $ed\"'.\" = \"$(cat e)\"'\n+\t test \"warning: Log for '\\''master'\\'' only goes back to $ed.\" = \"$(cat e)\"'\n test_expect_success \\\n \t'Query \"master@{May 26 2005 23:32:00}\" (exactly history start)' \\\n \t'rm -f o e\n-- \n1.5.0.rc1.gcb48c\n"}]}