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
This commit is contained in:
commit
410e99fadf
3
cache.h
3
cache.h
@ -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);
|
||||||
|
|
||||||
|
43
date.c
43
date.c
@ -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 {
|
|||||||
{ "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 {
|
|||||||
{ 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
|
|||||||
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
|
|||||||
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
|
|||||||
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
|
|||||||
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
|
|||||||
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
|
|||||||
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
|
|||||||
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)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
|||||||
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)
|
|||||||
} 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)) {
|
||||||
|
45
t/t0101-at-syntax.sh
Executable file
45
t/t0101-at-syntax.sh
Executable file
@ -0,0 +1,45 @@
|
|||||||
|
#!/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
|
Loading…
Reference in New Issue
Block a user