Merge branch 'js/larger-timestamps'
authorJunio C Hamano <gitster@pobox.com>
Tue, 16 May 2017 02:51:59 +0000 (11:51 +0900)
committerJunio C Hamano <gitster@pobox.com>
Tue, 16 May 2017 02:51:59 +0000 (11:51 +0900)
Some platforms have ulong that is smaller than time_t, and our
historical use of ulong for timestamp would mean they cannot
represent some timestamp that the platform allows. Invent a
separate and dedicated timestamp_t (so that we can distingiuish
timestamps and a vanilla ulongs, which along is already a good
move), and then declare uintmax_t is the type to be used as the
timestamp_t.

* js/larger-timestamps:
archive-tar: fix a sparse 'constant too large' warning
use uintmax_t for timestamps
date.c: abort if the system time cannot handle one of our timestamps
timestamp_t: a new data type for timestamps
PRItime: introduce a new "printf format" for timestamps
parse_timestamp(): specify explicitly where we parse timestamps
t0006 & t5000: skip "far in the future" test when time_t is too limited
t0006 & t5000: prepare for 64-bit timestamps
ref-filter: avoid using `unsigned long` for catch-all data type

55 files changed:
Documentation/technical/api-parse-options.txt
archive-tar.c
archive-zip.c
archive.h
builtin/am.c
builtin/blame.c
builtin/fsck.c
builtin/gc.c
builtin/log.c
builtin/merge-base.c
builtin/name-rev.c
builtin/pack-objects.c
builtin/prune.c
builtin/receive-pack.c
builtin/reflog.c
builtin/rev-list.c
builtin/rev-parse.c
builtin/show-branch.c
builtin/worktree.c
bundle.c
cache.h
commit.c
commit.h
config.c
credential-cache--daemon.c
date.c
fetch-pack.c
fsck.c
git-compat-util.h
http-backend.c
parse-options-cb.c
pretty.c
reachable.c
reachable.h
ref-filter.c
reflog-walk.c
refs.c
refs.h
refs/files-backend.c
revision.c
revision.h
sha1_name.c
t/helper/test-date.c
t/helper/test-parse-options.c
t/helper/test-ref-store.c
t/t0006-date.sh
t/t5000-tar-tree.sh
t/test-lib.sh
tag.c
tag.h
upload-pack.c
vcs-svn/fast_export.c
vcs-svn/fast_export.h
vcs-svn/svndump.c
wt-status.c
index 36768b479e16c9456982230f078d98513a72c37f..829b5581105468d4d3b457e60b10cdbdf317fbbc 100644 (file)
@@ -183,13 +183,13 @@ There are some macros to easily define options:
        scale the provided value by 1024, 1024^2 or 1024^3 respectively.
        The scaled value is put into `unsigned_long_var`.
 
-`OPT_DATE(short, long, &int_var, description)`::
+`OPT_DATE(short, long, &timestamp_t_var, description)`::
        Introduce an option with date argument, see `approxidate()`.
-       The timestamp is put into `int_var`.
+       The timestamp is put into `timestamp_t_var`.
 
-`OPT_EXPIRY_DATE(short, long, &int_var, description)`::
+`OPT_EXPIRY_DATE(short, long, &timestamp_t_var, description)`::
        Introduce an option with expiry date argument, see `parse_expiry_date()`.
-       The timestamp is put into `int_var`.
+       The timestamp is put into `timestamp_t_var`.
 
 `OPT_CALLBACK(short, long, &var, arg_str, description, func_ptr)`::
        Introduce an option with argument.
index 380e3aedd23c02da9ba70d9c5a258550a9637c71..073e60ebd3c366b42298ae443eee230407d4e3a7 100644 (file)
@@ -27,10 +27,13 @@ static int write_tar_filter_archive(const struct archiver *ar,
  */
 #if ULONG_MAX == 0xFFFFFFFF
 #define USTAR_MAX_SIZE ULONG_MAX
-#define USTAR_MAX_MTIME ULONG_MAX
 #else
 #define USTAR_MAX_SIZE 077777777777UL
-#define USTAR_MAX_MTIME 077777777777UL
+#endif
+#if TIME_MAX == 0xFFFFFFFF
+#define USTAR_MAX_MTIME TIME_MAX
+#else
+#define USTAR_MAX_MTIME 077777777777ULL
 #endif
 
 /* writes out the whole block, but only if it is full */
index e81c5ac15a05d7d333005ff85fca767740693fc7..27563e9e2602108997033e6fa79c660bc08aa863 100644 (file)
@@ -593,9 +593,17 @@ static void write_zip_trailer(const unsigned char *sha1)
                write_or_die(1, sha1_to_hex(sha1), GIT_SHA1_HEXSZ);
 }
 
