Re: [PATCH v2 0/6] Move the read_tree() function to its only user

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Sun, Mar 7, 2021 at 6:22 PM Ævar Arnfjörð Bjarmason <avarab@xxxxxxxxx> wrote:
>
> v1 of this series over-removed code supporting the "ls-files
> --with-tree=*" parameter. In v2 there's no change to its behavior,
> just refactoring away of read_tree() from the tree.c API and the
> cleanup of read_tree_recursive(). Thanks to Elijah for spotting that.
>
> I've added a test at the start of this series that would have caught
> that regression in v1 (and more).
>
> 1. https://lore.kernel.org/git/CABPp-BF982muRS4GO=zYegvetQyrPMwaEM3uEBvcbPRP=krfmQ@xxxxxxxxxxxxxx/

This addresses my concerns with v1; so:

Reviewed-by: Elijah Newren <newren@xxxxxxxxx>

>
> Ævar Arnfjörð Bjarmason (6):
>   ls-files tests: add meaningful --with-tree tests
>   tree.c API: move read_tree() into builtin/ls-files.c
>   ls-files: don't needlessly pass around stage variable
>   ls-files: refactor away read_tree()
>   tree.h API: remove support for starting at prefix != ""
>   tree.h API: remove "stage" parameter from read_tree_recursive()
>
>  archive.c                     |  13 +++--
>  builtin/checkout.c            |   4 +-
>  builtin/log.c                 |   6 +-
>  builtin/ls-files.c            |  76 ++++++++++++++++++++++++-
>  builtin/ls-tree.c             |   4 +-
>  merge-recursive.c             |   4 +-
>  t/t3060-ls-files-with-tree.sh |  41 ++++++++++++++
>  tree.c                        | 101 ++--------------------------------
>  tree.h                        |  10 +---
>  9 files changed, 139 insertions(+), 120 deletions(-)
>
> Range-diff:
> -:  ----------- > 1:  6416da0dee2 ls-files tests: add meaningful --with-tree tests
> 1:  020534164d3 ! 2:  765001b44cd tree.c API: move read_tree() into builtin/ls-files.c
>     @@ tree.c: int cmp_cache_name_compare(const void *a_, const void *b_)
>
>       ## tree.h ##
>      @@ tree.h: int read_tree_recursive(struct repository *r,
>     +                   const char *base, int baselen,
>                         int stage, const struct pathspec *pathspec,
>                         read_tree_fn_t fn, void *context);
>     -
>     +-
>      -int read_tree(struct repository *r, struct tree *tree,
>      -        int stage, struct pathspec *pathspec,
>      -        struct index_state *istate);
> 2:  6aa6ba2fbb5 = 3:  a71ffba7d04 ls-files: don't needlessly pass around stage variable
> 3:  4f27e5d2970 ! 4:  e78d1810b89 ls-files: remove cache juggling + sorting
>     @@ Metadata
>      Author: Ævar Arnfjörð Bjarmason <avarab@xxxxxxxxx>
>
>       ## Commit message ##
>     -    ls-files: remove cache juggling + sorting
>     +    ls-files: refactor away read_tree()
>
>     -    Remove the "ce_stage(ce) == 1" and "Sort the cache entry" code from
>     -    read_tree(), which allows us to remove the function entirely and move
>     -    over to read_tree_recursive().
>     +    Refactor away the read_tree() function into its only user,
>     +    overlay_tree_on_index().
>
>     -    I don't think the "Sort the cached entry" code was needed here, see
>     -    af3785dc5a7 (Optimize "diff --cached" performance., 2007-08-09) for
>     -    the use-case it was intended for. The only user of this code is
>     -    "ls-files --with-tree", which isn't the sort of use-case that needs to
>     -    care about "ce_stage(ce) != 0" or sorting tree entries.
>     +    First, change read_one_entry_opt() to use the strbuf parameter
>     +    read_tree_recursive() passes down in place. This finishes up a partial
>     +    refactoring started in 6a0b0b6de99 (tree.c: update read_tree_recursive
>     +    callback to pass strbuf as base, 2014-11-30).
>     +
>     +    Moving the rest into overlay_tree_on_index() makes this index juggling
>     +    we're doing easier to read.
>
>          Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@xxxxxxxxx>
>
>       ## builtin/ls-files.c ##
>     -@@
>     - #include "dir.h"
>     - #include "builtin.h"
>     - #include "tree.h"
>     --#include "cache-tree.h"
>     - #include "parse-options.h"
>     - #include "resolve-undo.h"
>     - #include "string-list.h"
>      @@ builtin/ls-files.c: static int get_common_prefix_len(const char *common_prefix)
>     -   return common_prefix_len;
>     - }
>
>     --static int read_one_entry_opt(struct index_state *istate,
>     --                        const struct object_id *oid,
>     + static int read_one_entry_opt(struct index_state *istate,
>     +                         const struct object_id *oid,
>      -                        const char *base, int baselen,
>     --                        const char *pathname,
>     --                        unsigned mode, int stage, int opt)
>     -+static int read_one_entry_quick(const struct object_id *oid,
>     -+                          struct strbuf *basebuf,
>     -+                          const char *pathname,
>     -+                          unsigned mode,
>     -+                          int stage, void *context)
>     ++                        struct strbuf *base,
>     +                         const char *pathname,
>     +                         unsigned mode, int stage, int opt)
>       {
>     -+  struct index_state *istate = context;
>     -+  const char *base = basebuf->buf;
>     -+  const int baselen = basebuf->len;
>     -   int len;
>     -   struct cache_entry *ce;
>     -
>      @@ builtin/ls-files.c: static int read_one_entry_opt(struct index_state *istate,
>     -   memcpy(ce->name, base, baselen);
>     -   memcpy(ce->name + baselen, pathname, len+1);
>     +           return READ_TREE_RECURSIVE;
>     +
>     +   len = strlen(pathname);
>     +-  ce = make_empty_cache_entry(istate, baselen + len);
>     ++  ce = make_empty_cache_entry(istate, base->len + len);
>     +
>     +   ce->ce_mode = create_ce_mode(mode);
>     +   ce->ce_flags = create_ce_flags(stage);
>     +-  ce->ce_namelen = baselen + len;
>     +-  memcpy(ce->name, base, baselen);
>     +-  memcpy(ce->name + baselen, pathname, len+1);
>     ++  ce->ce_namelen = base->len + len;
>     ++  memcpy(ce->name, base->buf, base->len);
>     ++  memcpy(ce->name + base->len, pathname, len+1);
>         oidcpy(&ce->oid, oid);
>     --  return add_index_entry(istate, ce, opt);
>     --}
>     --
>     --static int read_one_entry(const struct object_id *oid, struct strbuf *base,
>     --                    const char *pathname, unsigned mode, int stage,
>     --                    void *context)
>     --{
>     --  struct index_state *istate = context;
>     +   return add_index_entry(istate, ce, opt);
>     + }
>     +@@ builtin/ls-files.c: static int read_one_entry(const struct object_id *oid, struct strbuf *base,
>     +                     void *context)
>     + {
>     +   struct index_state *istate = context;
>      -  return read_one_entry_opt(istate, oid, base->buf, base->len, pathname,
>     --                            mode, stage,
>     --                            ADD_CACHE_OK_TO_ADD|ADD_CACHE_SKIP_DFCHECK);
>     --}
>     --
>     --/*
>     -- * This is used when the caller knows there is no existing entries at
>     -- * the stage that will conflict with the entry being added.
>     -- */
>     --static int read_one_entry_quick(const struct object_id *oid, struct strbuf *base,
>     --                          const char *pathname, unsigned mode, int stage,
>     --                          void *context)
>     --{
>     --  struct index_state *istate = context;
>     ++  return read_one_entry_opt(istate, oid, base, pathname,
>     +                             mode, stage,
>     +                             ADD_CACHE_OK_TO_ADD|ADD_CACHE_SKIP_DFCHECK);
>     + }
>     +@@ builtin/ls-files.c: static int read_one_entry_quick(const struct object_id *oid, struct strbuf *base
>     +                           void *context)
>     + {
>     +   struct index_state *istate = context;
>      -  return read_one_entry_opt(istate, oid, base->buf, base->len, pathname,
>     --                            mode, stage,
>     --                            ADD_CACHE_JUST_APPEND);
>     --}
>     --
>     ++  return read_one_entry_opt(istate, oid, base, pathname,
>     +                             mode, stage,
>     +                             ADD_CACHE_JUST_APPEND);
>     + }
>     +
>      -
>      -static int read_tree(struct repository *r, struct tree *tree,
>      -               struct pathspec *match, struct index_state *istate)
>     @@ builtin/ls-files.c: static int read_one_entry_opt(struct index_state *istate,
>      -  cache_tree_free(&istate->cache_tree);
>      -  QSORT(istate->cache, istate->cache_nr, cmp_cache_name_compare);
>      -  return 0;
>     -+  return add_index_entry(istate, ce, ADD_CACHE_JUST_APPEND);
>     - }
>     -
>     +-}
>     +-
>       /*
>     +  * Read the tree specified with --with-tree option
>     +  * (typically, HEAD) into stage #1 and then
>     +@@ builtin/ls-files.c: void overlay_tree_on_index(struct index_state *istate,
>     +   struct pathspec pathspec;
>     +   struct cache_entry *last_stage0 = NULL;
>     +   int i;
>     ++  read_tree_fn_t fn = NULL;
>     ++  int err;
>     +
>     +   if (get_oid(tree_name, &oid))
>     +           die("tree-ish %s not found.", tree_name);
>      @@ builtin/ls-files.c: void overlay_tree_on_index(struct index_state *istate,
>                                PATHSPEC_PREFER_CWD, prefix, matchbuf);
>         } else
>                 memset(&pathspec, 0, sizeof(pathspec));
>      -  if (read_tree(the_repository, tree, &pathspec, istate))
>     -+  if (read_tree_recursive(the_repository, tree, "", 0, 1,
>     -+                          &pathspec, read_one_entry_quick, istate))
>     ++
>     ++  /*
>     ++   * See if we have cache entry at the stage.  If so,
>     ++   * do it the original slow way, otherwise, append and then
>     ++   * sort at the end.
>     ++   */
>     ++  for (i = 0; !fn && i < istate->cache_nr; i++) {
>     ++          const struct cache_entry *ce = istate->cache[i];
>     ++          if (ce_stage(ce) == 1)
>     ++                  fn = read_one_entry;
>     ++  }
>     ++
>     ++  if (!fn)
>     ++          fn = read_one_entry_quick;
>     ++  err = read_tree_recursive(the_repository, tree, "", 0, 1, &pathspec, fn, istate);
>     ++  if (err)
>                 die("unable to read tree entries %s", tree_name);
>
>     ++  /*
>     ++   * Sort the cache entry -- we need to nuke the cache tree, though.
>     ++   */
>     ++  if (fn == read_one_entry_quick) {
>     ++          cache_tree_free(&istate->cache_tree);
>     ++          QSORT(istate->cache, istate->cache_nr, cmp_cache_name_compare);
>     ++  }
>     ++
>         for (i = 0; i < istate->cache_nr; i++) {
>     +           struct cache_entry *ce = istate->cache[i];
>     +           switch (ce_stage(ce)) {
> 4:  33810d3c10c < -:  ----------- merge-ort: move cmp_cache_name_compare() from tree.c
> 5:  fb10246b85b < -:  ----------- ls-files: refactor read_one_entry_quick() to use a strbuf
> 6:  0c065615aec ! 5:  05eecdd7519 tree.h API: remove support for starting at prefix != ""
>     @@ Metadata
>       ## Commit message ##
>          tree.h API: remove support for starting at prefix != ""
>
>     -    Every caller or the read_tree_recursive() function hardcoded a
>     +    Every caller of the read_tree_recursive() function hardcoded a
>          starting point of "" in the tree. So let's simply remove that
>          parameter.
>
>     -    It might be useful in the future to get this functionality back,
>     -    there's no reason we won't have a read_tree_recursive() use-case that
>     -    would want to start in a subdirectory.
>     +    The last function to call read_tree_recursive() with a non-"" path was
>     +    read_tree_recursive() itself, but that was changed in
>     +    ffd31f661d5 (Reimplement read_tree_recursive() using
>     +    tree_entry_interesting(), 2011-03-25).
>
>     -    But if and when that happens we can just add something like a
>     -    read_tree_recursive_subdir() and have both read_tree_recursive() and
>     -    that function be a thin wrapper for read_tree_1().
>     +    If in the future we need to support recursively reading trees without
>     +    starting at the root we can easily add a read_tree_recursive_subdir(),
>     +    and make that function a thin wrapper for read_tree_1().
>
>          In the meantime there's no reason to keep around what amounts to dead
>     -    code just in case we need it in the future.
>     +    code, just in case we need it in the future.
>
>          Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@xxxxxxxxx>
>
>     @@ builtin/log.c: int cmd_show(int argc, const char **argv, const char *prefix)
>
>       ## builtin/ls-files.c ##
>      @@ builtin/ls-files.c: void overlay_tree_on_index(struct index_state *istate,
>     -                          PATHSPEC_PREFER_CWD, prefix, matchbuf);
>     -   } else
>     -           memset(&pathspec, 0, sizeof(pathspec));
>     --  if (read_tree_recursive(the_repository, tree, "", 0, 1,
>     -+  if (read_tree_recursive(the_repository, tree, 1,
>     -                           &pathspec, read_one_entry_quick, istate))
>     +
>     +   if (!fn)
>     +           fn = read_one_entry_quick;
>     +-  err = read_tree_recursive(the_repository, tree, "", 0, 1, &pathspec, fn, istate);
>     ++  err = read_tree_recursive(the_repository, tree, 1, &pathspec, fn, istate);
>     +   if (err)
>                 die("unable to read tree entries %s", tree_name);
>
>
>     @@ tree.h: typedef int (*read_tree_fn_t)(const struct object_id *, struct strbuf *,
>      -                  const char *base, int baselen,
>                         int stage, const struct pathspec *pathspec,
>                         read_tree_fn_t fn, void *context);
>     -
>     + #endif /* TREE_H */
> 7:  9685c7c5c50 ! 6:  fcecc82e1c8 tree.h API: remove "stage" parameter from read_tree_recursive()
>     @@ builtin/log.c: int cmd_show(int argc, const char **argv, const char *prefix)
>                         break;
>
>       ## builtin/ls-files.c ##
>     -@@ builtin/ls-files.c: static int read_one_entry_quick(const struct object_id *oid,
>     -                           struct strbuf *base,
>     -                           const char *pathname,
>     -                           unsigned mode,
>     --                          int stage, void *context)
>     -+                          void *context)
>     +@@ builtin/ls-files.c: static int read_one_entry_opt(struct index_state *istate,
>     +                         const struct object_id *oid,
>     +                         struct strbuf *base,
>     +                         const char *pathname,
>     +-                        unsigned mode, int stage, int opt)
>     ++                        unsigned mode, int opt)
>       {
>     -   struct index_state *istate = context;
>         int len;
>     -@@ builtin/ls-files.c: static int read_one_entry_quick(const struct object_id *oid,
>     +   struct cache_entry *ce;
>     +@@ builtin/ls-files.c: static int read_one_entry_opt(struct index_state *istate,
>         ce = make_empty_cache_entry(istate, base->len + len);
>
>         ce->ce_mode = create_ce_mode(mode);
>     @@ builtin/ls-files.c: static int read_one_entry_quick(const struct object_id *oid,
>         ce->ce_namelen = base->len + len;
>         memcpy(ce->name, base->buf, base->len);
>         memcpy(ce->name + base->len, pathname, len+1);
>     +@@ builtin/ls-files.c: static int read_one_entry_opt(struct index_state *istate,
>     + }
>     +
>     + static int read_one_entry(const struct object_id *oid, struct strbuf *base,
>     +-                    const char *pathname, unsigned mode, int stage,
>     ++                    const char *pathname, unsigned mode,
>     +                     void *context)
>     + {
>     +   struct index_state *istate = context;
>     +   return read_one_entry_opt(istate, oid, base, pathname,
>     +-                            mode, stage,
>     ++                            mode,
>     +                             ADD_CACHE_OK_TO_ADD|ADD_CACHE_SKIP_DFCHECK);
>     + }
>     +
>     +@@ builtin/ls-files.c: static int read_one_entry(const struct object_id *oid, struct strbuf *base,
>     +  * the stage that will conflict with the entry being added.
>     +  */
>     + static int read_one_entry_quick(const struct object_id *oid, struct strbuf *base,
>     +-                          const char *pathname, unsigned mode, int stage,
>     ++                          const char *pathname, unsigned mode,
>     +                           void *context)
>     + {
>     +   struct index_state *istate = context;
>     +   return read_one_entry_opt(istate, oid, base, pathname,
>     +-                            mode, stage,
>     ++                            mode,
>     +                             ADD_CACHE_JUST_APPEND);
>     + }
>     +
>      @@ builtin/ls-files.c: void overlay_tree_on_index(struct index_state *istate,
>     -                          PATHSPEC_PREFER_CWD, prefix, matchbuf);
>     -   } else
>     -           memset(&pathspec, 0, sizeof(pathspec));
>     --  if (read_tree_recursive(the_repository, tree, 1,
>     -+  if (read_tree_recursive(the_repository, tree,
>     -                           &pathspec, read_one_entry_quick, istate))
>     +
>     +   if (!fn)
>     +           fn = read_one_entry_quick;
>     +-  err = read_tree_recursive(the_repository, tree, 1, &pathspec, fn, istate);
>     ++  err = read_tree_recursive(the_repository, tree, &pathspec, fn, istate);
>     +   if (err)
>                 die("unable to read tree entries %s", tree_name);
>
>
>     @@ tree.c: static int read_tree_1(struct repository *r,
>       }
>
>       ## tree.h ##
>     -@@ tree.h: void free_tree_buffer(struct tree *tree);
>     - struct tree *parse_tree_indirect(const struct object_id *oid);
>     +@@ tree.h: struct tree *parse_tree_indirect(const struct object_id *oid);
>     + int cmp_cache_name_compare(const void *a_, const void *b_);
>
>       #define READ_TREE_RECURSIVE 1
>      -typedef int (*read_tree_fn_t)(const struct object_id *, struct strbuf *, const char *, unsigned int, int, void *);
>     @@ tree.h: void free_tree_buffer(struct tree *tree);
>      -                  int stage, const struct pathspec *pathspec,
>      +                  const struct pathspec *pathspec,
>                         read_tree_fn_t fn, void *context);
>     -
>       #endif /* TREE_H */
> --
> 2.31.0.rc0.126.g04f22c5b82
>




[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux