Skip to content

Commit 4207ed2

Browse files
rsahlberggitster
authored andcommitted
refs.c: change read_ref_at to use the reflog iterators
read_ref_at has its own parsing of the reflog file for no really good reason so lets change this to use the existing reflog iterators. This removes one instance where we manually unmarshall the reflog file format. Remove the now redundant ref_msg function. Log messages for errors are changed slightly. We no longer print the file name for the reflog, instead we refer to it as 'Log for ref <refname>'. This might be a minor useability regression, but I don't really think so, since experienced users would know where the log is anyway and inexperienced users would not know what to do about/how to repair 'Log ... has gap ...' anyway. Adapt the t1400 test to handle the change in log messages. Signed-off-by: Ronnie Sahlberg <sahlberg@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent e156455 commit 4207ed2

File tree

2 files changed

+105
-107
lines changed

2 files changed

+105
-107
lines changed

refs.c

Lines changed: 103 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -2930,119 +2930,117 @@ int create_symref(const char *ref_target, const char *refs_heads_master,
29302930
return 0;
29312931
}
29322932

2933-
static char *ref_msg(const char *line, const char *endp)
2934-
{
2935-
const char *ep;
2936-
line += 82;
2937-
ep = memchr(line, '\n', endp - line);
2938-
if (!ep)
2939-
ep = endp;
2940-
return xmemdupz(line, ep - line);
2933+
struct read_ref_at_cb {
2934+
const char *refname;
2935+
unsigned long at_time;
2936+
int cnt;
2937+
int reccnt;
2938+
unsigned char *sha1;
2939+
int found_it;
2940+
2941+
unsigned char osha1[20];
2942+
unsigned char nsha1[20];
2943+
int tz;
2944+
unsigned long date;
2945+
char **msg;
2946+
unsigned long *cutoff_time;
2947+
int *cutoff_tz;
2948+
int *cutoff_cnt;
2949+
};
2950+
2951+
static int read_ref_at_ent(unsigned char *osha1, unsigned char *nsha1,
2952+
const char *email, unsigned long timestamp, int tz,
2953+
const char *message, void *cb_data)
2954+
{
2955+
struct read_ref_at_cb *cb = cb_data;
2956+
2957+
cb->reccnt++;
2958+
cb->tz = tz;
2959+
cb->date = timestamp;
2960+
2961+
if (timestamp <= cb->at_time || cb->cnt == 0) {
2962+
if (cb->msg)
2963+
*cb->msg = xstrdup(message);
2964+
if (cb->cutoff_time)
2965+
*cb->cutoff_time = timestamp;
2966+
if (cb->cutoff_tz)
2967+
*cb->cutoff_tz = tz;
2968+
if (cb->cutoff_cnt)
2969+
*cb->cutoff_cnt = cb->reccnt - 1;
2970+
/*
2971+
* we have not yet updated cb->[n|o]sha1 so they still
2972+
* hold the values for the previous record.
2973+
*/
2974+
if (!is_null_sha1(cb->osha1)) {
2975+
hashcpy(cb->sha1, nsha1);
2976+
if (hashcmp(cb->osha1, nsha1))
2977+
warning("Log for ref %s has gap after %s.",
2978+
cb->refname, show_date(cb->date, cb->tz, DATE_RFC2822));
2979+
}
2980+
else if (cb->date == cb->at_time)
2981+
hashcpy(cb->sha1, nsha1);
2982+
else if (hashcmp(nsha1, cb->sha1))
2983+
warning("Log for ref %s unexpectedly ended on %s.",
2984+
cb->refname, show_date(cb->date, cb->tz,
2985+
DATE_RFC2822));
2986+
hashcpy(cb->osha1, osha1);
2987+
hashcpy(cb->nsha1, nsha1);
2988+
cb->found_it = 1;
2989+
return 1;
2990+
}
2991+
hashcpy(cb->osha1, osha1);
2992+
hashcpy(cb->nsha1, nsha1);
2993+
if (cb->cnt > 0)
2994+
cb->cnt--;
2995+
return 0;
2996+
}
2997+
2998+
static int read_ref_at_ent_oldest(unsigned char *osha1, unsigned char *nsha1,
2999+
const char *email, unsigned long timestamp,
3000+
int tz, const char *message, void *cb_data)
3001+
{
3002+
struct read_ref_at_cb *cb = cb_data;
3003+
3004+
if (cb->msg)
3005+
*cb->msg = xstrdup(message);
3006+
if (cb->cutoff_time)
3007+
*cb->cutoff_time = timestamp;
3008+
if (cb->cutoff_tz)
3009+
*cb->cutoff_tz = tz;
3010+
if (cb->cutoff_cnt)
3011+
*cb->cutoff_cnt = cb->reccnt;
3012+
hashcpy(cb->sha1, osha1);
3013+
if (is_null_sha1(cb->sha1))
3014+
hashcpy(cb->sha1, nsha1);
3015+
/* We just want the first entry */
3016+
return 1;
29413017
}
29423018

29433019
int read_ref_at(const char *refname, unsigned long at_time, int cnt,
29443020
unsigned char *sha1, char **msg,
29453021
unsigned long *cutoff_time, int *cutoff_tz, int *cutoff_cnt)
29463022
{
2947-
const char *logfile, *logdata, *logend, *rec, *lastgt, *lastrec;
2948-
char *tz_c;
2949-
int logfd, tz, reccnt = 0;
2950-
struct stat st;
2951-
unsigned long date;
2952-
unsigned char logged_sha1[20];
2953-
void *log_mapped;
2954-
size_t mapsz;
3023+
struct read_ref_at_cb cb;
29553024

2956-
logfile = git_path("logs/%s", refname);
2957-
logfd = open(logfile, O_RDONLY, 0);
2958-
if (logfd < 0)
2959-
die_errno("Unable to read log '%s'", logfile);
2960-
fstat(logfd, &st);
2961-
if (!st.st_size)
2962-
die("Log %s is empty.", logfile);
2963-
mapsz = xsize_t(st.st_size);
2964-
log_mapped = xmmap(NULL, mapsz, PROT_READ, MAP_PRIVATE, logfd, 0);
2965-
logdata = log_mapped;
2966-
close(logfd);
3025+
memset(&cb, 0, sizeof(cb));
3026+
cb.refname = refname;
3027+
cb.at_time = at_time;
3028+
cb.cnt = cnt;
3029+
cb.msg = msg;
3030+
cb.cutoff_time = cutoff_time;
3031+
cb.cutoff_tz = cutoff_tz;
3032+
cb.cutoff_cnt = cutoff_cnt;
3033+
cb.sha1 = sha1;
3034+
3035+
for_each_reflog_ent_reverse(refname, read_ref_at_ent, &cb);
3036+
3037+
if (!cb.reccnt)
3038+
die("Log for %s is empty.", refname);
3039+
if (cb.found_it)
3040+
return 0;
3041+
3042+
for_each_reflog_ent(refname, read_ref_at_ent_oldest, &cb);
29673043

2968-
lastrec = NULL;
2969-
rec = logend = logdata + st.st_size;
2970-
while (logdata < rec) {
2971-
reccnt++;
2972-
if (logdata < rec && *(rec-1) == '\n')
2973-
rec--;
2974-
lastgt = NULL;
2975-
while (logdata < rec && *(rec-1) != '\n') {
2976-
rec--;
2977-
if (*rec == '>')
2978-
lastgt = rec;
2979-
}
2980-
if (!lastgt)
2981-
die("Log %s is corrupt.", logfile);
2982-
date = strtoul(lastgt + 1, &tz_c, 10);
2983-
if (date <= at_time || cnt == 0) {
2984-
tz = strtoul(tz_c, NULL, 10);
2985-
if (msg)
2986-
*msg = ref_msg(rec, logend);
2987-
if (cutoff_time)
2988-
*cutoff_time = date;
2989-
if (cutoff_tz)
2990-
*cutoff_tz = tz;
2991-
if (cutoff_cnt)
2992-
*cutoff_cnt = reccnt - 1;
2993-
if (lastrec) {
2994-
if (get_sha1_hex(lastrec, logged_sha1))
2995-
die("Log %s is corrupt.", logfile);
2996-
if (get_sha1_hex(rec + 41, sha1))
2997-
die("Log %s is corrupt.", logfile);
2998-
if (hashcmp(logged_sha1, sha1)) {
2999-
warning("Log %s has gap after %s.",
3000-
logfile, show_date(date, tz, DATE_RFC2822));
3001-
}
3002-
}
3003-
else if (date == at_time) {
3004-
if (get_sha1_hex(rec + 41, sha1))
3005-
die("Log %s is corrupt.", logfile);
3006-
}
3007-
else {
3008-
if (get_sha1_hex(rec + 41, logged_sha1))
3009-
die("Log %s is corrupt.", logfile);
3010-
if (hashcmp(logged_sha1, sha1)) {
3011-
warning("Log %s unexpectedly ended on %s.",
3012-
logfile, show_date(date, tz, DATE_RFC2822));
3013-
}
3014-
}
3015-
munmap(log_mapped, mapsz);
3016-
return 0;
3017-
}
3018-
lastrec = rec;
3019-
if (cnt > 0)
3020-
cnt--;
3021-
}
3022-
3023-
rec = logdata;
3024-
while (rec < logend && *rec != '>' && *rec != '\n')
3025-
rec++;
3026-
if (rec == logend || *rec == '\n')
3027-
die("Log %s is corrupt.", logfile);
3028-
date = strtoul(rec + 1, &tz_c, 10);
3029-
tz = strtoul(tz_c, NULL, 10);
3030-
if (get_sha1_hex(logdata, sha1))
3031-
die("Log %s is corrupt.", logfile);
3032-
if (is_null_sha1(sha1)) {
3033-
if (get_sha1_hex(logdata + 41, sha1))
3034-
die("Log %s is corrupt.", logfile);
3035-
}
3036-
if (msg)
3037-
*msg = ref_msg(logdata, logend);
3038-
munmap(log_mapped, mapsz);
3039-
3040-
if (cutoff_time)
3041-
*cutoff_time = date;
3042-
if (cutoff_tz)
3043-
*cutoff_tz = tz;
3044-
if (cutoff_cnt)
3045-
*cutoff_cnt = reccnt;
30463044
return 1;
30473045
}
30483046

t/t1400-update-ref.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ test_expect_success \
235235
'rm -f o e &&
236236
git rev-parse --verify "master@{2005-05-26 23:33:01}" >o 2>e &&
237237
test '"$B"' = $(cat o) &&
238-
test "warning: Log .git/logs/'"$m has gap after $gd"'." = "$(cat e)"'
238+
test "warning: Log for ref '"$m has gap after $gd"'." = "$(cat e)"'
239239
test_expect_success \
240240
'Query "master@{2005-05-26 23:38:00}" (middle of history)' \
241241
'rm -f o e &&
@@ -253,7 +253,7 @@ test_expect_success \
253253
'rm -f o e &&
254254
git rev-parse --verify "master@{2005-05-28}" >o 2>e &&
255255
test '"$D"' = $(cat o) &&
256-
test "warning: Log .git/logs/'"$m unexpectedly ended on $ld"'." = "$(cat e)"'
256+
test "warning: Log for ref '"$m unexpectedly ended on $ld"'." = "$(cat e)"'
257257

258258

259259
rm -f .git/$m .git/logs/$m expect

0 commit comments

Comments
 (0)