-static void dos_time(time_t *time, int *dos_date, int *dos_time)
+static void dos_time(timestamp_t *timestamp, int *dos_date, int *dos_time)
 {
-       struct tm *t = localtime(time);
+       time_t time;
+       struct tm *t;
+
+       if (date_overflows(*timestamp))
+               die("timestamp too large for this system: %"PRItime,
+                   *timestamp);
+       time = (time_t)*timestamp;
+       t = localtime(&time);
+       *timestamp = time;
 
        *dos_date = t->tm_mday + (t->tm_mon + 1) * 32 +
                    (t->tm_year + 1900 - 1980) * 512;
index 415e0152e2cf42827b1b370d2e5c78f6e91bd961..62d1d82c1af0fa3bf77b32d63e9b4866f3428898 100644 (file)
--- a/archive.h
+++ b/archive.h
@@ -9,7 +9,7 @@ struct archiver_args {
        struct tree *tree;
        const unsigned char *commit_sha1;
        const struct commit *commit;
-       time_t time;
+       timestamp_t time;
        struct pathspec pathspec;
        unsigned int verbose : 1;
        unsigned int worktree_attributes : 1;
index 17c80329c23beb2aa60621aa3dc10d95153c61e3..a63935cc83409ef99551a69da79d52ac297fe83a 100644 (file)
@@ -879,12 +879,12 @@ static int hg_patch_to_mail(FILE *out, FILE *in, int keep_cr)
                if (skip_prefix(sb.buf, "# User ", &str))
                        fprintf(out, "From: %s\n", str);
                else if (skip_prefix(sb.buf, "# Date ", &str)) {
-                       unsigned long timestamp;
+                       timestamp_t timestamp;
                        long tz, tz2;
                        char *end;
 
                        errno = 0;
-                       timestamp = strtoul(str, &end, 10);
+                       timestamp = parse_timestamp(str, &end, 10);
                        if (errno)
                                return error(_("invalid timestamp"));
 
index 07506a3e457d1540acb7700e4677d715d6842735..f00eda163788e3e3a94f2eb568e5a785bc72bc13 100644 (file)
@@ -1561,13 +1561,13 @@ static void pass_blame(struct scoreboard *sb, struct origin *origin, int opt)
 struct commit_info {
        struct strbuf author;
        struct strbuf author_mail;
-       unsigned long author_time;
+       timestamp_t author_time;
        struct strbuf author_tz;
 
        /* filled only when asked for details */
        struct strbuf committer;
        struct strbuf committer_mail;
-       unsigned long committer_time;
+       timestamp_t committer_time;
        struct strbuf committer_tz;
 
        struct strbuf summary;
@@ -1578,7 +1578,7 @@ struct commit_info {
  */
 static void get_ac_line(const char *inbuf, const char *what,
        struct strbuf *name, struct strbuf *mail,
-       unsigned long *time, struct strbuf *tz)
+       timestamp_t *time, struct strbuf *tz)
 {
        struct ident_split ident;
        size_t len, maillen, namelen;
@@ -1727,11 +1727,11 @@ static int emit_one_suspect_detail(struct origin *suspect, int repeat)
        get_commit_info(suspect->commit, &ci, 1);
        printf("author %s\n", ci.author.buf);
        printf("author-mail %s\n", ci.author_mail.buf);
-       printf("author-time %lu\n", ci.author_time);
+       printf("author-time %"PRItime"\n", ci.author_time);
        printf("author-tz %s\n", ci.author_tz.buf);
        printf("committer %s\n", ci.committer.buf);
        printf("committer-mail %s\n", ci.committer_mail.buf);
-       printf("committer-time %lu\n", ci.committer_time);
+       printf("committer-time %"PRItime"\n", ci.committer_time);
        printf("committer-tz %s\n", ci.committer_tz.buf);
        printf("summary %s\n", ci.summary.buf);
        if (suspect->commit->object.flags & UNINTERESTING)
@@ -1837,14 +1837,14 @@ static void assign_blame(struct scoreboard *sb, int opt)
        stop_progress(&pi.progress);
 }
 
-static const char *format_time(unsigned long time, const char *tz_str,
+static const char *format_time(timestamp_t time, const char *tz_str,
                               int show_raw_time)
 {
        static struct strbuf time_buf = STRBUF_INIT;
 
        strbuf_reset(&time_buf);
        if (show_raw_time) {
-               strbuf_addf(&time_buf, "%lu %s", time, tz_str);
+               strbuf_addf(&time_buf, "%"PRItime" %s", time, tz_str);
        }
        else {
                const char *time_str;
index b5e13a45560f9338a65191c22d213f33052bf9b9..32a32e55c8539372c11a36eba85f3bf14f0e221a 100644 (file)
@@ -397,7 +397,7 @@ static int fsck_obj_buffer(const unsigned char *sha1, enum object_type type,
 static int default_refs;
 
 static void fsck_handle_reflog_oid(const char *refname, struct object_id *oid,
-       unsigned long timestamp)
+       timestamp_t timestamp)
 {
        struct object *obj;
 
@@ -407,7 +407,7 @@ static void fsck_handle_reflog_oid(const char *refname, struct object_id *oid,
                        if (timestamp && name_objects)
                                add_decoration(fsck_walk_options.object_names,
                                        obj,
-                                       xstrfmt("%s@{%ld}", refname, timestamp));
+                                       xstrfmt("%s@{%"PRItime"}", refname, timestamp));
                        obj->used = 1;
                        mark_object_reachable(obj);
                } else {
@@ -418,7 +418,7 @@ static void fsck_handle_reflog_oid(const char *refname, struct object_id *oid,
 }
 
 static int fsck_handle_reflog_ent(struct object_id *ooid, struct object_id *noid,
-               const char *email, unsigned long timestamp, int tz,
+               const char *email, timestamp_t timestamp, int tz,
                const char *message, void *cb_data)
 {
        const char *refname = cb_data;
index 91f7696a85ec974d0ff5a1591cc404ed99efb7d7..f484eda43ca06046924931d2055b50c2f89ea8d7 100644 (file)
@@ -33,7 +33,7 @@ static int aggressive_window = 250;
 static int gc_auto_threshold = 6700;
 static int gc_auto_pack_limit = 50;
 static int detach_auto = 1;
-static unsigned long gc_log_expire_time;
+static timestamp_t gc_log_expire_time;
 static const char *gc_log_expire = "1.day.ago";
 static const char *prune_expire = "2.weeks.ago";
 static const char *prune_worktrees_expire = "3.months.ago";
index b3b10cc1edba2f6d77fdf4b12c328a7968fb5499..fd3d10ec21752b6ba78e3a2b4cd7a72af6ca8fe7 100644 (file)
@@ -910,8 +910,8 @@ static void get_patch_ids(struct rev_info *rev, struct patch_ids *ids)
 static void gen_message_id(struct rev_info *info, char *base)
 {
        struct strbuf buf = STRBUF_INIT;
-       strbuf_addf(&buf, "%s.%lu.git.%s", base,
-                   (unsigned long) time(NULL),
+       strbuf_addf(&buf, "%s.%"PRItime".git.%s", base,
+                   (timestamp_t) time(NULL),
                    git_committer_info(IDENT_NO_NAME|IDENT_NO_DATE|IDENT_STRICT));
        info->message_id = strbuf_detach(&buf, NULL);
 }
index cfe2a796f85ecf8dfbbb35d3232893929670b492..8ed96391c1d4d07c6a5944dd2dd7a70ca2565313 100644 (file)
@@ -132,7 +132,7 @@ static void add_one_commit(struct object_id *oid, struct rev_collect *revs)
 }
 
 static int collect_one_reflog_ent(struct object_id *ooid, struct object_id *noid,
-                                 const char *ident, unsigned long timestamp,
+                                 const char *ident, timestamp_t timestamp,
                                  int tz, const char *message, void *cbdata)
 {
        struct rev_collect *revs = cbdata;
index 92a5d8a5d263f78afaa2f426135998348dae53b8..44374750170e3c6721088cdaa9fdc4502905c242 100644 (file)
@@ -10,7 +10,7 @@
 
 typedef struct rev_name {
        const char *tip_name;
-       unsigned long taggerdate;
+       timestamp_t taggerdate;
        int generation;
        int distance;
 } rev_name;
@@ -21,7 +21,7 @@ static long cutoff = LONG_MAX;
 #define MERGE_TRAVERSAL_WEIGHT 65535
 
 static void name_rev(struct commit *commit,
-               const char *tip_name, unsigned long taggerdate,
+               const char *tip_name, timestamp_t taggerdate,
                int generation, int distance,
                int deref)
 {
@@ -146,7 +146,7 @@ static int name_ref(const char *path, const struct object_id *oid, int flags, vo
        struct name_ref_data *data = cb_data;
        int can_abbreviate_output = data->tags_only && data->name_only;
        int deref = 0;
-       unsigned long taggerdate = ULONG_MAX;
+       timestamp_t taggerdate = TIME_MAX;
 
        if (data->tags_only && !starts_with(path, "refs/tags/"))
                return 0;
index 0fe35d1b5aebd74116d66d5414bdabf19baf7d97..9b4ba8a80d7f0ac160467138507358f164b7af3e 100644 (file)
@@ -44,7 +44,7 @@ static uint32_t nr_result, nr_written;
 static int non_empty;
 static int reuse_delta = 1, reuse_object = 1;
 static int keep_unreachable, unpack_unreachable, include_tag;
-static unsigned long unpack_unreachable_expiration;
+static timestamp_t unpack_unreachable_expiration;
 static int pack_loose_unreachable;
 static int local;
 static int have_non_local_packs;
@@ -2675,7 +2675,7 @@ static int has_sha1_pack_kept_or_nonlocal(const unsigned char *sha1)
 static struct oid_array recent_objects;
 
 static int loosened_object_can_be_discarded(const struct object_id *oid,
-                                           unsigned long mtime)
+                                           timestamp_t mtime)
 {
        if (!unpack_unreachable_expiration)
                return 0;
index 42633e0c6e672c46852f0590f1941249691f962c..8dcfecde0f363e05fc2b95db3d8fce04d665ecf8 100644 (file)
@@ -13,7 +13,7 @@ static const char * const prune_usage[] = {
 };
 static int show_only;
 static int verbose;
-static unsigned long expire;
+static timestamp_t expire;
 static int show_progress = -1;
 
 static int prune_tmp_file(const char *fullpath)
@@ -111,7 +111,7 @@ int cmd_prune(int argc, const char **argv, const char *prefix)
        };
        char *s;
 
-       expire = ULONG_MAX;
+       expire = TIME_MAX;
        save_commit_buffer = 0;
        check_replace_refs = 0;
        ref_paranoia = 1;
index f96834f42c9849746b64c20c84869232cbac7367..0bb36d584d7e97ef0234c932d27e8312c1461107 100644 (file)
@@ -78,7 +78,7 @@ static const char *NONCE_OK = "OK";
 static const char *NONCE_SLOP = "SLOP";
 static const char *nonce_status;
 static long nonce_stamp_slop;
-static unsigned long nonce_stamp_slop_limit;
+static timestamp_t nonce_stamp_slop_limit;
 static struct ref_transaction *transaction;
 
 static enum {
@@ -454,17 +454,17 @@ static void hmac_sha1(unsigned char *out,
        git_SHA1_Final(out, &ctx);
 }
 
-static char *prepare_push_cert_nonce(const char *path, unsigned long stamp)
+static char *prepare_push_cert_nonce(const char *path, timestamp_t stamp)
 {
        struct strbuf buf = STRBUF_INIT;
        unsigned char sha1[20];
 
-       strbuf_addf(&buf, "%s:%lu", path, stamp);
+       strbuf_addf(&buf, "%s:%"PRItime, path, stamp);
        hmac_sha1(sha1, buf.buf, buf.len, cert_nonce_seed, strlen(cert_nonce_seed));;
        strbuf_release(&buf);
 
        /* RFC 2104 5. HMAC-SHA1-80 */
-       strbuf_addf(&buf, "%lu-%.*s", stamp, 20, sha1_to_hex(sha1));
+       strbuf_addf(&buf, "%"PRItime"-%.*s", stamp, 20, sha1_to_hex(sha1));
        return strbuf_detach(&buf, NULL);
 }
 
@@ -496,7 +496,7 @@ static char *find_header(const char *msg, size_t len, const char *key)
 static const char *check_nonce(const char *buf, size_t len)
 {
        char *nonce = find_header(buf, len, "nonce");
-       unsigned long stamp, ostamp;
+       timestamp_t stamp, ostamp;
        char *bohmac, *expect = NULL;
        const char *retval = NONCE_BAD;
 
@@ -534,7 +534,7 @@ static const char *check_nonce(const char *buf, size_t len)
                retval = NONCE_BAD;
                goto leave;
        }
-       stamp = strtoul(nonce, &bohmac, 10);
+       stamp = parse_timestamp(nonce, &bohmac, 10);
        if (bohmac == nonce || bohmac[0] != '-') {
                retval = NONCE_BAD;
                goto leave;
@@ -552,7 +552,7 @@ static const char *check_nonce(const char *buf, size_t len)
         * would mean it was issued by another server with its clock
         * skewed in the future.
         */
-       ostamp = strtoul(push_cert_nonce, NULL, 10);
+       ostamp = parse_timestamp(push_cert_nonce, NULL, 10);
        nonce_stamp_slop = (long)ostamp - (long)stamp;
 
        if (nonce_stamp_slop_limit &&
index 747277577857af2c71ab74b83d9ab3aea863c597..4228d9ff4dbeb0d423ec513809844cbcb8655225 100644 (file)
@@ -16,14 +16,14 @@ static const char reflog_delete_usage[] =
 static const char reflog_exists_usage[] =
 "git reflog exists <ref>";
 
-static unsigned long default_reflog_expire;
-static unsigned long default_reflog_expire_unreachable;
+static timestamp_t default_reflog_expire;
+static timestamp_t default_reflog_expire_unreachable;
 
 struct cmd_reflog_expire_cb {
        struct rev_info revs;
        int stalefix;
-       unsigned long expire_total;
-       unsigned long expire_unreachable;
+       timestamp_t expire_total;
+       timestamp_t expire_unreachable;
        int recno;
 };
 
@@ -219,7 +219,7 @@ static int keep_entry(struct commit **it, unsigned char *sha1)
 static void mark_reachable(struct expire_reflog_policy_cb *cb)
 {
        struct commit_list *pending;
-       unsigned long expire_limit = cb->mark_limit;
+       timestamp_t expire_limit = cb->mark_limit;
        struct commit_list *leftover = NULL;
 
        for (pending = cb->mark_list; pending; pending = pending->next)
@@ -284,7 +284,7 @@ static int unreachable(struct expire_reflog_policy_cb *cb, struct commit *commit
  * Return true iff the specified reflog entry should be expired.
  */
 static int should_expire_reflog_ent(unsigned char *osha1, unsigned char *nsha1,
-                                   const char *email, unsigned long timestamp, int tz,
+                                   const char *email, timestamp_t timestamp, int tz,
                                    const char *message, void *cb_data)
 {
        struct expire_reflog_policy_cb *cb = cb_data;
@@ -392,8 +392,8 @@ static int collect_reflog(const char *ref, const struct object_id *oid, int unus
 
 static struct reflog_expire_cfg {
        struct reflog_expire_cfg *next;
-       unsigned long expire_total;
-       unsigned long expire_unreachable;
+       timestamp_t expire_total;
+       timestamp_t expire_unreachable;
        char pattern[FLEX_ARRAY];
 } *reflog_expire_cfg, **reflog_expire_cfg_tail;
 
@@ -415,7 +415,7 @@ static struct reflog_expire_cfg *find_cfg_ent(const char *pattern, size_t len)
        return ent;
 }
 
-static int parse_expire_cfg_value(const char *var, const char *value, unsigned long *expire)
+static int parse_expire_cfg_value(const char *var, const char *value, timestamp_t *expire)
 {
        if (!value)
                return config_error_nonbool(var);
@@ -433,7 +433,7 @@ static int reflog_expire_config(const char *var, const char *value, void *cb)
 {
        const char *pattern, *key;
        int pattern_len;
-       unsigned long expire;
+       timestamp_t expire;
        int slot;
        struct reflog_expire_cfg *ent;
 
@@ -515,7 +515,7 @@ static void set_reflog_expiry_param(struct cmd_reflog_expire_cb *cb, int slot, c
 static int cmd_reflog_expire(int argc, const char **argv, const char *prefix)
 {
        struct expire_reflog_policy_cb cb;
-       unsigned long now = time(NULL);
+       timestamp_t now = time(NULL);
        int i, status, do_all;
        int explicit_expiry = 0;
        unsigned int flags = 0;
@@ -616,7 +616,7 @@ static int cmd_reflog_expire(int argc, const char **argv, const char *prefix)
 }
 
 static int count_reflog_ent(struct object_id *ooid, struct object_id *noid,
-               const char *email, unsigned long timestamp, int tz,
+               const char *email, timestamp_t timestamp, int tz,
                const char *message, void *cb_data)
 {
        struct expire_reflog_policy_cb *cb = cb_data;
index bcf77f0b8a201278f0887933e568937473eb7251..3b292c99bda97d78967e7c8e9575cb6f2e1e66ee 100644 (file)
@@ -80,7 +80,7 @@ static void show_commit(struct commit *commit, void *data)
        }
 
        if (info->show_timestamp)
-               printf("%lu ", commit->date);
+               printf("%"PRItime" ", commit->date);
        if (info->header_prefix)
                fputs(info->header_prefix, stdout);
 
index 051333091062ef8e2e717ec4aef8a9bdf3b4450f..b4509002435267f0f791813271326c7e211d3b45 100644 (file)
@@ -218,7 +218,7 @@ static void show_datestring(const char *flag, const char *datestr)
        /* date handling requires both flags and revs */
        if ((filter & (DO_FLAGS | DO_REVS)) != (DO_FLAGS | DO_REVS))
                return;
-       buffer = xstrfmt("%s%lu", flag, approxidate(datestr));
+       buffer = xstrfmt("%s%"PRItime, flag, approxidate(datestr));
        show(buffer);
        free(buffer);
 }
index 19756595d57f27c35c72449d03a95cefd55aef15..8860f429b06f0778aef1991fcfe9217fd4bda304 100644 (file)
@@ -735,7 +735,7 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)
                        base = strtoul(reflog_base, &ep, 10);
                        if (*ep) {
                                /* Ah, that is a date spec... */
-                               unsigned long at;
+                               timestamp_t at;
                                at = approxidate(reflog_base);
                                read_ref_at(ref, flags, at, -1, oid.hash, NULL,
                                            NULL, NULL, &base);
@@ -746,7 +746,7 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)
                        char *logmsg;
                        char *nth_desc;
                        const char *msg;
-                       unsigned long timestamp;
+                       timestamp_t timestamp;
                        int tz;
 
                        if (read_ref_at(ref, flags, 0, base+i, oid.hash, &logmsg,
index 1722a9bdc2a07ce3d98921299c6b57d03a50e870..11f90d6e45f44f96f637cc976163075181c78fac 100644 (file)
@@ -31,7 +31,7 @@ struct add_opts {
 
 static int show_only;
 static int verbose;
-static unsigned long expire;
+static timestamp_t expire;
 
 static int prune_worktree(const char *id, struct strbuf *reason)
 {
@@ -131,7 +131,7 @@ static int prune(int ac, const char **av, const char *prefix)
                OPT_END()
        };
 
-       expire = ULONG_MAX;
+       expire = TIME_MAX;
        ac = parse_options(ac, av, prefix, options, worktree_usage, 0);
        if (ac)
                usage_with_options(worktree_usage, options);
index bbf4efa0a0a38ac8f13ee1c2178eff1d2127c802..05e014fc5ab7e55149daf7b1bc7336d26fbc0923 100644 (file)
--- a/bundle.c
+++ b/bundle.c
@@ -211,7 +211,7 @@ static int is_tag_in_date_range(struct object *tag, struct rev_info *revs)
        unsigned long size;
        enum object_type type;
        char *buf = NULL, *line, *lineend;
-       unsigned long date;
+       timestamp_t date;
        int result = 1;
 
        if (revs->max_age == -1 && revs->min_age == -1)
@@ -227,7 +227,7 @@ static int is_tag_in_date_range(struct object *tag, struct rev_info *revs)
        line = memchr(line, '>', lineend ? lineend - line : buf + size - line);
        if (!line++)
                goto out;
-       date = strtoul(line, NULL, 10);
+       date = parse_timestamp(line, NULL, 10);
        result = (revs->max_age == -1 || revs->max_age < date) &&
                (revs->min_age == -1 || revs->min_age > date);
 out:
diff --git a/cache.h b/cache.h
index e1f0e182ad011d5a3b6912f48b597dcc6d1070b0..188811920ccf5b389332db252e389ae17e88d59f 100644 (file)
--- a/cache.h
+++ b/cache.h
@@ -1479,18 +1479,18 @@ struct date_mode {
 #define DATE_MODE(t) date_mode_from_type(DATE_##t)
 struct date_mode *date_mode_from_type(enum date_mode_type type);
 
-const char *show_date(unsigned long time, int timezone, const struct date_mode *mode);
-void show_date_relative(unsigned long time, int tz, const struct timeval *now,
+const char *show_date(timestamp_t time, int timezone, const struct date_mode *mode);
+void show_date_relative(timestamp_t time, int tz, const struct timeval *now,
                        struct strbuf *timebuf);
 int parse_date(const char *date, struct strbuf *out);
-int parse_date_basic(const char *date, unsigned long *timestamp, int *offset);
-int parse_expiry_date(const char *date, unsigned long *timestamp);
+int parse_date_basic(const char *date, timestamp_t *timestamp, int *offset);
+int parse_expiry_date(const char *date, timestamp_t *timestamp);
 void datestamp(struct strbuf *out);
 #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);
+timestamp_t approxidate_careful(const char *, int *);
+timestamp_t approxidate_relative(const char *date, const struct timeval *now);
 void parse_date_format(const char *format, struct date_mode *mode);
-int date_overflows(unsigned long date);
+int date_overflows(timestamp_t date);
 
 #define IDENT_STRICT          1
 #define IDENT_NO_DATE         2
index 73c78c2b80c1a21e83f1942347a76fb76511a0d3..99a62b90ee29280d9fb455d2907bb6885ca0fab6 100644 (file)
--- a/commit.c
+++ b/commit.c
@@ -66,7 +66,7 @@ struct commit *lookup_commit_reference_by_name(const char *name)
        return commit;
 }
 
-static unsigned long parse_commit_date(const char *buf, const char *tail)
+static timestamp_t parse_commit_date(const char *buf, const char *tail)
 {
        const char *dateptr;
 
@@ -89,8 +89,8 @@ static unsigned long parse_commit_date(const char *buf, const char *tail)
                /* nada */;
        if (buf >= tail)
                return 0;
-       /* dateptr < buf && buf[-1] == '\n', so strtoul will stop at buf-1 */
-       return strtoul(dateptr, NULL, 10);
+       /* dateptr < buf && buf[-1] == '\n', so parsing will stop at buf-1 */
+       return parse_timestamp(dateptr, NULL, 10);
 }
 
 static struct commit_graft **commit_graft;
@@ -473,8 +473,8 @@ struct commit_list * commit_list_insert_by_date(struct commit *item, struct comm
 
 static int commit_list_compare_by_date(const void *a, const void *b)
 {
-       unsigned long a_date = ((const struct commit_list *)a)->item->date;
-       unsigned long b_date = ((const struct commit_list *)b)->item->date;
+       timestamp_t a_date = ((const struct commit_list *)a)->item->date;
+       timestamp_t b_date = ((const struct commit_list *)b)->item->date;
        if (a_date < b_date)
                return 1;
        if (a_date > b_date)
@@ -598,7 +598,7 @@ static void record_author_date(struct author_date_slab *author_date,
        const char *ident_line;
        size_t ident_len;
        char *date_end;
-       unsigned long date;
+       timestamp_t date;
 
        ident_line = find_commit_header(buffer, "author", &ident_len);
        if (!ident_line)
@@ -607,7 +607,7 @@ static void record_author_date(struct author_date_slab *author_date,
            !ident.date_begin || !ident.date_end)
                goto fail_exit; /* malformed "author" line */
 
-       date = strtoul(ident.date_begin, &date_end, 10);
+       date = parse_timestamp(ident.date_begin, &date_end, 10);
        if (date_end != ident.date_end)
                goto fail_exit; /* malformed date */
        *(author_date_slab_at(author_date, commit)) = date;
@@ -621,8 +621,8 @@ static int compare_commits_by_author_date(const void *a_, const void *b_,
 {
        const struct commit *a = a_, *b = b_;
        struct author_date_slab *author_date = cb_data;
-       unsigned long a_date = *(author_date_slab_at(author_date, a));
-       unsigned long b_date = *(author_date_slab_at(author_date, b));
+       timestamp_t a_date = *(author_date_slab_at(author_date, a));
+       timestamp_t b_date = *(author_date_slab_at(author_date, b));
 
        /* newer commits with larger date first */
        if (a_date < b_date)
index 7b1986d5c8a0120ea90ee485ba46aff912de60fa..c9d887b5e533ede72900920450bcd9fd34636129 100644 (file)
--- a/commit.h
+++ b/commit.h
@@ -17,7 +17,7 @@ struct commit {
        struct object object;
        void *util;
        unsigned int index;
-       unsigned long date;
+       timestamp_t date;
        struct commit_list *parents;
        struct tree *tree;
 };
index b4a3205da32faf43db1ab990f08c0bb941af87d0..bb4d735701928d7f648c33ab371c04e3b7af12ad 100644 (file)
--- a/config.c
+++ b/config.c
@@ -1965,7 +1965,7 @@ int git_config_get_expiry(const char *key, const char **output)
        if (ret)
                return ret;
        if (strcmp(*output, "now")) {
-               unsigned long now = approxidate("now");
+               timestamp_t now = approxidate("now");
                if (approxidate(*output) >= now)
                        git_die_config(key, _("Invalid %s: '%s'"), key, *output);
        }
index 46c5937526a53c3563ea47bfba8195bcf9352c35..f3814cc47a059227e24ca52007c7e19fdf2db480 100644 (file)
@@ -8,7 +8,7 @@ static struct tempfile socket_file;
 
 struct credential_cache_entry {
        struct credential item;
-       unsigned long expiration;
+       timestamp_t expiration;
 };
 static struct credential_cache_entry *entries;
 static int entries_nr;
@@ -47,12 +47,12 @@ static void remove_credential(const struct credential *c)
                e->expiration = 0;
 }
 
-static int check_expirations(void)
+static timestamp_t check_expirations(void)
 {
-       static unsigned long wait_for_entry_until;
+       static timestamp_t wait_for_entry_until;
        int i = 0;
-       unsigned long now = time(NULL);
-       unsigned long next = (unsigned long)-1;
+       timestamp_t now = time(NULL);
+       timestamp_t next = TIME_MAX;
 
        /*
         * Initially give the client 30 seconds to actually contact us
@@ -159,7 +159,7 @@ static void serve_one_client(FILE *in, FILE *out)
 static int serve_cache_loop(int fd)
 {
        struct pollfd pfd;
-       unsigned long wakeup;
+       timestamp_t wakeup;
 
        wakeup = check_expirations();
        if (!wakeup)
diff --git a/date.c b/date.c
index a996331f5b33703c9f70844c6b49453ec39d16a7..63fa99685e288bd79c75fd6af983f8b628a08fed 100644 (file)
--- a/date.c
+++ b/date.c
@@ -39,14 +39,24 @@ static const char *weekday_names[] = {
        "Sundays", "Mondays", "Tuesdays", "Wednesdays", "Thursdays", "Fridays", "Saturdays"
 };
 
-static time_t gm_time_t(unsigned long time, int tz)
+static time_t gm_time_t(timestamp_t time, int tz)
 {
        int minutes;
 
        minutes = tz < 0 ? -tz : tz;
        minutes = (minutes / 100)*60 + (minutes % 100);
        minutes = tz < 0 ? -minutes : minutes;
-       return time + minutes * 60;
+
+       if (minutes > 0) {
+               if (unsigned_add_overflows(time, minutes * 60))
+                       die("Timestamp+tz too large: %"PRItime" +%04d",
+                           time, tz);
+       } else if (time < -minutes * 60)
+               die("Timestamp before Unix epoch: %"PRItime" %04d", time, tz);
+       time += minutes * 60;
+       if (date_overflows(time))
+               die("Timestamp too large for this system: %"PRItime, time);
+       return (time_t)time;
 }
 
 /*
@@ -54,7 +64,7 @@ static time_t gm_time_t(unsigned long time, int tz)
  * thing, which means that tz -0100 is passed in as the integer -100,
  * even though it means "sixty minutes off"
  */
-static struct tm *time_to_tm(unsigned long time, int tz)
+static struct tm *time_to_tm(timestamp_t time, int tz)
 {
        time_t t = gm_time_t(time, tz);
        return gmtime(&t);
@@ -64,13 +74,16 @@ static struct tm *time_to_tm(unsigned long time, int tz)
  * What value of "tz" was in effect back then at "time" in the
  * local timezone?
  */
-static int local_tzoffset(unsigned long time)
+static int local_tzoffset(timestamp_t time)
 {
        time_t t, t_local;
        struct tm tm;
        int offset, eastwest;
 
-       t = time;
+       if (date_overflows(time))
+               die("Timestamp too large for this system: %"PRItime, time);
+
+       t = (time_t)time;
        localtime_r(&t, &tm);
        t_local = tm_to_time_t(&tm);
 
@@ -88,11 +101,11 @@ static int local_tzoffset(unsigned long time)
        return offset * eastwest;
 }
 
-void show_date_relative(unsigned long time, int tz,
+void show_date_relative(timestamp_t time, int tz,
                               const struct timeval *now,
                               struct strbuf *timebuf)
 {
-       unsigned long diff;
+       timestamp_t diff;
        if (now->tv_sec < time) {
                strbuf_addstr(timebuf, _("in the future"));
                return;
@@ -100,65 +113,65 @@ void show_date_relative(unsigned long time, int tz,
        diff = now->tv_sec - time;
        if (diff < 90) {
                strbuf_addf(timebuf,
-                        Q_("%lu second ago", "%lu seconds ago", diff), diff);
+                        Q_("%"PRItime" second ago", "%"PRItime" seconds ago", diff), diff);
                return;
        }
        /* Turn it into minutes */
        diff = (diff + 30) / 60;
        if (diff < 90) {
                strbuf_addf(timebuf,
-                        Q_("%lu minute ago", "%lu minutes ago", diff), diff);
+                        Q_("%"PRItime" minute ago", "%"PRItime" minutes ago", diff), diff);
                return;
        }
        /* Turn it into hours */
        diff = (diff + 30) / 60;
        if (diff < 36) {
                strbuf_addf(timebuf,
-                        Q_("%lu hour ago", "%lu hours ago", diff), diff);
+                        Q_("%"PRItime" hour ago", "%"PRItime" hours ago", diff), diff);
                return;
        }
        /* We deal with number of days from here on */
        diff = (diff + 12) / 24;
        if (diff < 14) {
                strbuf_addf(timebuf,
-                        Q_("%lu day ago", "%lu days ago", diff), diff);
+                        Q_("%"PRItime" day ago", "%"PRItime" days ago", diff), diff);
                return;
        }
        /* Say weeks for the past 10 weeks or so */
        if (diff < 70) {
                strbuf_addf(timebuf,
-                        Q_("%lu week ago", "%lu weeks ago", (diff + 3) / 7),
+                        Q_("%"PRItime" week ago", "%"PRItime" weeks ago", (diff + 3) / 7),
                         (diff + 3) / 7);
                return;
        }
        /* Say months for the past 12 months or so */
        if (diff < 365) {
                strbuf_addf(timebuf,
-                        Q_("%lu month ago", "%lu months ago", (diff + 15) / 30),
+                        Q_("%"PRItime" month ago", "%"PRItime" months ago", (diff + 15) / 30),
                         (diff + 15) / 30);
                return;
        }
        /* Give years and months for 5 years or so */
        if (diff < 1825) {
-               unsigned long totalmonths = (diff * 12 * 2 + 365) / (365 * 2);
-               unsigned long years = totalmonths / 12;
-               unsigned long months = totalmonths % 12;
+               timestamp_t totalmonths = (diff * 12 * 2 + 365) / (365 * 2);
+               timestamp_t years = totalmonths / 12;
+               timestamp_t months = totalmonths % 12;
                if (months) {
                        struct strbuf sb = STRBUF_INIT;
-                       strbuf_addf(&sb, Q_("%lu year", "%lu years", years), years);
+                       strbuf_addf(&sb, Q_("%"PRItime" year", "%"PRItime" years", years), years);
                        strbuf_addf(timebuf,
                                 /* TRANSLATORS: "%s" is "<n> years" */
-                                Q_("%s, %lu month ago", "%s, %lu months ago", months),
+                                Q_("%s, %"PRItime" month ago", "%s, %"PRItime" months ago", months),
                                 sb.buf, months);
                        strbuf_release(&sb);
                } else
                        strbuf_addf(timebuf,
-                                Q_("%lu year ago", "%lu years ago", years), years);
+                                Q_("%"PRItime" year ago", "%"PRItime" years ago", years), years);
                return;
        }
        /* Otherwise, just years. Centuries is probably overkill. */
        strbuf_addf(timebuf,
-                Q_("%lu year ago", "%lu years ago", (diff + 183) / 365),
+                Q_("%"PRItime" year ago", "%"PRItime" years ago", (diff + 183) / 365),
                 (diff + 183) / 365);
 }
 
@@ -172,14 +185,14 @@ struct date_mode *date_mode_from_type(enum date_mode_type type)
        return &mode;
 }
 
-const char *show_date(unsigned long time, int tz, const struct date_mode *mode)
+const char *show_date(timestamp_t time, int tz, const struct date_mode *mode)
 {
        struct tm *tm;
        static struct strbuf timebuf = STRBUF_INIT;
 
        if (mode->type == DATE_UNIX) {
                strbuf_reset(&timebuf);
-               strbuf_addf(&timebuf, "%lu", time);
+               strbuf_addf(&timebuf, "%"PRItime, time);
                return timebuf.buf;
        }
 
@@ -188,7 +201,7 @@ const char *show_date(unsigned long time, int tz, const struct date_mode *mode)
 
        if (mode->type == DATE_RAW) {
                strbuf_reset(&timebuf);
-               strbuf_addf(&timebuf, "%lu %+05d", time, tz);
+               strbuf_addf(&timebuf, "%"PRItime" %+05d", time, tz);
                return timebuf.buf;
        }
 
@@ -425,7 +438,7 @@ static int is_date(int year, int month, int day, struct tm *now_tm, time_t now,
        return 0;
 }
 
-static int match_multi_number(unsigned long num, char c, const char *date,
+static int match_multi_number(timestamp_t num, char c, const char *date,
                              char *end, struct tm *tm, time_t now)
 {
        struct tm now_tm;
@@ -508,9 +521,9 @@ static int match_digit(const char *date, struct tm *tm, int *offset, int *tm_gmt
 {
        int n;
        char *end;
-       unsigned long num;
+       timestamp_t num;
 
-       num = strtoul(date, &end, 10);
+       num = parse_timestamp(date, &end, 10);
 
        /*
         * Seconds since 1970? We trigger on that for any numbers with
@@ -635,7 +648,7 @@ static int match_tz(const char *date, int *offp)
        return end - date;
 }
 
-static void date_string(unsigned long date, int offset, struct strbuf *buf)
+static void date_string(timestamp_t date, int offset, struct strbuf *buf)
 {
        int sign = '+';
 
@@ -643,23 +656,23 @@ static void date_string(unsigned long date, int offset, struct strbuf *buf)
                offset = -offset;
                sign = '-';
        }
-       strbuf_addf(buf, "%lu %c%02d%02d", date, sign, offset / 60, offset % 60);
+       strbuf_addf(buf, "%"PRItime" %c%02d%02d", date, sign, offset / 60, offset % 60);
 }
 
 /*
  * Parse a string like "0 +0000" as ancient timestamp near epoch, but
  * only when it appears not as part of any other string.
  */
-static int match_object_header_date(const char *date, unsigned long *timestamp, int *offset)
+static int match_object_header_date(const char *date, timestamp_t *timestamp, int *offset)
 {
        char *end;
-       unsigned long stamp;
+       timestamp_t stamp;
        int ofs;
 
        if (*date < '0' || '9' < *date)
                return -1;
-       stamp = strtoul(date, &end, 10);
-       if (*end != ' ' || stamp == ULONG_MAX || (end[1] != '+' && end[1] != '-'))
+       stamp = parse_timestamp(date, &end, 10);
+       if (*end != ' ' || stamp == TIME_MAX || (end[1] != '+' && end[1] != '-'))
                return -1;
        date = end + 2;
        ofs = strtol(date, &end, 10);
@@ -675,11 +688,11 @@ static int match_object_header_date(const char *date, unsigned long *timestamp,
 
 /* Gr. strptime is crap for this; it doesn't have a way to require RFC2822
    (i.e. English) day/month names, and it doesn't work correctly with %z. */
-int parse_date_basic(const char *date, unsigned long *timestamp, int *offset)
+int parse_date_basic(const char *date, timestamp_t *timestamp, int *offset)
 {
        struct tm tm;
        int tm_gmt;
-       unsigned long dummy_timestamp;
+       timestamp_t dummy_timestamp;
        int dummy_offset;
 
        if (!timestamp)
@@ -747,7 +760,7 @@ int parse_date_basic(const char *date, unsigned long *timestamp, int *offset)
        return 0; /* success */
 }
 
-int parse_expiry_date(const char *date, unsigned long *timestamp)
+int parse_expiry_date(const char *date, timestamp_t *timestamp)
 {
        int errors = 0;
 
@@ -762,7 +775,7 @@ int parse_expiry_date(const char *date, unsigned long *timestamp)
                 * of the past, and there is nothing from the future
                 * to be kept.
                 */
-               *timestamp = ULONG_MAX;
+               *timestamp = TIME_MAX;
        else
                *timestamp = approxidate_careful(date, &errors);
 
@@ -771,7 +784,7 @@ int parse_expiry_date(const char *date, unsigned long *timestamp)
 
 int parse_date(const char *date, struct strbuf *result)
 {
-       unsigned long timestamp;
+       timestamp_t timestamp;
        int offset;
        if (parse_date_basic(date, &timestamp, &offset))
                return -1;
@@ -845,7 +858,7 @@ void datestamp(struct strbuf *out)
  * Relative time update (eg "2 days ago").  If we haven't set the time
  * yet, we need to set it from current time.
  */
-static unsigned long update_tm(struct tm *tm, struct tm *now, unsigned long sec)
+static time_t update_tm(struct tm *tm, struct tm *now, time_t sec)
 {
        time_t n;
 
@@ -1066,7 +1079,7 @@ static const char *approxidate_digit(const char *date, struct tm *tm, int *num,
                                     time_t now)
 {
        char *end;
-       unsigned long number = strtoul(date, &end, 10);
+       timestamp_t number = parse_timestamp(date, &end, 10);
 
        switch (*end) {
        case ':':
@@ -1114,9 +1127,9 @@ static void pending_number(struct tm *tm, int *num)
        }
 }
 
-static unsigned long approxidate_str(const char *date,
-                                    const struct timeval *tv,
-                                    int *error_ret)
+static timestamp_t approxidate_str(const char *date,
+                                  const struct timeval *tv,
+                                  int *error_ret)
 {
        int number = 0;
        int touched = 0;
@@ -1148,12 +1161,12 @@ static unsigned long approxidate_str(const char *date,
        pending_number(&tm, &number);
        if (!touched)
                *error_ret = 1;
-       return update_tm(&tm, &now, 0);
+       return (timestamp_t)update_tm(&tm, &now, 0);
 }
 
-unsigned long approxidate_relative(const char *date, const struct timeval *tv)
+timestamp_t approxidate_relative(const char *date, const struct timeval *tv)
 {
-       unsigned long timestamp;
+       timestamp_t timestamp;
        int offset;
        int errors = 0;
 
@@ -1162,10 +1175,10 @@ unsigned long approxidate_relative(const char *date, const struct timeval *tv)
        return approxidate_str(date, tv, &errors);
 }
 
-unsigned long approxidate_careful(const char *date, int *error_ret)
+timestamp_t approxidate_careful(const char *date, int *error_ret)
 {
        struct timeval tv;
-       unsigned long timestamp;
+       timestamp_t timestamp;
        int offset;
        int dummy = 0;
        if (!error_ret)
@@ -1180,12 +1193,12 @@ unsigned long approxidate_careful(const char *date, int *error_ret)
        return approxidate_str(date, &tv, error_ret);
 }
 
-int date_overflows(unsigned long t)
+int date_overflows(timestamp_t t)
 {
        time_t sys;
 
-       /* If we overflowed our unsigned long, that's bad... */
-       if (t == ULONG_MAX)
+       /* If we overflowed our timestamp data type, that's bad... */
+       if ((uintmax_t)t >= TIME_MAX)
                return 1;
 
        /*
index afb8b05024823981be9bedfaa70f7301c6f7076c..5f15dd2c390a8105da0d84d0dfeda7cb69b111b7 100644 (file)
@@ -394,8 +394,8 @@ static int find_common(struct fetch_pack_args *args,
        if (args->depth > 0)
                packet_buf_write(&req_buf, "deepen %d", args->depth);
        if (args->deepen_since) {
-               unsigned long max_age = approxidate(args->deepen_since);
-               packet_buf_write(&req_buf, "deepen-since %lu", max_age);
+               timestamp_t max_age = approxidate(args->deepen_since);
+               packet_buf_write(&req_buf, "deepen-since %"PRItime, max_age);
        }
        if (args->deepen_not) {
                int i;
@@ -583,7 +583,7 @@ static int mark_complete_oid(const char *refname, const struct object_id *oid,
 }
 
 static void mark_recent_complete_commits(struct fetch_pack_args *args,
-                                        unsigned long cutoff)
+                                        timestamp_t cutoff)
 {
        while (complete && cutoff <= complete->item->date) {
                print_verbose(args, _("Marking %s as complete"),
@@ -670,7 +670,7 @@ static int everything_local(struct fetch_pack_args *args,
 {
        struct ref *ref;
        int retval;
-       unsigned long cutoff = 0;
+       timestamp_t cutoff = 0;
 
        save_commit_buffer = 0;
 
diff --git a/fsck.c b/fsck.c
index e6152e4e6d426bd92ae7ae063346f25f85ddd8de..d589341cddfa2b76bc8c5ee0f66a6b745883126b 100644 (file)
--- a/fsck.c
+++ b/fsck.c
@@ -691,7 +691,7 @@ static int fsck_ident(const char **ident, struct object *obj, struct fsck_option
        p++;
        if (*p == '0' && p[1] != ' ')
                return report(options, obj, FSCK_MSG_ZERO_PADDED_DATE, "invalid author/committer line - zero-padded date");
-       if (date_overflows(strtoul(p, &end, 10)))
+       if (date_overflows(parse_timestamp(p, &end, 10)))
                return report(options, obj, FSCK_MSG_BAD_DATE_OVERFLOW, "invalid author/committer line - date causes integer overflow");
        if ((end == p || *end != ' '))
                return report(options, obj, FSCK_MSG_BAD_DATE, "invalid author/committer line - bad date");
index bb4537c0ba0631f94fa1e57c6c5877949e50d750..ab7552a7ce2e292df2875258fef6f8bd0438e115 100644 (file)
@@ -319,6 +319,11 @@ extern char *gitdirname(char *);
 #define PRIo32 "o"
 #endif
 
+typedef uintmax_t timestamp_t;
+#define PRItime PRIuMAX
+#define parse_timestamp strtoumax
+#define TIME_MAX UINTMAX_MAX
+
 #ifndef PATH_SEP
 #define PATH_SEP ':'
 #endif
index eef0a361f4f9bcc7f8fb278268334cb40a32fcb3..d6ea60753395c519ef6af3b88f1287b5254f4a22 100644 (file)
@@ -90,7 +90,7 @@ static void hdr_int(struct strbuf *hdr, const char *name, uintmax_t value)
        strbuf_addf(hdr, "%s: %" PRIuMAX "\r\n", name, value);
 }
 
-static void hdr_date(struct strbuf *hdr, const char *name, unsigned long when)
+static void hdr_date(struct strbuf *hdr, const char *name, timestamp_t when)
 {
        const char *value = show_date(when, 0, DATE_MODE(RFC2822));
        hdr_str(hdr, name, value);
@@ -105,7 +105,7 @@ static void hdr_nocache(struct strbuf *hdr)
 
 static void hdr_cache_forever(struct strbuf *hdr)
 {
-       unsigned long now = time(NULL);
+       timestamp_t now = time(NULL);
        hdr_date(hdr, "Date", now);
        hdr_date(hdr, "Expires", now + 31536000);
        hdr_str(hdr, "Cache-Control", "public, max-age=31536000");
index 7419780a9b644e74107eec31d1c75156374920b8..a6810f295cbbcd3eb7482fcd6d94b26ecbbcedb9 100644 (file)
@@ -31,14 +31,14 @@ int parse_opt_abbrev_cb(const struct option *opt, const char *arg, int unset)
 int parse_opt_approxidate_cb(const struct option *opt, const char *arg,
                             int unset)
 {
-       *(unsigned long *)(opt->value) = approxidate(arg);
+       *(timestamp_t *)(opt->value) = approxidate(arg);
        return 0;
 }
 
 int parse_opt_expiry_date_cb(const struct option *opt, const char *arg,
                             int unset)
 {
-       return parse_expiry_date(arg, (unsigned long *)opt->value);
+       return parse_expiry_date(arg, (timestamp_t *)opt->value);
 }
 
 int parse_opt_color_flag_cb(const struct option *opt, const char *arg,
index d0f86f5d85cab6c470871cdd6e5ead526259bf6a..587d48371b05e0298e3358fa46bfaa4232ae24f9 100644 (file)
--- a/pretty.c
+++ b/pretty.c
@@ -405,11 +405,11 @@ static void add_rfc2047(struct strbuf *sb, const char *line, size_t len,
 const char *show_ident_date(const struct ident_split *ident,
                            const struct date_mode *mode)
 {
-       unsigned long date = 0;
+       timestamp_t date = 0;
        long tz = 0;
 
        if (ident->date_begin && ident->date_end)
-               date = strtoul(ident->date_begin, NULL, 10);
+               date = parse_timestamp(ident->date_begin, NULL, 10);
        if (date_overflows(date))
                date = 0;
        else {
index a8a979bd4fcbac6732d26dda3f826a1eec3d3a6b..682418f5d23bf8ce68b6aceeb96ebb778e71a467 100644 (file)
@@ -55,11 +55,11 @@ static void mark_commit(struct commit *c, void *data)
 
 struct recent_data {
        struct rev_info *revs;
-       unsigned long timestamp;
+       timestamp_t timestamp;
 };
 
 static void add_recent_object(const struct object_id *oid,
-                             unsigned long mtime,
+                             timestamp_t mtime,
                              struct recent_data *data)
 {
        struct object *obj;
@@ -139,7 +139,7 @@ static int add_recent_packed(const struct object_id *oid,
 }
 
 int add_unseen_recent_objects_to_traversal(struct rev_info *revs,
-                                          unsigned long timestamp)
+                                          timestamp_t timestamp)
 {
        struct recent_data data;
        int r;
@@ -156,8 +156,7 @@ int add_unseen_recent_objects_to_traversal(struct rev_info *revs,
 }
 
 void mark_reachable_objects(struct rev_info *revs, int mark_reflog,
-                           unsigned long mark_recent,
-                           struct progress *progress)
+                           timestamp_t mark_recent, struct progress *progress)
 {
        struct connectivity_progress cp;
 
index d23efc36ec5f198b9edab76f2aadff9461b83f45..3c00fa0526cd97e36111f2d94ccbf3d2817ccf34 100644 (file)
@@ -3,8 +3,8 @@
 
 struct progress;
 extern int add_unseen_recent_objects_to_traversal(struct rev_info *revs,
-                                                 unsigned long timestamp);
+                                                 timestamp_t timestamp);
 extern void mark_reachable_objects(struct rev_info *revs, int mark_reflog,
-                                  unsigned long mark_recent, struct progress *);
+                                  timestamp_t mark_recent, struct progress *);
 
 #endif
index 3a640448fd83e6cf0bda8ddda081757d5941361e..1fc5e9970db1b821384e61942db856504ce46902 100644 (file)
@@ -351,7 +351,7 @@ struct ref_formatting_state {
 struct atom_value {
        const char *s;
        void (*handler)(struct atom_value *atomv, struct ref_formatting_state *state);
-       unsigned long ul; /* used for sorting when not FIELD_STR */
+       uintmax_t value; /* used for sorting when not FIELD_STR */
        struct used_atom *atom;
 };
 
@@ -723,7 +723,7 @@ static void grab_common_values(struct atom_value *val, int deref, struct object
                if (!strcmp(name, "objecttype"))
                        v->s = typename(obj->type);
                else if (!strcmp(name, "objectsize")) {
-                       v->ul = sz;
+                       v->value = sz;
                        v->s = xstrfmt("%lu", sz);
                }
                else if (deref)
@@ -770,8 +770,8 @@ static void grab_commit_values(struct atom_value *val, int deref, struct object
                        v->s = xstrdup(oid_to_hex(&commit->tree->object.oid));
                }
                else if (!strcmp(name, "numparent")) {
-                       v->ul = commit_list_count(commit->parents);
-                       v->s = xstrfmt("%lu", v->ul);
+                       v->value = commit_list_count(commit->parents);
+                       v->s = xstrfmt("%lu", (unsigned long)v->value);
                }
                else if (!strcmp(name, "parent")) {
                        struct commit_list *parents;
@@ -849,7 +849,7 @@ static void grab_date(const char *buf, struct atom_value *v, const char *atomnam
 {
        const char *eoemail = strstr(buf, "> ");
        char *zone;
-       unsigned long timestamp;
+       timestamp_t timestamp;
        long tz;
        struct date_mode date_mode = { DATE_NORMAL };
        const char *formatp;
@@ -868,18 +868,18 @@ static void grab_date(const char *buf, struct atom_value *v, const char *atomnam
 
        if (!eoemail)
                goto bad;
-       timestamp = strtoul(eoemail + 2, &zone, 10);
-       if (timestamp == ULONG_MAX)
+       timestamp = parse_timestamp(eoemail + 2, &zone, 10);
+       if (timestamp == TIME_MAX)
                goto bad;
        tz = strtol(zone, NULL, 10);
        if ((tz == LONG_MIN || tz == LONG_MAX) && errno == ERANGE)
                goto bad;
        v->s = xstrdup(show_date(timestamp, tz, &date_mode));
-       v->ul = timestamp;
+       v->value = timestamp;
        return;
  bad:
        v->s = "";
-       v->ul = 0;
+       v->value = 0;
 }
 
 /* See grab_values */
@@ -1941,9 +1941,9 @@ static int cmp_ref_sorting(struct ref_sorting *s, struct ref_array_item *a, stru
        else if (cmp_type == FIELD_STR)
                cmp = cmp_fn(va->s, vb->s);
        else {
-               if (va->ul < vb->ul)
+               if (va->value < vb->value)
                        cmp = -1;
-               else if (va->ul == vb->ul)
+               else if (va->value == vb->value)
                        cmp = cmp_fn(a->refname, b->refname);
                else
                        cmp = 1;
index 99679f58255e386526335da8342e17356b48a4f9..3ca5ed8415a076a1a18fc8a1912c03866a50f522 100644 (file)
@@ -12,7 +12,7 @@ struct complete_reflogs {
        struct reflog_info {
                struct object_id ooid, noid;
                char *email;
-               unsigned long timestamp;
+               timestamp_t timestamp;
                int tz;
                char *message;
        } *items;
@@ -20,7 +20,7 @@ struct complete_reflogs {
 };
 
 static int read_one_reflog(struct object_id *ooid, struct object_id *noid,
-               const char *email, unsigned long timestamp, int tz,
+               const char *email, timestamp_t timestamp, int tz,
                const char *message, void *cb_data)
 {
        struct complete_reflogs *array = cb_data;
@@ -69,7 +69,7 @@ static struct complete_reflogs *read_complete_reflog(const char *ref)
 }
 
 static int get_reflog_recno_by_time(struct complete_reflogs *array,
-       unsigned long timestamp)
+       timestamp_t timestamp)
 {
        int i;
        for (i = array->nr - 1; i >= 0; i--)
@@ -141,7 +141,7 @@ void init_reflog_walk(struct reflog_walk_info **info)
 int add_reflog_for_walk(struct reflog_walk_info *info,
                struct commit *commit, const char *name)
 {
-       unsigned long timestamp = 0;
+       timestamp_t timestamp = 0;
        int recno = -1;
        struct string_list_item *item;
        struct complete_reflogs *reflogs;
diff --git a/refs.c b/refs.c
index fda450118112694ed1fedd1258cea3e283866569..26d40f99277f91167a243c19a2380b26075e30d6 100644 (file)
--- a/refs.c
+++ b/refs.c
@@ -714,7 +714,7 @@ int is_branch(const char *refname)
 
 struct read_ref_at_cb {
        const char *refname;
-       unsigned long at_time;
+       timestamp_t at_time;
        int cnt;
        int reccnt;
        unsigned char *sha1;
@@ -723,15 +723,15 @@ struct read_ref_at_cb {
        unsigned char osha1[20];
        unsigned char nsha1[20];
        int tz;
-       unsigned long date;
+       timestamp_t date;
        char **msg;
-       unsigned long *cutoff_time;
+       timestamp_t *cutoff_time;
        int *cutoff_tz;
        int *cutoff_cnt;
 };
 
 static int read_ref_at_ent(struct object_id *ooid, struct object_id *noid,
-               const char *email, unsigned long timestamp, int tz,
+               const char *email, timestamp_t timestamp, int tz,
                const char *message, void *cb_data)
 {
        struct read_ref_at_cb *cb = cb_data;
@@ -778,7 +778,7 @@ static int read_ref_at_ent(struct object_id *ooid, struct object_id *noid,
 }
 
 static int read_ref_at_ent_oldest(struct object_id *ooid, struct object_id *noid,
-                                 const char *email, unsigned long timestamp,
+                                 const char *email, timestamp_t timestamp,
                                  int tz, const char *message, void *cb_data)
 {
        struct read_ref_at_cb *cb = cb_data;
@@ -798,9 +798,9 @@ static int read_ref_at_ent_oldest(struct object_id *ooid, struct object_id *noid
        return 1;
 }
 
-int read_ref_at(const char *refname, unsigned int flags, unsigned long at_time, int cnt,
+int read_ref_at(const char *refname, unsigned int flags, timestamp_t at_time, int cnt,
                unsigned char *sha1, char **msg,
-               unsigned long *cutoff_time, int *cutoff_tz, int *cutoff_cnt)
+               timestamp_t *cutoff_time, int *cutoff_tz, int *cutoff_cnt)
 {
        struct read_ref_at_cb cb;
 
diff --git a/refs.h b/refs.h
index aca805168abd98149bc1725721fe2d53b6ed5802..d18ef47128688b6bee35b4bd5ae5c42bc3e6690e 100644 (file)
--- a/refs.h
+++ b/refs.h
@@ -318,9 +318,9 @@ int safe_create_reflog(const char *refname, int force_create, struct strbuf *err
 
 /** Reads log for the value of ref during at_time. **/
 int read_ref_at(const char *refname, unsigned int flags,
-               unsigned long at_time, int cnt,
+               timestamp_t at_time, int cnt,
                unsigned char *sha1, char **msg,
-               unsigned long *cutoff_time, int *cutoff_tz, int *cutoff_cnt);
+               timestamp_t *cutoff_time, int *cutoff_tz, int *cutoff_cnt);
 
 /** Check if a particular reflog exists */
 int refs_reflog_exists(struct ref_store *refs, const char *refname);
@@ -357,7 +357,7 @@ int delete_reflog(const char *refname);
 /* iterate over reflog entries */
 typedef int each_reflog_ent_fn(
                struct object_id *old_oid, struct object_id *new_oid,
-               const char *committer, unsigned long timestamp,
+               const char *committer, timestamp_t timestamp,
                int tz, const char *msg, void *cb_data);
 
 int refs_for_each_reflog_ent(struct ref_store *refs, const char *refname,
@@ -607,7 +607,7 @@ typedef void reflog_expiry_prepare_fn(const char *refname,
 typedef int reflog_expiry_should_prune_fn(unsigned char *osha1,
                                          unsigned char *nsha1,
                                          const char *email,
-                                         unsigned long timestamp, int tz,
+                                         timestamp_t timestamp, int tz,
                                          const char *message, void *cb_data);
 typedef void reflog_expiry_cleanup_fn(void *cb_data);
 
index 9d08e84ded1e93c3f43b74f4dd92934d190fabf1..4925e698d84b46e425c158e28709c22c339803c4 100644 (file)
@@ -2273,7 +2273,7 @@ static int show_one_reflog_ent(struct strbuf *sb, each_reflog_ent_fn fn, void *c
 {
        struct object_id ooid, noid;
        char *email_end, *message;
-       unsigned long timestamp;
+       timestamp_t timestamp;
        int tz;
        const char *p = sb->buf;
 
@@ -2283,7 +2283,7 @@ static int show_one_reflog_ent(struct strbuf *sb, each_reflog_ent_fn fn, void *c
            parse_oid_hex(p, &noid, &p) || *p++ != ' ' ||
            !(email_end = strchr(p, '>')) ||
            email_end[1] != ' ' ||
-           !(timestamp = strtoul(email_end + 2, &message, 10)) ||
+           !(timestamp = parse_timestamp(email_end + 2, &message, 10)) ||
            !message || message[0] != ' ' ||
            (message[1] != '+' && message[1] != '-') ||
            !isdigit(message[2]) || !isdigit(message[3]) ||
@@ -3154,7 +3154,7 @@ struct expire_reflog_cb {
 };
 
 static int expire_reflog_ent(struct object_id *ooid, struct object_id *noid,
-                            const char *email, unsigned long timestamp, int tz,
+                            const char *email, timestamp_t timestamp, int tz,
                             const char *message, void *cb_data)
 {
        struct expire_reflog_cb *cb = cb_data;
@@ -3171,7 +3171,7 @@ static int expire_reflog_ent(struct object_id *ooid, struct object_id *noid,
                        printf("prune %s", message);
        } else {
                if (cb->newlog) {
-                       fprintf(cb->newlog, "%s %s %s %lu %+05d\t%s",
+                       fprintf(cb->newlog, "%s %s %s %"PRItime" %+05d\t%s",
                                oid_to_hex(ooid), oid_to_hex(noid),
                                email, timestamp, tz, message);
                        oidcpy(&cb->last_kept_oid, noid);
index 7ff61ff5f73db07af522ac57d62ed9e699aedf72..8a8c1789c7bc275db852b6e89a1d3acef3417371 100644 (file)
@@ -884,7 +884,7 @@ static void cherry_pick_list(struct commit_list *list, struct rev_info *revs)
 /* How many extra uninteresting commits we want to see.. */
 #define SLOP 5
 
-static int still_interesting(struct commit_list *src, unsigned long date, int slop,
+static int still_interesting(struct commit_list *src, timestamp_t date, int slop,
                             struct commit **interesting_cache)
 {
        /*
@@ -1018,7 +1018,7 @@ static void limit_left_right(struct commit_list *list, struct rev_info *revs)
 static int limit_list(struct rev_info *revs)
 {
        int slop = SLOP;
-       unsigned long date = ~0ul;
+       timestamp_t date = TIME_MAX;
        struct commit_list *list = revs->commits;
        struct commit_list *newlist = NULL;
        struct commit_list **p = &newlist;
@@ -1215,7 +1215,7 @@ static void handle_one_reflog_commit(struct object_id *oid, void *cb_data)
 }
 
 static int handle_one_reflog_ent(struct object_id *ooid, struct object_id *noid,
-               const char *email, unsigned long timestamp, int tz,
+               const char *email, timestamp_t timestamp, int tz,
                const char *message, void *cb_data)
 {
        handle_one_reflog_commit(ooid, cb_data);
index 14886ec92b4f67527a86fc821998214a4d2b321f..0d9e68b36e9e753e0ed09f3e4bfdd946d8610bda 100644 (file)
@@ -181,8 +181,8 @@ struct rev_info {
        /* special limits */
        int skip_count;
        int max_count;
-       unsigned long max_age;
-       unsigned long min_age;
+       timestamp_t max_age;
+       timestamp_t min_age;
        int min_parents;
        int max_parents;
        int (*include_check)(struct commit *, void *);
index 8eec9f7c1bb59b8124e098367b7bff552bcafcf4..35c1e2a9e324bed6e004e627cf11c2b316ef04c2 100644 (file)
@@ -660,8 +660,8 @@ static int get_sha1_basic(const char *str, int len, unsigned char *sha1,
 
        if (reflog_len) {
                int nth, i;
-               unsigned long at_time;
-               unsigned long co_time;
+               timestamp_t at_time;
+               timestamp_t co_time;
                int co_tz, co_cnt;
 
                /* Is it asking for N-th entry, or approxidate? */
@@ -1054,7 +1054,7 @@ struct grab_nth_branch_switch_cbdata {
 };
 
 static int grab_nth_branch_switch(struct object_id *ooid, struct object_id *noid,
-                                 const char *email, unsigned long timestamp, int tz,
+                                 const char *email, timestamp_t timestamp, int tz,
                                  const char *message, void *cb_data)
 {
        struct grab_nth_branch_switch_cbdata *cb = cb_data;
index 506054bcd5dfbd76c8aec85382f35794514b9db9..f414a3ac670fb2d77645f5d7301b6aa8f603379e 100644 (file)
@@ -4,7 +4,9 @@ static const char *usage_msg = "\n"
 "  test-date relative [time_t]...\n"
 "  test-date show:<format> [time_t]...\n"
 "  test-date parse [date]...\n"
-"  test-date approxidate [date]...\n";
+"  test-date approxidate [date]...\n"
+"  test-date is64bit\n"
+"  test-date time_t-is64bit\n";
 
 static void show_relative_dates(const char **argv, struct timeval *now)
 {
@@ -25,14 +27,14 @@ static void show_dates(const char **argv, const char *format)
        parse_date_format(format, &mode);
        for (; *argv; argv++) {
                char *arg;
-               time_t t;
+               timestamp_t t;
                int tz;
 
                /*
                 * Do not use our normal timestamp parsing here, as the point
                 * is to test the formatting code in isolation.
                 */
-               t = strtol(*argv, &arg, 10);
+               t = parse_timestamp(*argv, &arg, 10);
                while (*arg == ' ')
                        arg++;
                tz = atoi(arg);
@@ -46,12 +48,12 @@ static void parse_dates(const char **argv, struct timeval *now)
        struct strbuf result = STRBUF_INIT;
 
        for (; *argv; argv++) {
-               unsigned long t;
+               timestamp_t t;
                int tz;
 
                strbuf_reset(&result);
                parse_date(*argv, &result);
-               if (sscanf(result.buf, "%lu %d", &t, &tz) == 2)
+               if (sscanf(result.buf, "%"PRItime" %d", &t, &tz) == 2)
                        printf("%s -> %s\n",
                               *argv, show_date(t, tz, DATE_MODE(ISO8601)));
                else
@@ -63,7 +65,7 @@ static void parse_dates(const char **argv, struct timeval *now)
 static void parse_approxidate(const char **argv, struct timeval *now)
 {
        for (; *argv; argv++) {
-               time_t t;
+               timestamp_t t;
                t = approxidate_relative(*argv, now);
                printf("%s -> %s\n", *argv, show_date(t, 0, DATE_MODE(ISO8601)));
        }
@@ -93,6 +95,10 @@ int cmd_main(int argc, const char **argv)
                parse_dates(argv+1, &now);
        else if (!strcmp(*argv, "approxidate"))
                parse_approxidate(argv+1, &now);
+       else if (!strcmp(*argv, "is64bit"))
+               return sizeof(timestamp_t) == 8 ? 0 : 1;
+       else if (!strcmp(*argv, "time_t-is64bit"))
+               return sizeof(time_t) == 8 ? 0 : 1;
        else
                usage(usage_msg);
        return 0;
index a01430c24bdb8c0e35147b71d6f9e898405b1c85..75fe883aac1ee17b9dda40dd88b7a4a4fd328318 100644 (file)
@@ -5,7 +5,7 @@
 static int boolean = 0;
 static int integer = 0;
 static unsigned long magnitude = 0;
-static unsigned long timestamp;
+static timestamp_t timestamp;
 static int abbrev = 7;
 static int verbose = -1; /* unspecified */
 static int dry_run = 0, quiet = 0;
@@ -161,7 +161,7 @@ int cmd_main(int argc, const char **argv)
        show(&expect, &ret, "boolean: %d", boolean);
        show(&expect, &ret, "integer: %d", integer);
        show(&expect, &ret, "magnitude: %lu", magnitude);
-       show(&expect, &ret, "timestamp: %lu", timestamp);
+       show(&expect, &ret, "timestamp: %"PRItime, timestamp);
        show(&expect, &ret, "string: %s", string ? string : "(not set)");
        show(&expect, &ret, "abbrev: %d", abbrev);
        show(&expect, &ret, "verbose: %d", verbose);
index 4a487c014e08794a818704735101e85a6781c14a..fba85e7da58fb124b409de502e9bb4f9a7d8f5b5 100644 (file)
@@ -156,10 +156,10 @@ static int cmd_for_each_reflog(struct ref_store *refs, const char **argv)
 }
 
 static int each_reflog(struct object_id *old_oid, struct object_id *new_oid,
-                      const char *committer, unsigned long timestamp,
+                      const char *committer, timestamp_t timestamp,
                       int tz, const char *msg, void *cb_data)
 {
-       printf("%s %s %s %lu %d %s\n",
+       printf("%s %s %s %"PRItime" %d %s\n",
               oid_to_hex(old_oid), oid_to_hex(new_oid),
               committer, timestamp, tz, msg);
        return 0;
index c0c910867d75368832ce8b297e9dd82ee984a85a..42d4ea61ef531d8c495c5c2216d434982f1c6182 100755 (executable)
@@ -53,8 +53,8 @@ check_show unix-local "$TIME" '1466000000'
 
 # arbitrary time absurdly far in the future
 FUTURE="5758122296 -0400"
-check_show iso       "$FUTURE" "2152-06-19 18:24:56 -0400" LONG_IS_64BIT
-check_show iso-local "$FUTURE" "2152-06-19 22:24:56 +0000" LONG_IS_64BIT
+check_show iso       "$FUTURE" "2152-06-19 18:24:56 -0400" TIME_IS_64BIT,TIME_T_IS_64BIT
+check_show iso-local "$FUTURE" "2152-06-19 22:24:56 +0000" TIME_IS_64BIT,TIME_T_IS_64BIT
 
 check_parse() {
        echo "$1 -> $2" >expect
index 886b6953e40f9fceae18642ebec031e0bdf511e3..fe2d4f15a73f082c516a03b1877c4cf82982138a 100755 (executable)
@@ -390,7 +390,7 @@ test_expect_success TAR_HUGE,LONG_IS_64BIT 'system tar can read our huge size' '
        test_cmp expect actual
 '
 
-test_expect_success LONG_IS_64BIT 'set up repository with far-future commit' '
+test_expect_success TIME_IS_64BIT 'set up repository with far-future commit' '
        rm -f .git/index &&
        echo content >file &&
        git add file &&
@@ -398,11 +398,11 @@ test_expect_success LONG_IS_64BIT 'set up repository with far-future commit' '
                git commit -m "tempori parendum"
 '
 
-test_expect_success LONG_IS_64BIT 'generate tar with future mtime' '
+test_expect_success TIME_IS_64BIT 'generate tar with future mtime' '
        git archive HEAD >future.tar
 '
 
-test_expect_success TAR_HUGE,LONG_IS_64BIT 'system tar can read our future mtime' '
+test_expect_success TAR_HUGE,TIME_IS_64BIT,TIME_T_IS_64BIT 'system tar can read our future mtime' '
        echo 4147 >expect &&
        tar_info future.tar | cut -d" " -f2 >actual &&
        test_cmp expect actual
index 014136fb06dc689a4a2a2744cedcd0f2fda37d6d..26b3edfb2e4e725f589fc99986587aa3ecb48b75 100644 (file)
@@ -1168,3 +1168,6 @@ build_option () {
 test_lazy_prereq LONG_IS_64BIT '
        test 8 -le "$(build_option sizeof-long)"
 '
+
+test_lazy_prereq TIME_IS_64BIT 'test-date is64bit'
+test_lazy_prereq TIME_T_IS_64BIT 'test-date time_t-is64bit'
diff --git a/tag.c b/tag.c
index 243d1fdbbcb1424b0082e1c999920f6a50b32d68..d71b67e8d83cba2273f468b1922cc788e2e0989e 100644 (file)
--- a/tag.c
+++ b/tag.c
@@ -97,7 +97,7 @@ struct tag *lookup_tag(const unsigned char *sha1)
        return object_as_type(obj, OBJ_TAG, 0);
 }
 
-static unsigned long parse_tag_date(const char *buf, const char *tail)
+static timestamp_t parse_tag_date(const char *buf, const char *tail)
 {
        const char *dateptr;
 
@@ -110,8 +110,8 @@ static unsigned long parse_tag_date(const char *buf, const char *tail)
                /* nada */;
        if (buf >= tail)
                return 0;
-       /* dateptr < buf && buf[-1] == '\n', so strtoul will stop at buf-1 */
-       return strtoul(dateptr, NULL, 10);
+       /* dateptr < buf && buf[-1] == '\n', so parsing will stop at buf-1 */
+       return parse_timestamp(dateptr, NULL, 10);
 }
 
 int parse_tag_buffer(struct tag *item, const void *data, unsigned long size)
diff --git a/tag.h b/tag.h
index a5721b6731eb89e1db78e41fcf6b8dfd8784841e..2abb3726fb5c289a5ef2c90716ec1a01f28169d6 100644 (file)
--- a/tag.h
+++ b/tag.h
@@ -9,7 +9,7 @@ struct tag {
        struct object object;
        struct object *tagged;
        char *tag;
-       unsigned long date;
+       timestamp_t date;
 };
 
 extern struct tag *lookup_tag(const unsigned char *sha1);
index ffb028d6231e24877b5b6af616d0c3de59516d95..97da13e6a54df30ecbdbad9c3941354a8ebbf9d3 100644 (file)
@@ -35,7 +35,7 @@ static const char * const upload_pack_usage[] = {
 #define CLIENT_SHALLOW (1u << 18)
 #define HIDDEN_REF     (1u << 19)
 
-static unsigned long oldest_have;
+static timestamp_t oldest_have;
 
 static int deepen_relative;
 static int multi_ack;
@@ -735,7 +735,7 @@ static void receive_needs(void)
        struct string_list deepen_not = STRING_LIST_INIT_DUP;
        int depth = 0;
        int has_non_tip = 0;
-       unsigned long deepen_since = 0;
+       timestamp_t deepen_since = 0;
        int deepen_rev_list = 0;
 
        shallow_nr = 0;
@@ -775,7 +775,7 @@ static void receive_needs(void)
                }
                if (skip_prefix(line, "deepen-since ", &arg)) {
                        char *end = NULL;
-                       deepen_since = strtoul(arg, &end, 0);
+                       deepen_since = parse_timestamp(arg, &end, 0);
                        if (!end || *end || !deepen_since ||
                            /* revisions.c's max_age -1 is special */
                            deepen_since == -1)
@@ -863,7 +863,7 @@ static void receive_needs(void)
 
                argv_array_push(&av, "rev-list");
                if (deepen_since)
-                       argv_array_pushf(&av, "--max-age=%lu", deepen_since);
+                       argv_array_pushf(&av, "--max-age=%"PRItime, deepen_since);
                if (deepen_not.nr) {
                        argv_array_push(&av, "--not");
                        for (i = 0; i < deepen_not.nr; i++) {
index 97cba39cdf5b6de75e3df0cd0240cae6adcf3859..5a89db30e3ffcb64ee25597fe014592929e07abb 100644 (file)
@@ -68,12 +68,12 @@ void fast_export_modify(const char *path, uint32_t mode, const char *dataref)
 }
 
 void fast_export_begin_note(uint32_t revision, const char *author,
-               const char *log, unsigned long timestamp, const char *note_ref)
+               const char *log, timestamp_t timestamp, const char *note_ref)
 {
        static int firstnote = 1;
        size_t loglen = strlen(log);
        printf("commit %s\n", note_ref);
-       printf("committer %s <%s@%s> %lu +0000\n", author, author, "local", timestamp);
+       printf("committer %s <%s@%s> %"PRItime" +0000\n", author, author, "local", timestamp);
        printf("data %"PRIuMAX"\n", (uintmax_t)loglen);
        fwrite(log, loglen, 1, stdout);
        if (firstnote) {
@@ -93,7 +93,7 @@ static char gitsvnline[MAX_GITSVN_LINE_LEN];
 void fast_export_begin_commit(uint32_t revision, const char *author,
                        const struct strbuf *log,
                        const char *uuid, const char *url,
-                       unsigned long timestamp, const char *local_ref)
+                       timestamp_t timestamp, const char *local_ref)
 {
        static const struct strbuf empty = STRBUF_INIT;
        if (!log)
@@ -107,7 +107,7 @@ void fast_export_begin_commit(uint32_t revision, const char *author,
        }
        printf("commit %s\n", local_ref);
        printf("mark :%"PRIu32"\n", revision);
-       printf("committer %s <%s@%s> %lu +0000\n",
+       printf("committer %s <%s@%s> %"PRItime" +0000\n",
                   *author ? author : "nobody",
                   *author ? author : "nobody",
                   *uuid ? uuid : "local", timestamp);
index c8b5adb811c7ba5652b94a6cf6f9ea54d6d9335f..b9a3b71c99fd59312f493d6b1eb24c9a0b44578c 100644 (file)
@@ -11,10 +11,10 @@ void fast_export_delete(const char *path);
 void fast_export_modify(const char *path, uint32_t mode, const char *dataref);
 void fast_export_note(const char *committish, const char *dataref);
 void fast_export_begin_note(uint32_t revision, const char *author,
-               const char *log, unsigned long timestamp, const char *note_ref);
+               const char *log, timestamp_t timestamp, const char *note_ref);
 void fast_export_begin_commit(uint32_t revision, const char *author,
                        const struct strbuf *log, const char *uuid,const char *url,
-                       unsigned long timestamp, const char *local_ref);
+                       timestamp_t timestamp, const char *local_ref);
 void fast_export_end_commit(uint32_t revision);
 void fast_export_data(uint32_t mode, off_t len, struct line_buffer *input);
 void fast_export_buf_to_data(const struct strbuf *data);
index e4b395963b9457a680a369c3e1997c799f8793ab..1846685a21a44decfe5790f0020dcf933c8d6583 100644 (file)
@@ -47,7 +47,7 @@ static struct {
 
 static struct {
        uint32_t revision;
-       unsigned long timestamp;
+       timestamp_t timestamp;
        struct strbuf log, author, note;
 } rev_ctx;
 
index b7ade902fb4ef0cf30b1933a32433ab355b21395..7daa5320ac7538835285495782e74be5423ed76b 100644 (file)
@@ -1387,7 +1387,7 @@ struct grab_1st_switch_cbdata {
 };
 
 static int grab_1st_switch(struct object_id *ooid, struct object_id *noid,
-                          const char *email, unsigned long timestamp, int tz,
+                          const char *email, timestamp_t timestamp, int tz,
                           const char *message, void *cb_data)
 {
        struct grab_1st_switch_cbdata *cb = cb_data;