Merge branch 'jk/reflog-date'
authorJunio C Hamano <gitster@pobox.com>
Mon, 8 Aug 2016 21:48:37 +0000 (14:48 -0700)
committerJunio C Hamano <gitster@pobox.com>
Mon, 8 Aug 2016 21:48:37 +0000 (14:48 -0700)
The reflog output format is documented better, and a new format
--date=unix to report the seconds-since-epoch (without timezone)
has been added.

* jk/reflog-date:
date: clarify --date=raw description
date: add "unix" format
date: document and test "raw-local" mode
doc/pretty-formats: explain shortening of %gd
doc/pretty-formats: describe index/time formats for %gd
doc/rev-list-options: explain "-g" output formats
doc/rev-list-options: clarify "commit@{Nth}" for "-g" option

1  2 
Documentation/rev-list-options.txt
builtin/blame.c
cache.h
index f39cb6d4f56e55da0c38841c9da0346b12b841a0,bee54a617787607ac217da7af97c5e34b5100578..a779c9dfec0ed962e7274577b1c53daa0ecff1d9
@@@ -193,7 -193,7 +193,7 @@@ endif::git-rev-list[
  
  --stdin::
        In addition to the '<commit>' listed on the command
 -      line, read them from the standard input. If a '--' separator is
 +      line, read them from the standard input. If a `--` separator is
        seen, stop reading commits and start reading paths to limit the
        result.
  
@@@ -252,10 -252,25 +252,25 @@@ list
  +
  With `--pretty` format other than `oneline` (for obvious reasons),
  this causes the output to have two extra lines of information
- taken from the reflog.  By default, 'commit@\{Nth}' notation is
- used in the output.  When the starting commit is specified as
- 'commit@\{now}', output also uses 'commit@\{timestamp}' notation
- instead.  Under `--pretty=oneline`, the commit message is
+ taken from the reflog.  The reflog designator in the output may be shown
+ as `ref@{Nth}` (where `Nth` is the reverse-chronological index in the
+ reflog) or as `ref@{timestamp}` (with the timestamp for that entry),
+ depending on a few rules:
+ +
+ --
+ 1. If the starting point is specified as `ref@{Nth}`, show the index
+ format.
+ +
+ 2. If the starting point was specified as `ref@{now}`, show the
+ timestamp format.
+ +
+ 3. If neither was used, but `--date` was given on the command line, show
+ the timestamp in the format requested by `--date`.
+ +
+ 4. Otherwise, show the index format.
+ --
+ +
+ Under `--pretty=oneline`, the commit message is
  prefixed with this information on the same line.
  This option cannot be combined with `--reverse`.
  See also linkgit:git-reflog[1].
@@@ -274,10 -289,6 +289,10 @@@ ifdef::git-rev-list[
        Try to speed up the traversal using the pack bitmap index (if
        one is available). Note that when traversing with `--objects`,
        trees and blobs will not have their associated path printed.
 +
 +--progress=<header>::
 +      Show progress reports on stderr as objects are considered. The
 +      `<header>` text will be printed with each progress update.
  endif::git-rev-list[]
  
  --
@@@ -714,8 -725,8 +729,8 @@@ include::pretty-options.txt[
        `iso-local`), the user's local time zone is used instead.
  +
  `--date=relative` shows dates relative to the current time,
- e.g. ``2 hours ago''. The `-local` option cannot be used with
- `--raw` or `--relative`.
+ e.g. ``2 hours ago''. The `-local` option has no effect for
+ `--date=relative`.
  +
  `--date=local` is an alias for `--date=default-local`.
  +
@@@ -735,7 -746,18 +750,18 @@@ format, often found in email messages
  +
  `--date=short` shows only the date, but not the time, in `YYYY-MM-DD` format.
  +
- `--date=raw` shows the date in the internal raw Git format `%s %z` format.
+ `--date=raw` shows the date as seconds since the epoch (1970-01-01
+ 00:00:00 UTC), followed by a space, and then the timezone as an offset
+ from UTC (a `+` or `-` with four digits; the first two are hours, and
+ the second two are minutes). I.e., as if the timestamp were formatted
+ with `strftime("%s %z")`).
+ Note that the `-local` option does not affect the seconds-since-epoch
+ value (which is always measured in UTC), but does switch the accompanying
+ timezone value.
+ +
+ `--date=unix` shows the date as a Unix epoch timestamp (seconds since
+ 1970).  As with `--raw`, this is always in UTC and therefore `-local`
+ has no effect.
  +
  `--date=format:...` feeds the format `...` to your system `strftime`.
  Use `--date=format:%c` to show the date in your system locale's
diff --combined builtin/blame.c
index ab66cde2c2cf0f535678469cdf6eb6e37cd3113b,002e70f9b59b5a6d4aefc8fe30bad6360cb1b63e..2e7b3030c67a4e83f902166533998461df444aa3
@@@ -56,7 -56,7 +56,7 @@@ static int show_progress
  static struct date_mode blame_date_mode = { DATE_ISO8601 };
  static size_t blame_date_width;
  
 -static struct string_list mailmap;
 +static struct string_list mailmap = STRING_LIST_INIT_NODUP;
  
  #ifndef DEBUG
  #define DEBUG 0
@@@ -134,7 -134,7 +134,7 @@@ struct progress_info 
        int blamed_lines;
  };
  
 -static int diff_hunks(mmfile_t *file_a, mmfile_t *file_b, long ctxlen,
 +static int diff_hunks(mmfile_t *file_a, mmfile_t *file_b,
                      xdl_emit_hunk_consume_func_t hunk_func, void *cb_data)
  {
        xpparam_t xpp = {0};
        xdemitcb_t ecb = {NULL};
  
        xpp.flags = xdl_opts;
 -      xecfg.ctxlen = ctxlen;
        xecfg.hunk_func = hunk_func;
        ecb.priv = cb_data;
        return xdi_diff(file_a, file_b, &xpp, &xecfg, &ecb);
@@@ -598,7 -599,7 +598,7 @@@ static struct origin *find_origin(struc
                            p->status);
                case 'M':
                        porigin = get_origin(sb, parent, origin->path);
 -                      hashcpy(porigin->blob_sha1, p->one->sha1);
 +                      hashcpy(porigin->blob_sha1, p->one->oid.hash);
                        porigin->mode = p->one->mode;
                        break;
                case 'A':
                }
        }
        diff_flush(&diff_opts);
 -      free_pathspec(&diff_opts.pathspec);
 +      clear_pathspec(&diff_opts.pathspec);
        return porigin;
  }
  
