Skip to content

Commit 410e99f

Browse files
committed
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
2 parents c329898 + 6c647af commit 410e99f

File tree

4 files changed

+86
-10
lines changed

4 files changed

+86
-10
lines changed

cache.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -747,7 +747,8 @@ const char *show_date_relative(unsigned long time, int tz,
747747
size_t timebuf_size);
748748
int parse_date(const char *date, char *buf, int bufsize);
749749
void datestamp(char *buf, int bufsize);
750-
unsigned long approxidate(const char *);
750+
#define approxidate(s) approxidate_careful((s), NULL)
751+
unsigned long approxidate_careful(const char *, int *);
751752
unsigned long approxidate_relative(const char *date, const struct timeval *now);
752753
enum date_mode parse_date_format(const char *format);
753754

date.c

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -696,6 +696,11 @@ static unsigned long update_tm(struct tm *tm, struct tm *now, unsigned long sec)
696696
return n;
697697
}
698698

699+
static void date_now(struct tm *tm, struct tm *now, int *num)
700+
{
701+
update_tm(tm, now, 0);
702+
}
703+
699704
static void date_yesterday(struct tm *tm, struct tm *now, int *num)
700705
{
701706
update_tm(tm, now, 24*60*60);
@@ -770,6 +775,7 @@ static const struct special {
770775
{ "PM", date_pm },
771776
{ "AM", date_am },
772777
{ "never", date_never },
778+
{ "now", date_now },
773779
{ NULL }
774780
};
775781

@@ -790,7 +796,7 @@ static const struct typelen {
790796
{ NULL }
791797
};
792798

793-
static const char *approxidate_alpha(const char *date, struct tm *tm, struct tm *now, int *num)
799+
static const char *approxidate_alpha(const char *date, struct tm *tm, struct tm *now, int *num, int *touched)
794800
{
795801
const struct typelen *tl;
796802
const struct special *s;
@@ -804,6 +810,7 @@ static const char *approxidate_alpha(const char *date, struct tm *tm, struct tm
804810
int match = match_string(date, month_names[i]);
805811
if (match >= 3) {
806812
tm->tm_mon = i;
813+
*touched = 1;
807814
return end;
808815
}
809816
}
@@ -812,6 +819,7 @@ static const char *approxidate_alpha(const char *date, struct tm *tm, struct tm
812819
int len = strlen(s->name);
813820
if (match_string(date, s->name) == len) {
814821
s->fn(tm, now, num);
822+
*touched = 1;
815823
return end;
816824
}
817825
}
@@ -821,11 +829,14 @@ static const char *approxidate_alpha(const char *date, struct tm *tm, struct tm
821829
int len = strlen(number_name[i]);
822830
if (match_string(date, number_name[i]) == len) {
823831
*num = i;
832+
*touched = 1;
824833
return end;
825834
}
826835
}
827-
if (match_string(date, "last") == 4)
836+
if (match_string(date, "last") == 4) {
828837
*num = 1;
838+
*touched = 1;
839+
}
829840
return end;
830841
}
831842

@@ -835,6 +846,7 @@ static const char *approxidate_alpha(const char *date, struct tm *tm, struct tm
835846
if (match_string(date, tl->type) >= len-1) {
836847
update_tm(tm, now, tl->length * *num);
837848
*num = 0;
849+
*touched = 1;
838850
return end;
839851
}
840852
tl++;
@@ -852,6 +864,7 @@ static const char *approxidate_alpha(const char *date, struct tm *tm, struct tm
852864
diff += 7*n;
853865

854866
update_tm(tm, now, diff * 24 * 60 * 60);
867+
*touched = 1;
855868
return end;
856869
}
857870
}
@@ -866,13 +879,15 @@ static const char *approxidate_alpha(const char *date, struct tm *tm, struct tm
866879
tm->tm_year--;
867880
}
868881
tm->tm_mon = n;
882+
*touched = 1;
869883
return end;
870884
}
871885

872886
if (match_string(date, "years") >= 4) {
873887
update_tm(tm, now, 0); /* fill in date fields if needed */
874888
tm->tm_year -= *num;
875889
*num = 0;
890+
*touched = 1;
876891
return end;
877892
}
878893

@@ -929,9 +944,12 @@ static void pending_number(struct tm *tm, int *num)
929944
}
930945
}
931946

