1. 06 May, 2018 1 commit
    • Johannes Schindelin's avatar
      Replace all die("BUG: ...") calls by BUG() ones · 033abf97
      Johannes Schindelin authored
      In d8193743 (usage.c: add BUG() function, 2017-05-12), a new macro
      was introduced to use for reporting bugs instead of die(). It was then
      subsequently used to convert one single caller in 588a538a
      (setup_git_env: convert die("BUG") to BUG(), 2017-05-12).
      The cover letter of the patch series containing this patch
      (cf 20170513032414.mfrwabt4hovujde2@sigill.intra.peff.net) is not
      terribly clear why only one call site was converted, or what the plan
      is for other, similar calls to die() to report bugs.
      Let's just convert all remaining ones in one fell swoop.
      This trick was performed by this invocation:
      	sed -i 's/die("BUG: /BUG("/g' $(git grep -l 'die("BUG' \*.c)
      Signed-off-by: Johannes Schindelin's avatarJohannes Schindelin <johannes.schindelin@gmx.de>
      Signed-off-by: default avatarJunio C Hamano <gitster@pobox.com>
  2. 01 Jul, 2017 1 commit
  3. 15 Jun, 2017 2 commits
    • Jeff King's avatar
      date: use localtime() for "-local" time formats · 6eced3ec
      Jeff King authored
      When we convert seconds-since-epochs timestamps into a
      broken-down "struct tm", we do so by adjusting the timestamp
      according to the known offset and then using gmtime() to
      break down the result. This means that the resulting struct
      "knows" that it's in GMT, even though the time it represents
      is adjusted for a different zone. The fields where it stores
      this data are not portably accessible, so we have no way to
      override them to tell them the real zone info.
      For the most part, this works. Our date-formatting routines
      don't pay attention to these inaccessible fields, and use
      the same tz info we provided for adjustment. The one
      exception is when we call strftime(), whose %Z format
      reveals this hidden timezone data.
      We solved that by always showing the empty string for %Z.
      This is allowed by POSIX, but not very helpful to the user.
      We can't make this work in the general case, as there's no
      portable function for setting an arbitrary timezone (and
      anyway, we don't have the zone name for the author zones,
      only their offsets).
      But for the special case of the "-local" formats, we can
      just skip the adjustment and use localtime() instead of
      gmtime(). This makes --date=format-local:%Z work correctly,
      showing the local timezone instead of an empty string.
      The new test checks the result for "UTC", our default
      test-lib value for $TZ. Using something like EST5 might be
      more interesting, but the actual zone string is
      system-dependent (for instance, on my system it expands to
      just EST). Hopefully "UTC" is vanilla enough that every
      system treats it the same.
      Signed-off-by: default avatarJeff King <peff@peff.net>
      Signed-off-by: default avatarJunio C Hamano <gitster@pobox.com>
    • René Scharfe's avatar
      strbuf: let strbuf_addftime handle %z and %Z itself · c3fbf81a
      René Scharfe authored
      There is no portable way to pass timezone information to strftime.  Add
      parameters for timezone offset and name to strbuf_addftime and let it
      handle the timezone-related format specifiers %z and %Z internally.
      Callers can opt out for %Z by passing NULL as timezone name.  %z is
      always handled internally -- this helps on Windows, where strftime would
      expand it to a timezone name (same as %Z), in violation of POSIX.
      Modifiers are not handled, e.g. %Ez is still passed to strftime.
      Use an empty string as timezone name in show_date (the only current
      caller) for now because we only have the timezone offset in non-local
      mode.  POSIX allows %Z to resolve to an empty string in case of missing
      Helped-by: Ulrich Müller's avatarUlrich Mueller <ulm@gentoo.org>
      Helped-by: default avatarJeff King <peff@peff.net>
      Signed-off-by: default avatarRene Scharfe <l.s.r@web.de>
      Signed-off-by: default avatarJunio C Hamano <gitster@pobox.com>
  4. 27 Apr, 2017 2 commits
  5. 24 Apr, 2017 2 commits
  6. 27 Jul, 2016 1 commit
    • Jeff King's avatar
      date: add "unix" format · 642833db
      Jeff King authored
      We already have "--date=raw", which is a Unix epoch
      timestamp plus a contextual timezone (either the author's or
      the local). But one may not care about the timezone and just
      want the epoch timestamp by itself. It's not hard to parse
      the two apart, but if you are using a pretty-print format,
      you may want git to show the "finished" form that the user
      will see.
      We can accomodate this by adding a new date format, "unix",
      which is basically "raw" without the timezone.
      Signed-off-by: default avatarJeff King <peff@peff.net>
      Signed-off-by: default avatarJunio C Hamano <gitster@pobox.com>
  7. 20 Jun, 2016 1 commit
    • Jeff King's avatar
      local_tzoffset: detect errors from tm_to_time_t · bab74837
      Jeff King authored
      When we want to know the local timezone offset at a given
      timestamp, we compute it by asking for localtime() at the
      given time, and comparing the offset to GMT at that time.
      However, there's some juggling between time_t and "struct
      tm" which happens, which involves calling our own
      If that function returns an error (e.g., because it only
      handles dates up to the year 2099), it returns "-1", which
      we treat as a time_t, and is clearly bogus, leading to
      bizarre timestamps (that seem to always adjust the time back
      to (time_t)(uint32_t)-1, in the year 2106).
      It's not a good idea for local_tzoffset() to simply die
      here; it would make it hard to run "git log" on a repository
      with funny timestamps. Instead, let's just treat such cases
      as "zero offset".
      Reported-by: Norbert Kiesel's avatarNorbert Kiesel <nkiesel@gmail.com>
      Signed-off-by: default avatarJeff King <peff@peff.net>
      Signed-off-by: default avatarJunio C Hamano <gitster@pobox.com>
  8. 03 Sep, 2015 2 commits
    • Jeff King's avatar
      date: make "local" orthogonal to date format · add00ba2
      Jeff King authored
      Most of our "--date" modes are about the format of the date:
      which items we show and in what order. But "--date=local" is
      a bit of an oddball. It means "show the date in the normal
      format, but using the local timezone". The timezone we use
      is orthogonal to the actual format, and there is no reason
      we could not have "localized iso8601", etc.
      This patch adds a "local" boolean field to "struct
      date_mode", and drops the DATE_LOCAL element from the
      date_mode_type enum (it's now just DATE_NORMAL plus
      local=1). The new feature is accessible to users by adding
      "-local" to any date mode (e.g., "iso-local"), and we retain
      "local" as an alias for "default-local" for backwards
      Signed-off-by: default avatarJeff King <peff@peff.net>
      Signed-off-by: John Keeping's avatarJohn Keeping <john@keeping.me.uk>
      Signed-off-by: default avatarJunio C Hamano <gitster@pobox.com>
    • John Keeping's avatar
      date: check for "local" before anything else · dc6d782c
      John Keeping authored
      In a following commit we will make "local" orthogonal to the format.
      Although this will not apply to "relative", which does not use the
      timezone, it applies to all other formats so move the timezone
      conversion to the start of the function.
      Signed-off-by: John Keeping's avatarJohn Keeping <john@keeping.me.uk>
      Signed-off-by: default avatarJunio C Hamano <gitster@pobox.com>
  9. 29 Jun, 2015 2 commits
    • Jeff King's avatar
      introduce "format" date-mode · aa1462cc
      Jeff King authored
      This feeds the format directly to strftime. Besides being a
      little more flexible, the main advantage is that your system
      strftime may know more about your locale's preferred format
      (e.g., how to spell the days of the week).
      Signed-off-by: default avatarJeff King <peff@peff.net>
      Signed-off-by: default avatarJunio C Hamano <gitster@pobox.com>
    • Jeff King's avatar
      convert "enum date_mode" into a struct · a5481a6c
      Jeff King authored
      In preparation for adding date modes that may carry extra
      information beyond the mode itself, this patch converts the
      date_mode enum into a struct.
      Most of the conversion is fairly straightforward; we pass
      the struct as a pointer and dereference the type field where
      necessary. Locations that declare a date_mode can use a "{}"
      constructor.  However, the tricky case is where we use the
      enum labels as constants, like:
        show_date(t, tz, DATE_NORMAL);
      Ideally we could say:
        show_date(t, tz, &{ DATE_NORMAL });
      but of course C does not allow that. Likewise, we cannot
      cast the constant to a struct, because we need to pass an
      actual address. Our options are basically:
        1. Manually add a "struct date_mode d = { DATE_NORMAL }"
           definition to each caller, and pass "&d". This makes
           the callers uglier, because they sometimes do not even
           have their own scope (e.g., they are inside a switch
        2. Provide a pre-made global "date_normal" struct that can
           be passed by address. We'd also need "date_rfc2822",
           "date_iso8601", and so forth. But at least the ugliness
           is defined in one place.
        3. Provide a wrapper that generates the correct struct on
           the fly. The big downside is that we end up pointing to
           a single global, which makes our wrapper non-reentrant.
           But show_date is already not reentrant, so it does not
      This patch implements 3, along with a minor macro to keep
      the size of the callers sane.
      Signed-off-by: default avatarJeff King <peff@peff.net>
      Signed-off-by: default avatarJunio C Hamano <gitster@pobox.com>
  10. 15 Apr, 2015 2 commits
  11. 13 Nov, 2014 2 commits
    • Jeff King's avatar
      approxidate: allow ISO-like dates far in the future · d3723953
      Jeff King authored
      When we are parsing approxidate strings and we find three
      numbers separate by one of ":/-.", we guess that it may be a
      date. We feed the numbers to match_multi_number, which
      checks whether it makes sense as a date in various orderings
      (e.g., dd/mm/yy or mm/dd/yy, etc).
      One of the checks we do is to see whether it is a date more
      than 10 days in the future. This was added in 38035cf4 (date
      parsing: be friendlier to our European friends.,
      2006-04-05), and lets us guess that if it is currently April
      2014, then "10/03/2014" is probably March 10th, not October
      This has a downside, though; if you want to be overly
      generous with your "--until" date specification, we may
      wrongly parse "2014-12-01" as "2014-01-12" (because the
      latter is an in-the-past date). If the year is a future year
      (i.e., both are future dates), it gets even weirder. Due to
      the vagaries of approxidate, months _after_ the current date
      (no matter the year) get flipped, but ones before do not.
      This patch drops the "in the future" check for dates of this
      form, letting us treat them always as yyyy-mm-dd, even if
      they are in the future. This does not affect the normal
      dd/mm/yyyy versus mm/dd/yyyy lookup, because this code path
      only kicks in when the first number is greater than 70
      (i.e., it must be a year, and cannot be either a date or a
      The one possible casualty is that "yyyy-dd-mm" is less
      likely to be chosen over "yyyy-mm-dd". That's probably OK,
      though because:
        1. The difference happens only when the date is in the
           future. Already we prefer yyyy-mm-dd for dates in the
        2. It's unclear whether anybody even uses yyyy-dd-mm
           regularly. It does not appear in lists of common date
           formats in Wikipedia[1,2].
        3. Even if (2) is wrong, it is better to prefer ISO-like
           dates, as that is consistent with what we use elsewhere
           in git.
      [1] http://en.wikipedia.org/wiki/Date_and_time_representation_by_country
      [2] http://en.wikipedia.org/wiki/Calendar_dateSigned-off-by: default avatarJeff King <peff@peff.net>
      Signed-off-by: default avatarJunio C Hamano <gitster@pobox.com>
    • Jeff King's avatar
      pass TIME_DATE_NOW to approxidate future-check · 073281e2
      Jeff King authored
      The approxidate functions accept an extra "now" parameter to
      avoid calling time() themselves. We use this in our test
      suite to make sure we have a consistent time for computing
      relative dates. However, deep in the bowels of approxidate,
      we also call time() to check whether possible dates are far
      in the future. Let's make sure that the "now" override makes
      it to that spot, too, so we can consistently test that
      Signed-off-by: default avatarJeff King <peff@peff.net>
      Signed-off-by: default avatarJunio C Hamano <gitster@pobox.com>
  12. 29 Aug, 2014 1 commit
  13. 27 Aug, 2014 1 commit
    • Jeff King's avatar
      date: use strbufs in date-formatting functions · c33ddc2e
      Jeff King authored
      Many of the date functions write into fixed-size buffers.
      This is a minor pain, as we have to take special
      precautions, and frequently end up copying the result into a
      strbuf or heap-allocated buffer anyway (for which we
      sometimes use strcpy!).
      Let's instead teach parse_date, datestamp, etc to write to a
      strbuf. The obvious downside is that we might need to
      perform a heap allocation where we otherwise would not need
      to. However, it turns out that the only two new allocations
      required are:
        1. In test-date.c, where we don't care about efficiency.
        2. In determine_author_info, which is not performance
           critical (and where the use of a strbuf will help later
      Signed-off-by: default avatarJeff King <peff@peff.net>
      Signed-off-by: default avatarJunio C Hamano <gitster@pobox.com>
  14. 17 Apr, 2014 1 commit
  15. 24 Feb, 2014 2 commits
    • Jeff King's avatar
      log: do not segfault on gmtime errors · 2b15846d
      Jeff King authored
      Many code paths assume that show_date and show_ident_date
      cannot return NULL. For the most part, we handle missing or
      corrupt timestamps by showing the epoch time t=0.
      However, we might still return NULL if gmtime rejects the
      time_t we feed it, resulting in a segfault. Let's catch this
      case and just format t=0.
      Signed-off-by: default avatarJeff King <peff@peff.net>
      Signed-off-by: default avatarJunio C Hamano <gitster@pobox.com>
    • Jeff King's avatar
      date: check date overflow against time_t · 7ca36d93
      Jeff King authored
      When we check whether a timestamp has overflowed, we check
      only against ULONG_MAX, meaning that strtoul has overflowed.
      However, we also feed these timestamps to system functions
      like gmtime, which expect a time_t. On many systems, time_t
      is actually smaller than "unsigned long" (e.g., because it
      is signed), and we would overflow when using these
      functions.  We don't know the actual size or signedness of
      time_t, but we can easily check for truncation with a simple
      Signed-off-by: default avatarJeff King <peff@peff.net>
      Signed-off-by: default avatarJunio C Hamano <gitster@pobox.com>
  16. 24 Oct, 2013 1 commit
  17. 17 Apr, 2013 1 commit
    • Junio C Hamano's avatar
      date.c: add parse_expiry_date() · 3d27b9b0
      Junio C Hamano authored
      "git reflog --expire=all" tries to expire reflog entries up to the
      current second, because the approxidate() parser gives the current
      timestamp for anything it does not understand (and it does not know
      what time "all" means).  When the user tells us to expire "all" (or
      set the expiration time to "now"), the user wants to remove all the
      reflog entries (no reflog entry should record future time).
      Just set it to ULONG_MAX and to let everything that is older that
      timestamp expire.
      While at it, allow "now" to be treated the same way for callers that
      parse expiry date timestamp with this function.  Also use an error
      reporting version of approxidate() to report misspelled date.  When
      the user says e.g. "--expire=mnoday" to delete entries two days or
      older on Wednesday, we wouldn't want the "unknown, default to now"
      logic to kick in.
      Signed-off-by: default avatarJunio C Hamano <gitster@pobox.com>
  18. 25 Feb, 2013 2 commits
  19. 12 Jul, 2012 1 commit
  20. 24 Apr, 2012 1 commit
  21. 04 Feb, 2012 2 commits
    • Junio C Hamano's avatar
      parse_date(): '@' prefix forces git-timestamp · 2c733fb2
      Junio C Hamano authored
      The only place that the issue this series addresses was observed
      where we read "cat-file commit" output and put it in GIT_AUTHOR_DATE
      in order to replay a commit with an ancient timestamp.
      With the previous patch alone, "git commit --date='20100917 +0900'"
      can be misinterpreted to mean an ancient timestamp, not September in
      year 2010.  Guard this codepath by requring an extra '@' in front of
      the raw git timestamp on the parsing side. This of course needs to
      be compensated by updating get_author_ident_from_commit and the code
      for "git commit --amend" to prepend '@' to the string read from the
      existing commit in the GIT_AUTHOR_DATE environment variable.
      Signed-off-by: default avatarJunio C Hamano <gitster@pobox.com>
    • Junio C Hamano's avatar
      parse_date(): allow ancient git-timestamp · 116eb3ab
      Junio C Hamano authored
      The date-time parser parses out a human-readble datestring piece by
      piece, so that it could even parse a string in a rather strange
      notation like 'noon november 11, 2005', but restricts itself from
      parsing strings in "<seconds since epoch> <timezone>" format only
      for reasonably new timestamps (like 1974 or newer) with 10 or more
      digits. This is to prevent a string like "20100917" from getting
      interpreted as seconds since epoch (we want to treat it as September
      17, 2010 instead) while doing so.
      The same codepath is used to read back the timestamp that we have
      already recorded in the headers of commit and tag objects; because
      of this, such a commit with timestamp "0 +0000" cannot be rebased or
      amended very easily.
      Teach parse_date() codepath to special case a string of the form
      "<digits> +<4-digits>" to work this issue around, but require that
      there is no other cruft around the string when parsing a timestamp
      of this format for safety.
      Note that this has a slight backward incompatibility implications.
      If somebody writes "git commit --date='20100917 +0900'" and wants it
      to mean a timestamp in September 2010 in Japan, this change will
      break such a use case.
      Signed-off-by: default avatarJunio C Hamano <gitster@pobox.com>
  22. 12 Sep, 2011 1 commit
  23. 21 Apr, 2011 1 commit
    • Michael J Gruber's avatar
      date: avoid "X years, 12 months" in relative dates · f1e9c548
      Michael J Gruber authored
      When relative dates are more than about a year ago, we start
      writing them as "Y years, M months".  At the point where we
      calculate Y and M, we have the time delta specified as a
      number of days. We calculate these integers as:
        Y = days / 365
        M = (days % 365 + 15) / 30
      This rounds days in the latter half of a month up to the
      nearest month, so that day 16 is "1 month" (or day 381 is "1
      year, 1 month").
      We don't round the year at all, though, meaning we can end
      up with "1 year, 12 months", which is silly; it should just
      be "2 years".
      Implement this differently with months of size
        onemonth = 365/12
      so that
        totalmonths = (long)( (days + onemonth/2)/onemonth )
        years = totalmonths / 12
        months = totalmonths % 12
      In order to do this without floats, we write the first formula as
        totalmonths = (days*12*2 + 365) / (365*2)
      Tests and inspiration by Jeff King.
      Helped-by: default avatarJeff King <peff@peff.net>
      Signed-off-by: default avatarMichael J Gruber <git@drmicha.warpmail.net>
      Signed-off-by: default avatarJunio C Hamano <gitster@pobox.com>
  24. 15 Jul, 2010 1 commit
  25. 05 Jul, 2010 1 commit
    • Jeff King's avatar
      parse_date: fix signedness in timezone calculation · 9ba0f033
      Jeff King authored
      When no timezone is specified, we deduce the offset by
      subtracting the result of mktime from our calculated
      However, our timestamp is stored as an unsigned integer,
      meaning we perform the subtraction as unsigned. For a
      negative offset, this means we wrap to a very high number,
      and our numeric timezone is in the millions of hours. You
      can see this bug by doing:
         $ TZ=EST \
           GIT_AUTHOR_DATE='2010-06-01 10:00' \
           git commit -a -m foo
         $ git cat-file -p HEAD | grep author
         author Jeff King <peff@peff.net> 1275404416 +119304128
      Instead, we should perform this subtraction as a time_t, the
      same type that mktime returns.
      Signed-off-by: default avatarJeff King <peff@peff.net>
      Signed-off-by: default avatarJunio C Hamano <gitster@pobox.com>
  26. 07 Jun, 2010 1 commit
  27. 19 May, 2010 1 commit
  28. 26 Jan, 2010 1 commit
    • Junio C Hamano's avatar
      approxidate_careful() reports errorneous date string · 93cfa7c7
      Junio C Hamano authored
      For a long time, the time based reflog syntax (e.g. master@{yesterday})
      didn't complain when the "human readable" timestamp was misspelled, as
      the underlying mechanism tried to be as lenient as possible.  The funny
      thing was that parsing of "@{now}" even relied on the fact that anything
      not recognized by the machinery returned the current timestamp.
      Introduce approxidate_careful() that takes an optional pointer to an
      integer, that gets assigned 1 when the input does not make sense as a
      As I am too lazy to fix all the callers that use approxidate(), most of
      the callers do not take advantage of the error checking, but convert the
      code to parse reflog to use it as a demonstration.
      Tests are mostly from Jeff King.
      Signed-off-by: default avatarJunio C Hamano <gitster@pobox.com>
  29. 20 Jan, 2010 1 commit
  30. 03 Oct, 2009 1 commit