@@@ -644,13 -645,13 +644,13 @@@ static struct origin *find_rename(struc
                if ((p->status == 'R' || p->status == 'C') &&
                    !strcmp(p->two->path, origin->path)) {
                        porigin = get_origin(sb, parent, p->one->path);
 -                      hashcpy(porigin->blob_sha1, p->one->sha1);
 +                      hashcpy(porigin->blob_sha1, p->one->oid.hash);
                        porigin->mode = p->one->mode;
                        break;
                }
        }
        diff_flush(&diff_opts);
 -      free_pathspec(&diff_opts.pathspec);
 +      clear_pathspec(&diff_opts.pathspec);
        return porigin;
  }
  
@@@ -979,7 -980,7 +979,7 @@@ static void pass_blame_to_parent(struc
        fill_origin_blob(&sb->revs->diffopt, target, &file_o);
        num_get_patch++;
  
 -      if (diff_hunks(&file_p, &file_o, 0, blame_chunk_cb, &d))
 +      if (diff_hunks(&file_p, &file_o, blame_chunk_cb, &d))
                die("unable to generate diff (%s -> %s)",
                    oid_to_hex(&parent->commit->object.oid),
                    oid_to_hex(&target->commit->object.oid));
@@@ -1128,7 -1129,7 +1128,7 @@@ static void find_copy_in_blob(struct sc
         * file_p partially may match that image.
         */
        memset(split, 0, sizeof(struct blame_entry [3]));
 -      if (diff_hunks(file_p, &file_o, 1, handle_split_cb, &d))
 +      if (diff_hunks(file_p, &file_o, handle_split_cb, &d))
                die("unable to generate diff (%s)",
                    oid_to_hex(&parent->commit->object.oid));
        /* remainder, if any, all match the preimage */
@@@ -1308,7 -1309,7 +1308,7 @@@ static void find_copy_in_parent(struct 
                                continue;
  
                        norigin = get_origin(sb, parent, p->one->path);
 -                      hashcpy(norigin->blob_sha1, p->one->sha1);
 +                      hashcpy(norigin->blob_sha1, p->one->oid.hash);
                        norigin->mode = p->one->mode;
                        fill_origin_blob(&sb->revs->diffopt, norigin, &file_p);
                        if (!file_p.ptr)
        } while (unblamed);
        target->suspects = reverse_blame(leftover, NULL);
        diff_flush(&diff_opts);
 -      free_pathspec(&diff_opts.pathspec);
 +      clear_pathspec(&diff_opts.pathspec);
  }
  
  /*
@@@ -2229,7 -2230,6 +2229,7 @@@ static int git_blame_config(const char 
  static void verify_working_tree_path(struct commit *work_tree, const char *path)
  {
        struct commit_list *parents;
 +      int pos;
  
        for (parents = work_tree->parents; parents; parents = parents->next) {
                const unsigned char *commit_sha1 = parents->item->object.oid.hash;
                    sha1_object_info(blob_sha1, NULL) == OBJ_BLOB)
                        return;
        }
 -      die("no such path '%s' in HEAD", path);
 +
 +      pos = cache_name_pos(path, strlen(path));
 +      if (pos >= 0)
 +              ; /* path is in the index */
 +      else if (!strcmp(active_cache[-1 - pos]->name, path))
 +              ; /* path is in the index, unmerged */
 +      else
 +              die("no such path '%s' in HEAD", path);
  }
  
  static struct commit_list **append_parent(struct commit_list **tail, const unsigned char *sha1)
