提交 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,
size_t timebuf_size);
int parse_date(const char *date, 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);
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)
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)
{
update_tm(tm, now, 24*60*60);
......@@ -770,6 +775,7 @@ static const struct special {
{ "PM", date_pm },
{ "AM", date_am },
{ "never", date_never },
{ "now", date_now },
{ NULL }
};
......@@ -790,7 +796,7 @@ static const struct typelen {
{ 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 special *s;
......@@ -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]);
if (match >= 3) {
tm->tm_mon = i;
*touched = 1;
return end;
}
}
......@@ -812,6 +819,7 @@ static const char *approxidate_alpha(const char *date, struct tm *tm, struct tm
int len = strlen(s->name);
if (match_string(date, s->name) == len) {
s->fn(tm, now, num);
*touched = 1;
return end;
}
}
......@@ -821,11 +829,14 @@ static const char *approxidate_alpha(const char *date, struct tm *tm, struct tm
int len = strlen(number_name[i]);
if (match_string(date, number_name[i]) == len) {
*num = i;
*touched = 1;
return end;
}
}
if (match_string(date, "last") == 4)
if (match_string(date, "last") == 4) {
*num = 1;
*touched = 1;
}
return end;
}
......@@ -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) {
update_tm(tm, now, tl->length * *num);
*num = 0;
*touched = 1;
return end;
}
tl++;
......@@ -852,6 +864,7 @@ static const char *approxidate_alpha(const char *date, struct tm *tm, struct tm
diff += 7*n;
update_tm(tm, now, diff * 24 * 60 * 60);
*touched = 1;
return end;
}
}
......@@ -866,6 +879,7 @@ static const char *approxidate_alpha(const char *date, struct tm *tm, struct tm
tm->tm_year--;
}
tm->tm_mon = n;
*touched = 1;
return end;
}
......@@ -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 */
tm->tm_year -= *num;
*num = 0;
*touched = 1;
return end;
}
......@@ -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 touched = 0;
struct tm tm, now;
time_t time_sec;
......@@ -951,33 +969,42 @@ static unsigned long approxidate_str(const char *date, const struct timeval *tv)
if (isdigit(c)) {
pending_number(&tm, &number);
date = approxidate_digit(date-1, &tm, &number);
touched = 1;
continue;
}
if (isalpha(c))
date = approxidate_alpha(date-1, &tm, &now, &number);
date = approxidate_alpha(date-1, &tm, &now, &number, &touched);
}
pending_number(&tm, &number);
if (!touched)
*error_ret = 1;
return update_tm(&tm, &now, 0);
}
unsigned long approxidate_relative(const char *date, const struct timeval *tv)
{
char buffer[50];
int errors = 0;
if (parse_date(date, buffer, sizeof(buffer)) > 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;
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);
}
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)
} else if (0 <= nth)
at_time = 0;
else {
int errors = 0;
char *tmp = xstrndup(str + at + 2, reflog_len);
at_time = approxidate(tmp);
at_time = approxidate_careful(tmp, &errors);
free(tmp);
if (errors)
return -1;
}
if (read_ref_at(real_ref, at_time, nth, sha1, NULL,
&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.
先完成此消息的编辑!
想要评论请 注册