commit - e746ca7f4f68ff664bee61f8f658f551f8f7ec02
commit + 3f338f0a096f8648ea0bb148ba5e4383d6434eaa
blob - f666e84083ffb2ad05eab02a4fe4cc4a06853221
blob + 89ec5aabb1b27cad61902560dc7e83551e00665b
--- include/got_reference.h
+++ include/got_reference.h
/* Get the name of the reference which a symoblic reference points at. */
const char *got_ref_get_symref_target(struct got_reference *);
+/* Get the last modification timestamp of the reference. */
+time_t got_ref_get_mtime(struct got_reference *);
+
/*
* Create a duplicate copy of a reference.
* The caller must dispose of this copy with got_ref_close().
blob - ee703d1487de86d26b7373621514084605d208eb
blob + 1f7e7d1033f43108af0c239bd50be641dccfc47d
--- lib/reference.c
+++ lib/reference.c
} ref;
struct got_lockfile *lf;
+ time_t mtime;
};
static const struct got_error *
alloc_ref(struct got_reference **ref, const char *name,
- struct got_object_id *id, int flags)
+ struct got_object_id *id, int flags, time_t mtime)
{
const struct got_error *err = NULL;
memcpy((*ref)->ref.ref.sha1, id->sha1, sizeof((*ref)->ref.ref.sha1));
(*ref)->flags = flags;
(*ref)->ref.ref.name = strdup(name);
+ (*ref)->mtime = mtime;
if ((*ref)->ref.ref.name == NULL) {
err = got_error_from_errno("strdup");
got_ref_close(*ref);
}
static const struct got_error *
-parse_ref_line(struct got_reference **ref, const char *name, const char *line)
+parse_ref_line(struct got_reference **ref, const char *name, const char *line,
+ time_t mtime)
{
struct got_object_id id;
if (!got_parse_sha1_digest(id.sha1, line))
return got_error(GOT_ERR_BAD_REF_DATA);
- return alloc_ref(ref, name, &id, 0);
+ return alloc_ref(ref, name, &id, 0, mtime);
}
static const struct got_error *
size_t linesize = 0;
ssize_t linelen;
struct got_lockfile *lf = NULL;
+ struct stat sb;
if (lock) {
err = got_lockfile_lock(&lf, abspath, -1);
got_lockfile_unlock(lf, -1);
return err;
}
+ if (fstat(fileno(f), &sb) == -1) {
+ err = got_error_from_errno2("fstat", abspath);
+ goto done;
+ }
linelen = getline(&line, &linesize, f);
if (linelen == -1) {
linelen--;
}
- err = parse_ref_line(ref, absname, line);
+ err = parse_ref_line(ref, absname, line, sb.st_mtime);
if (lock) {
if (err)
got_lockfile_unlock(lf, -1);
if (!is_valid_ref_name(name))
return got_error_path(name, GOT_ERR_BAD_REF_NAME);
- return alloc_ref(ref, name, id, 0);
+ return alloc_ref(ref, name, id, 0, 0);
}
const struct got_error *
static const struct got_error *
parse_packed_ref_line(struct got_reference **ref, const char *abs_refname,
- const char *line)
+ const char *line, time_t mtime)
{
struct got_object_id id;
const char *name;
} else
name = line + SHA1_DIGEST_STRING_LENGTH;
- return alloc_ref(ref, name, &id, GOT_REF_IS_PACKED);
+ return alloc_ref(ref, name, &id, GOT_REF_IS_PACKED, mtime);
}
static const struct got_error *
open_packed_ref(struct got_reference **ref, FILE *f, const char **subdirs,
- int nsubdirs, const char *refname)
+ int nsubdirs, const char *refname, time_t mtime)
{
const struct got_error *err = NULL;
char *abs_refname;
asprintf(&abs_refname, "refs/%s/%s", subdirs[i],
refname) == -1)
return got_error_from_errno("asprintf");
- err = parse_packed_ref_line(ref, abs_refname, line);
+ err = parse_packed_ref_line(ref, abs_refname, line,
+ mtime);
if (!ref_is_absolute)
free(abs_refname);
if (err || *ref != NULL)
f = fopen(packed_refs_path, "rb");
free(packed_refs_path);
if (f != NULL) {
+ struct stat sb;
+ if (fstat(fileno(f), &sb) == -1) {
+ err = got_error_from_errno2("fstat",
+ packed_refs_path);
+ goto done;
+ }
err = open_packed_ref(ref, f, subdirs, nitems(subdirs),
- refname);
+ refname, sb.st_mtime);
if (!err) {
if (fclose(f) == EOF) {
err = got_error_from_errno("fclose");
return ref->ref.symref.ref;
return NULL;
+}
+
+time_t
+got_ref_get_mtime(struct got_reference *ref)
+{
+ return ref->mtime;
}
const struct got_error *
if (f) {
size_t linesize = 0;
ssize_t linelen;
+ struct stat sb;
+
+ if (fstat(fileno(f), &sb) == -1) {
+ err = got_error_from_errno2("fstat", packed_refs_path);
+ goto done;
+ }
for (;;) {
linelen = getline(&line, &linesize, f);
if (linelen == -1) {
}
if (linelen > 0 && line[linelen - 1] == '\n')
line[linelen - 1] = '\0';
- err = parse_packed_ref_line(&ref, NULL, line);
+ err = parse_packed_ref_line(&ref, NULL, line,
+ sb.st_mtime);
if (err)
goto done;
if (ref) {
}
free(tmppath);
tmppath = NULL;
+
+ if (stat(path, &sb) == -1) {
+ err = got_error_from_errno2("stat", path);
+ goto done;
+ }
+ ref->mtime = sb.st_mtime;
done:
if (ref->lf == NULL && lf)
unlock_err = got_lockfile_unlock(lf, -1);
}
if (linelen > 0 && line[linelen - 1] == '\n')
line[linelen - 1] = '\0';
- err = parse_packed_ref_line(&ref, NULL, line);
+ err = parse_packed_ref_line(&ref, NULL, line, 0);
if (err)
goto done;
if (ref == NULL)