@@@ -2527,12 -2520,12 +2527,12 @@@ int cmd_blame(int argc, const char **ar
        enum object_type type;
        struct commit *final_commit = NULL;
  
 -      static struct string_list range_list;
 -      static int output_option = 0, opt = 0;
 -      static int show_stats = 0;
 -      static const char *revs_file = NULL;
 -      static const char *contents_from = NULL;
 -      static const struct option options[] = {
 +      struct string_list range_list = STRING_LIST_INIT_NODUP;
 +      int output_option = 0, opt = 0;
 +      int show_stats = 0;
 +      const char *revs_file = NULL;
 +      const char *contents_from = NULL;
 +      const struct option options[] = {
                OPT_BOOL(0, "incremental", &incremental, N_("Show blame entries as we find them, incrementally")),
                OPT_BOOL('b', NULL, &blank_boundary, N_("Show blank SHA-1 for boundary commits (Default: off)")),
                OPT_BOOL(0, "root", &show_root, N_("Do not treat root commits as boundaries (Default: off)")),
@@@ -2633,6 -2626,9 +2633,9 @@@ parse_done
        case DATE_RAW:
                blame_date_width = sizeof("1161298804 -0700");
                break;
+       case DATE_UNIX:
+               blame_date_width = sizeof("1161298804");
+               break;
        case DATE_SHORT:
                blame_date_width = sizeof("2006-10-19");
                break;
diff --combined cache.h
index b5f76a4cf4b1599f024f14553dd8c99a63abf77c,ace7f70e3b6eb30740c3964c80333c2572496d6b..6cddf2c1de906f1a45343acd3d268221c352ad3d
+++ b/cache.h
@@@ -632,7 -632,6 +632,7 @@@ extern void fill_stat_cache_info(struc
  #define REFRESH_IGNORE_SUBMODULES     0x0010  /* ignore submodules */
  #define REFRESH_IN_PORCELAIN  0x0020  /* user friendly output, not "needs update" */
  extern int refresh_index(struct index_state *, unsigned int flags, const struct pathspec *pathspec, char *seen, const char *header_msg);
 +extern struct cache_entry *refresh_cache_entry(struct cache_entry *, unsigned int);
  
  extern void update_index_if_able(struct index_state *, struct lock_file *);
  
@@@ -1004,11 -1003,6 +1004,11 @@@ int adjust_shared_perm(const char *path
   * directory while we were working.  To be robust against this kind of
   * race, callers might want to try invoking the function again when it
   * returns SCLD_VANISHED.
 + *
 + * safe_create_leading_directories() temporarily changes path while it
 + * is working but restores it before returning.
 + * safe_create_leading_directories_const() doesn't modify path, even
 + * temporarily.
   */
  enum scld_error {
        SCLD_OK = 0,
@@@ -1199,7 -1193,6 +1199,7 @@@ extern int get_oid_hex(const char *hex
   *   printf("%s -> %s", sha1_to_hex(one), sha1_to_hex(two));
   */
  extern char *sha1_to_hex_r(char *out, const unsigned char *sha1);
 +extern char *oid_to_hex_r(char *out, const struct object_id *oid);
  extern char *sha1_to_hex(const unsigned char *sha1);  /* static buffer result! */
  extern char *oid_to_hex(const struct object_id *oid); /* same static buffer as sha1_to_hex */
  
@@@ -1230,7 -1223,8 +1230,8 @@@ struct date_mode 
                DATE_ISO8601_STRICT,
                DATE_RFC2822,
                DATE_STRFTIME,
-               DATE_RAW
+               DATE_RAW,
+               DATE_UNIX
        } type;
        const char *strftime_fmt;
        int local;
@@@ -1515,7 -1509,7 +1516,7 @@@ struct object_info 
        /* Request */
        enum object_type *typep;
        unsigned long *sizep;
 -      unsigned long *disk_sizep;
 +      off_t *disk_sizep;
        unsigned char *delta_base_sha1;
        struct strbuf *typename;
  
@@@ -1611,16 -1605,6 +1612,16 @@@ extern const char *get_log_output_encod
  extern const char *get_commit_output_encoding(void);
  
  extern int git_config_parse_parameter(const char *, config_fn_t fn, void *data);
 +
 +enum config_scope {
 +      CONFIG_SCOPE_UNKNOWN = 0,
 +      CONFIG_SCOPE_SYSTEM,
 +      CONFIG_SCOPE_GLOBAL,
 +      CONFIG_SCOPE_REPO,
 +      CONFIG_SCOPE_CMDLINE,
 +};
 +
 +extern enum config_scope current_config_scope(void);
  extern const char *current_config_origin_type(void);
  extern const char *current_config_name(void);
  
@@@ -1713,8 -1697,6 +1714,8 @@@ extern int ignore_untracked_cache_confi
  struct key_value_info {
        const char *filename;
        int linenr;
 +      const char *origin_type;
 +      enum config_scope scope;
  };
  
  extern NORETURN void git_die_config(const char *key, const char *err, ...) __attribute__((format(printf, 2, 3)));
@@@ -1740,6 -1722,7 +1741,6 @@@ extern int copy_file(const char *dst, c
  extern int copy_file_with_time(const char *dst, const char *src, int mode);
  
  extern void write_or_die(int fd, const void *buf, size_t count);
 -extern int write_or_whine(int fd, const void *buf, size_t count, const char *msg);
  extern int write_or_whine_pipe(int fd, const void *buf, size_t count, const char *msg);
  extern void fsync_or_die(int fd, const char *);
  
@@@ -1752,21 -1735,8 +1753,21 @@@ static inline ssize_t write_str_in_full
        return write_in_full(fd, str, strlen(str));
  }
  
 -extern int write_file(const char *path, const char *fmt, ...);
 -extern int write_file_gently(const char *path, const char *fmt, ...);
 +/**
 + * Open (and truncate) the file at path, write the contents of buf to it,
 + * and close it. Dies if any errors are encountered.
 + */
 +extern void write_file_buf(const char *path, const char *buf, size_t len);
 +
 +/**
 + * Like write_file_buf(), but format the contents into a buffer first.
 + * Additionally, write_file() will append a newline if one is not already
 + * present, making it convenient to write text files:
 + *
 + *   write_file(path, "counter: %d", ctr);
 + */
 +__attribute__((format (printf, 2, 3)))
 +extern void write_file(const char *path, const char *fmt, ...);
  
  /* pager.c */
  extern void setup_pager(void);