932-
static unsigned long approxidate_str(const char *date, const struct timeval *tv)
947+
static unsigned long approxidate_str(const char *date,
948+
const struct timeval *tv,
949+
int *error_ret)
933950
{
934951
int number = 0;
952+
int touched = 0;
935953
struct tm tm, now;
936954
time_t time_sec;
937955

@@ -951,33 +969,42 @@ static unsigned long approxidate_str(const char *date, const struct timeval *tv)
951969
if (isdigit(c)) {
952970
pending_number(&tm, &number);
953971
date = approxidate_digit(date-1, &tm, &number);
972+
touched = 1;
954973
continue;
955974
}
956975
if (isalpha(c))
957-
date = approxidate_alpha(date-1, &tm, &now, &number);
976+
date = approxidate_alpha(date-1, &tm, &now, &number, &touched);
958977
}
959978
pending_number(&tm, &number);
979+
if (!touched)
980+
*error_ret = 1;
960981
return update_tm(&tm, &now, 0);
961982
}
962983

963984
unsigned long approxidate_relative(const char *date, const struct timeval *tv)
964985
{
965986
char buffer[50];
987+
int errors = 0;
966988

967989
if (parse_date(date, buffer, sizeof(buffer)) > 0)
968990
return strtoul(buffer, NULL, 0);
969991

970-
return approxidate_str(date, tv);
992+
return approxidate_str(date, tv, &errors);
971993
}
972994

973-
unsigned long approxidate(const char *date)
995+
unsigned long approxidate_careful(const char *date, int *error_ret)
974996
{
975997
struct timeval tv;
976998
char buffer[50];
999+
int dummy = 0;
1000+
if (!error_ret)
1001+
error_ret = &dummy;
9771002

978-
if (parse_date(date, buffer, sizeof(buffer)) > 0)
1003+
if (parse_date(date, buffer, sizeof(buffer)) > 0) {
1004+
*error_ret = 0;
9791005
return strtoul(buffer, NULL, 0);
1006+
}
9801007

9811008
gettimeofday(&tv, NULL);
982-
return approxidate_str(date, &tv);
1009+
return approxidate_str(date, &tv, error_ret);
9831010
}

sha1_name.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -395,9 +395,12 @@ static int get_sha1_basic(const char *str, int len, unsigned char *sha1)
395395
} else if (0 <= nth)
396396
at_time = 0;
397397
else {
398+
int errors = 0;
398399
char *tmp = xstrndup(str + at + 2, reflog_len);
399-
at_time = approxidate(tmp);
400+
at_time = approxidate_careful(tmp, &errors);
400401
free(tmp);
402+
if (errors)
403+
return -1;
401404
}
402405
if (read_ref_at(real_ref, at_time, nth, sha1, NULL,
403406
&co_time, &co_tz, &co_cnt)) {

t/t0101-at-syntax.sh

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
#!/bin/sh
2+
3+
test_description='various @{whatever} syntax tests'
4+
. ./test-lib.sh
5+
6+
test_expect_success 'setup' '
7+
test_commit one &&
8+
test_commit two
9+
'
10+
11+
check_at() {
12+
echo "$2" >expect &&
13+
git log -1 --format=%s "$1" >actual &&
14+
test_cmp expect actual
15+
}
16+
17+
test_expect_success '@{0} shows current' '
18+
check_at @{0} two
19+
'
20+
21+
test_expect_success '@{1} shows old' '
22+
check_at @{1} one
23+
'
24+
25+
test_expect_success '@{now} shows current' '
26+
check_at @{now} two
27+
'
28+
29+
test_expect_success '@{2001-09-17} (before the first commit) shows old' '
30+
check_at @{2001-09-17} one
31+
'
32+
33+
test_expect_success 'silly approxidates work' '
34+
check_at @{3.hot.dogs.and.30.years.ago} one
35+
'
36+
37+
test_expect_success 'notice misspelled upstream' '
38+
test_must_fail git log -1 --format=%s @{usptream}
39+
'
40+
41+
test_expect_success 'complain about total nonsense' '
42+
test_must_fail git log -1 --format=%s @{utter.bogosity}
43+
'
44+
45+
test_done

0 commit comments

Comments
 (0)