提交 410e99fa 编写于 作者: J Junio C Hamano

Merge branch 'jc/maint-reflog-bad-timestamp' into maint

* jc/maint-reflog-bad-timestamp:
  t0101: use a fixed timestamp when searching in the reflog
  Update @{bogus.timestamp} fix not to die()
  approxidate_careful() reports errorneous date string
...@@ -747,7 +747,8 @@ const char *show_date_relative(unsigned long time, int tz, ...@@ -747,7 +747,8 @@ const char *show_date_relative(unsigned long time, int tz,
size_t timebuf_size); size_t timebuf_size);
int parse_date(const char *date, char *buf, int bufsize); int parse_date(const char *date, char *buf, int bufsize);
void datestamp(char *buf, int bufsize); void datestamp(char *buf, int bufsize);
unsigned long approxidate(const char *); #define approxidate(s) approxidate_careful((s), NULL)
unsigned long approxidate_careful(const char *, int *);
unsigned long approxidate_relative(const char *date, const struct timeval *now); unsigned long approxidate_relative(const char *date, const struct timeval *now);
enum date_mode parse_date_format(const char *format); enum date_mode parse_date_format(const char *format);
......
...@@ -696,6 +696,11 @@ static unsigned long update_tm(struct tm *tm, struct tm *now, unsigned long sec) ...@@ -696,6 +696,11 @@ static unsigned long update_tm(struct tm *tm, struct tm *now, unsigned long sec)
return n; return n;
} }
static void date_now(struct tm *tm, struct tm *now, int *num)
{
update_tm(tm, now, 0);
}
static void date_yesterday(struct tm *tm, struct tm *now, int *num) static void date_yesterday(struct tm *tm, struct tm *now, int *num)
{ {
update_tm(tm, now, 24*60*60); update_tm(tm, now, 24*60*60);
...@@ -770,6 +775,7 @@ static const struct special { ...@@ -770,6 +775,7 @@ static const struct special {
{ "PM", date_pm }, { "PM", date_pm },
{ "AM", date_am }, { "AM", date_am },
{ "never", date_never }, { "never", date_never },
{ "now", date_now },
{ NULL } { NULL }
}; };
...@@ -790,7 +796,7 @@ static const struct typelen { ...@@ -790,7 +796,7 @@ static const struct typelen {
{ NULL } { NULL }
}; };
static const char *approxidate_alpha(const char *date, struct tm *tm, struct tm *now, int *num) static const char *approxidate_alpha(const char *date, struct tm *tm, struct tm *now, int *num, int *touched)
{ {
const struct typelen *tl; const struct typelen *tl;
const struct special *s; const struct special *s;
...@@ -804,6 +810,7 @@ static const char *approxidate_alpha(const char *date, struct tm *tm, struct tm ...@@ -804,6 +810,7 @@ static const char *approxidate_alpha(const char *date, struct tm *tm, struct tm
int match = match_string(date, month_names[i]); int match = match_string(date, month_names[i]);
if (match >= 3) { if (match >= 3) {
tm->tm_mon = i; tm->tm_mon = i;
*touched = 1;
return end; return end;
} }
} }
...@@ -812,6 +819,7 @@ static const char *approxidate_alpha(const char *date, struct tm *tm, struct tm ...@@ -812,6 +819,7 @@ static const char *approxidate_alpha(const char *date, struct tm *tm, struct tm
int len = strlen(s->name); int len = strlen(s->name);
if (match_string(date, s->name) == len) { if (match_string(date, s->name) == len) {
s->fn(tm, now, num); s->fn(tm, now, num);
*touched = 1;
return end; return end;
} }
} }
...@@ -821,11 +829,14 @@ static const char *approxidate_alpha(const char *date, struct tm *tm, struct tm ...@@ -821,11 +829,14 @@ static const char *approxidate_alpha(const char *date, struct tm *tm, struct tm
int len = strlen(number_name[i]); int len = strlen(number_name[i]);
if (match_string(date, number_name[i]) == len) { if (match_string(date, number_name[i]) == len) {
*num = i; *num = i;
*touched = 1;
return end; return end;
} }
} }
if (match_string(date, "last") == 4) if (match_string(date, "last") == 4) {
*num = 1; *num = 1;
*touched = 1;
}
return end; return end;
} }
...@@ -835,6 +846,7 @@ static const char *approxidate_alpha(const char *date, struct tm *tm, struct tm ...@@ -835,6 +846,7 @@ static const char *approxidate_alpha(const char *date, struct tm *tm, struct tm
if (match_string(date, tl->type) >= len-1) { if (match_string(date, tl->type) >= len-1) {
update_tm(tm, now, tl->length * *num); update_tm(tm, now, tl->length * *num);
*num = 0; *num = 0;
*touched = 1;
return end; return end;
} }
tl++; tl++;
...@@ -852,6 +864,7 @@ static const char *approxidate_alpha(const char *date, struct tm *tm, struct tm ...@@ -852,6 +864,7 @@ static const char *approxidate_alpha(const char *date, struct tm *tm, struct tm
diff += 7*n; diff += 7*n;
update_tm(tm, now, diff * 24 * 60 * 60); update_tm(tm, now, diff * 24 * 60 * 60);
*touched = 1;
return end; return end;
} }
} }
...@@ -866,6 +879,7 @@ static const char *approxidate_alpha(const char *date, struct tm *tm, struct tm ...@@ -866,6 +879,7 @@ static const char *approxidate_alpha(const char *date, struct tm *tm, struct tm
tm->tm_year--; tm->tm_year--;
} }
tm->tm_mon = n; tm->tm_mon = n;
*touched = 1;
return end; return end;
} }
...@@ -873,6 +887,7 @@ static const char *approxidate_alpha(const char *date, struct tm *tm, struct tm ...@@ -873,6 +887,7 @@ static const char *approxidate_alpha(const char *date, struct tm *tm, struct tm
update_tm(tm, now, 0); /* fill in date fields if needed */ update_tm(tm, now, 0); /* fill in date fields if needed */
tm->tm_year -= *num; tm->tm_year -= *num;
*num = 0; *num = 0;
*touched = 1;
return end; return end;
} }
...@@ -929,9 +944,12 @@ static void pending_number(struct tm *tm, int *num) ...@@ -929,9 +944,12 @@ static void pending_number(struct tm *tm, int *num)
} }
} }
static unsigned long approxidate_str(const char *date, const struct timeval *tv) static unsigned long approxidate_str(const char *date,
const struct timeval *tv,
int *error_ret)
{ {
int number = 0; int number = 0;
int touched = 0;
struct tm tm, now; struct tm tm, now;
time_t time_sec; time_t time_sec;
...@@ -951,33 +969,42 @@ static unsigned long approxidate_str(const char *date, const struct timeval *tv) ...@@ -951,33 +969,42 @@ static unsigned long approxidate_str(const char *date, const struct timeval *tv)
if (isdigit(c)) { if (isdigit(c)) {
pending_number(&tm, &number); pending_number(&tm, &number);
date = approxidate_digit(date-1, &tm, &number); date = approxidate_digit(date-1, &tm, &number);
touched = 1;
continue; continue;
} }
if (isalpha(c)) if (isalpha(c))
date = approxidate_alpha(date-1, &tm, &now, &number); date = approxidate_alpha(date-1, &tm, &now, &number, &touched);
} }
pending_number(&tm, &number); pending_number(&tm, &number);
if (!touched)
*error_ret = 1;
return update_tm(&tm, &now, 0); return update_tm(&tm, &now, 0);
} }
unsigned long approxidate_relative(const char *date, const struct timeval *tv) unsigned long approxidate_relative(const char *date, const struct timeval *tv)
{ {
char buffer[50]; char buffer[50];
int errors = 0;
if (parse_date(date, buffer, sizeof(buffer)) > 0) if (parse_date(date, buffer, sizeof(buffer)) > 0)
return strtoul(buffer, NULL, 0); return strtoul(buffer, NULL, 0);
return approxidate_str(date, tv); return approxidate_str(date, tv, &errors);
} }
unsigned long approxidate(const char *date) unsigned long approxidate_careful(const char *date, int *error_ret)
{ {
struct timeval tv; struct timeval tv;
char buffer[50]; char buffer[50];
int dummy = 0;
if (!error_ret)
error_ret = &dummy;
if (parse_date(date, buffer, sizeof(buffer)) > 0) if (parse_date(date, buffer, sizeof(buffer)) > 0) {
*error_ret = 0;
return strtoul(buffer, NULL, 0); return strtoul(buffer, NULL, 0);
}
gettimeofday(&tv, NULL); gettimeofday(&tv, NULL);
return approxidate_str(date, &tv); return approxidate_str(date, &tv, error_ret);
} }
...@@ -395,9 +395,12 @@ static int get_sha1_basic(const char *str, int len, unsigned char *sha1) ...@@ -395,9 +395,12 @@ static int get_sha1_basic(const char *str, int len, unsigned char *sha1)
} else if (0 <= nth) } else if (0 <= nth)
at_time = 0; at_time = 0;
else { else {
int errors = 0;
char *tmp = xstrndup(str + at + 2, reflog_len); char *tmp = xstrndup(str + at + 2, reflog_len);
at_time = approxidate(tmp); at_time = approxidate_careful(tmp, &errors);
free(tmp); free(tmp);
if (errors)
return -1;
} }
if (read_ref_at(real_ref, at_time, nth, sha1, NULL, if (read_ref_at(real_ref, at_time, nth, sha1, NULL,
&co_time, &co_tz, &co_cnt)) { &co_time, &co_tz, &co_cnt)) {
......
#!/bin/sh
test_description='various @{whatever} syntax tests'
. ./test-lib.sh
test_expect_success 'setup' '
test_commit one &&
test_commit two
'
check_at() {
echo "$2" >expect &&
git log -1 --format=%s "$1" >actual &&
test_cmp expect actual
}
test_expect_success '@{0} shows current' '
check_at @{0} two
'
test_expect_success '@{1} shows old' '
check_at @{1} one
'
test_expect_success '@{now} shows current' '
check_at @{now} two
'
test_expect_success '@{2001-09-17} (before the first commit) shows old' '
check_at @{2001-09-17} one
'
test_expect_success 'silly approxidates work' '
check_at @{3.hot.dogs.and.30.years.ago} one
'
test_expect_success 'notice misspelled upstream' '
test_must_fail git log -1 --format=%s @{usptream}
'
test_expect_success 'complain about total nonsense' '
test_must_fail git log -1 --format=%s @{utter.bogosity}
'
test_done
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册