Merge branch 'jk/unused-parameter-cleanup'
authorJunio C Hamano <gitster@pobox.com>
Thu, 7 Feb 2019 06:05:23 +0000 (22:05 -0800)
committerJunio C Hamano <gitster@pobox.com>
Thu, 7 Feb 2019 06:05:23 +0000 (22:05 -0800)
Code cleanup.

* jk/unused-parameter-cleanup:
convert: drop path parameter from actual conversion functions
convert: drop len parameter from conversion checks
config: drop unused parameter from maybe_remove_section()
show_date_relative(): drop unused "tz" parameter
column: drop unused "opts" parameter in item_length()
create_bundle(): drop unused "header" parameter
apply: drop unused "def" parameter from find_name_gnu()
match-trees: drop unused path parameter from score functions

1  2 
apply.c
cache.h
convert.c
match-trees.c
diff --combined apply.c
index f489a56f39c9a5f9541e5709d883c9d41d629193,ccab7e7907c874ea1bd6c65fb933abaffc5d0001..beed3091d2a347116a11cb4b593a70b2c90406f8
+++ b/apply.c
@@@ -467,7 -467,6 +467,6 @@@ static char *squash_slash(char *name
  
  static char *find_name_gnu(struct apply_state *state,
                           const char *line,
-                          const char *def,
                           int p_value)
  {
        struct strbuf name = STRBUF_INIT;
@@@ -714,7 -713,7 +713,7 @@@ static char *find_name(struct apply_sta
                       int terminate)
  {
        if (*line == '"') {
-               char *name = find_name_gnu(state, line, def, p_value);
+               char *name = find_name_gnu(state, line, p_value);
                if (name)
                        return name;
        }
@@@ -731,7 -730,7 +730,7 @@@ static char *find_name_traditional(stru
        size_t date_len;
  
        if (*line == '"') {
-               char *name = find_name_gnu(state, line, def, p_value);
+               char *name = find_name_gnu(state, line, p_value);
                if (name)
                        return name;
        }
@@@ -4020,7 -4019,7 +4019,7 @@@ static int read_apply_cache(struct appl
                return read_index_from(state->repo->index, state->index_file,
                                       get_git_dir());
        else
 -              return read_index(state->repo->index);
 +              return repo_read_index(state->repo);
  }
  
  /* This function tries to read the object name from the current index */
@@@ -4713,8 -4712,7 +4712,8 @@@ static int apply_patch(struct apply_sta
                                                  state->index_file,
                                                  LOCK_DIE_ON_ERROR);
                else
 -                      hold_locked_index(&state->lock_file, LOCK_DIE_ON_ERROR);
 +                      repo_hold_locked_index(state->repo, &state->lock_file,
 +                                             LOCK_DIE_ON_ERROR);
        }
  
        if (state->check_index && read_apply_cache(state) < 0) {
diff --combined cache.h
index c653668340232e2610729665c6fc740ee748232a,8d97939c0db5713becc2a2c3b380db4d4e3e6b33..400bc0ab25cd5dd12a3b1a71aab0168259df6e19
+++ b/cache.h
@@@ -45,20 -45,10 +45,20 @@@ unsigned long git_deflate_bound(git_zst
  /* The length in bytes and in hex digits of an object name (SHA-1 value). */
  #define GIT_SHA1_RAWSZ 20
  #define GIT_SHA1_HEXSZ (2 * GIT_SHA1_RAWSZ)
 +/* The block size of SHA-1. */
 +#define GIT_SHA1_BLKSZ 64
 +
 +/* The length in bytes and in hex digits of an object name (SHA-256 value). */
 +#define GIT_SHA256_RAWSZ 32
 +#define GIT_SHA256_HEXSZ (2 * GIT_SHA256_RAWSZ)
 +/* The block size of SHA-256. */
 +#define GIT_SHA256_BLKSZ 64
  
  /* The length in byte and in hex digits of the largest possible hash value. */
 -#define GIT_MAX_RAWSZ GIT_SHA1_RAWSZ
 -#define GIT_MAX_HEXSZ GIT_SHA1_HEXSZ
 +#define GIT_MAX_RAWSZ GIT_SHA256_RAWSZ
 +#define GIT_MAX_HEXSZ GIT_SHA256_HEXSZ
 +/* The largest possible block size for any supported hash. */
 +#define GIT_MAX_BLKSZ GIT_SHA256_BLKSZ
  
  struct object_id {
        unsigned char hash[GIT_MAX_RAWSZ];
@@@ -348,6 -338,8 +348,6 @@@ struct index_state 
        struct mem_pool *ce_mem_pool;
  };
  
 -extern struct index_state the_index;
 -
  /* Name hashing */
  extern int test_lazy_init_name_hash(struct index_state *istate, int try_threaded);
  extern void add_name_hash(struct index_state *istate, struct cache_entry *ce);
@@@ -409,20 -401,18 +409,20 @@@ struct cache_entry *dup_cache_entry(con
   */
  void validate_cache_entries(const struct index_state *istate);
  
 -#ifndef NO_THE_INDEX_COMPATIBILITY_MACROS
 +#ifdef USE_THE_INDEX_COMPATIBILITY_MACROS
 +extern struct index_state the_index;
 +
  #define active_cache (the_index.cache)
  #define active_nr (the_index.cache_nr)
  #define active_alloc (the_index.cache_alloc)
  #define active_cache_changed (the_index.cache_changed)
  #define active_cache_tree (the_index.cache_tree)
  
 -#define read_cache() read_index(&the_index)
 +#define read_cache() repo_read_index(the_repository)
  #define read_cache_from(path) read_index_from(&the_index, (path), (get_git_dir()))
 -#define read_cache_preload(pathspec) read_index_preload(&the_index, (pathspec), 0)
 +#define read_cache_preload(pathspec) repo_read_index_preload(the_repository, (pathspec), 0)
  #define is_cache_unborn() is_index_unborn(&the_index)
 -#define read_cache_unmerged() read_index_unmerged(&the_index)
 +#define read_cache_unmerged() repo_read_index_unmerged(the_repository)
  #define discard_cache() discard_index(&the_index)
  #define unmerged_cache() unmerged_index(&the_index)
  #define cache_name_pos(name, namelen) index_name_pos(&the_index,(name),(namelen))
  #define unmerge_cache_entry_at(at) unmerge_index_entry_at(&the_index, at)
  #define unmerge_cache(pathspec) unmerge_index(&the_index, pathspec)
  #define read_blob_data_from_cache(path, sz) read_blob_data_from_index(&the_index, (path), (sz))
 +#define hold_locked_index(lock_file, flags) repo_hold_locked_index(the_repository, (lock_file), (flags))
  #endif
  
  #define TYPE_BITS 3
@@@ -671,14 -660,19 +671,14 @@@ extern int daemonize(void)
  
  /* Initialize and use the cache information */
  struct lock_file;
 -extern int read_index(struct index_state *);
  extern void preload_index(struct index_state *index,
                          const struct pathspec *pathspec,
                          unsigned int refresh_flags);
 -extern int read_index_preload(struct index_state *,
 -                            const struct pathspec *pathspec,
 -                            unsigned int refresh_flags);
  extern int do_read_index(struct index_state *istate, const char *path,
                         int must_exist); /* for testting only! */
  extern int read_index_from(struct index_state *, const char *path,
                           const char *gitdir);
  extern int is_index_unborn(struct index_state *);
 -extern int read_index_unmerged(struct index_state *);
  
  /* For use with `write_locked_index()`. */
  #define COMMIT_LOCK           (1 << 0)
@@@ -716,9 -710,9 +716,9 @@@ extern int unmerged_index(const struct 
   * provided, the space-separated list of files that differ will be appended
   * to it.
   */
 -extern int index_has_changes(struct index_state *istate,
 -                           struct tree *tree,
 -                           struct strbuf *sb);
 +extern int repo_index_has_changes(struct repository *repo,
 +                                struct tree *tree,
 +                                struct strbuf *sb);
  
  extern int verify_path(const char *path, unsigned mode);
  extern int strcmp_offset(const char *s1, const char *s2, size_t *first_change);
@@@ -751,7 -745,6 +751,7 @@@ extern int index_name_pos(const struct 
  #define ADD_CACHE_JUST_APPEND 8               /* Append only; tree.c::read_tree() */
  #define ADD_CACHE_NEW_ONLY 16         /* Do not replace existing ones */
  #define ADD_CACHE_KEEP_CACHE_TREE 32  /* Do not invalidate cache-tree */
 +#define ADD_CACHE_RENORMALIZE 64        /* Pass along HASH_RENORMALIZE */
  extern int add_index_entry(struct index_state *, struct cache_entry *ce, int option);
  extern void rename_index_entry_at(struct index_state *, int pos, const char *new_name);
  
@@@ -834,6 -827,13 +834,6 @@@ extern void fill_stat_cache_info(struc
  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 index_state *, struct cache_entry *, unsigned int);
  
 -/*
 - * Opportunistically update the index but do not complain if we can't.
 - * The lockfile is always committed or rolled back.
 - */
 -extern void update_index_if_able(struct index_state *, struct lock_file *);
 -
 -extern int hold_locked_index(struct lock_file *, int);
  extern void set_alternate_index_output(const char *);
  
  extern int verify_index_checksum;
@@@ -1028,12 -1028,16 +1028,12 @@@ extern const struct object_id null_oid
  static inline int hashcmp(const unsigned char *sha1, const unsigned char *sha2)
  {
        /*
 -       * This is a temporary optimization hack. By asserting the size here,
 -       * we let the compiler know that it's always going to be 20, which lets
 -       * it turn this fixed-size memcmp into a few inline instructions.
 -       *
 -       * This will need to be extended or ripped out when we learn about
 -       * hashes of different sizes.
 +       * Teach the compiler that there are only two possibilities of hash size
 +       * here, so that it can optimize for this case as much as possible.
         */
 -      if (the_hash_algo->rawsz != 20)
 -              BUG("hash size not yet supported by hashcmp");
 -      return memcmp(sha1, sha2, the_hash_algo->rawsz);
 +      if (the_hash_algo->rawsz == GIT_MAX_RAWSZ)
 +              return memcmp(sha1, sha2, GIT_MAX_RAWSZ);
 +      return memcmp(sha1, sha2, GIT_SHA1_RAWSZ);
  }
  
  static inline int oidcmp(const struct object_id *oid1, const struct object_id *oid2)
  
  static inline int hasheq(const unsigned char *sha1, const unsigned char *sha2)
  {
 -      return !hashcmp(sha1, sha2);
 +      /*
 +       * We write this here instead of deferring to hashcmp so that the
 +       * compiler can properly inline it and avoid calling memcmp.
 +       */
 +      if (the_hash_algo->rawsz == GIT_MAX_RAWSZ)
 +              return !memcmp(sha1, sha2, GIT_MAX_RAWSZ);
 +      return !memcmp(sha1, sha2, GIT_SHA1_RAWSZ);
  }
  
  static inline int oideq(const struct object_id *oid1, const struct object_id *oid2)
@@@ -1074,7 -1072,7 +1074,7 @@@ static inline void hashcpy(unsigned cha
  
  static inline void oidcpy(struct object_id *dst, const struct object_id *src)
  {
 -      hashcpy(dst->hash, src->hash);
 +      memcpy(dst->hash, src->hash, GIT_MAX_RAWSZ);
  }
  
  static inline struct object_id *oiddup(const struct object_id *src)
@@@ -1334,24 -1332,6 +1334,24 @@@ struct object_context 
        GET_OID_TREE | GET_OID_TREEISH | \
        GET_OID_BLOB)
  
 +enum get_oid_result {
 +      FOUND = 0,
 +      MISSING_OBJECT = -1, /* The requested object is missing */
 +      SHORT_NAME_AMBIGUOUS = -2,
 +      /* The following only apply when symlinks are followed */
 +      DANGLING_SYMLINK = -4, /*
 +                              * The initial symlink is there, but
 +                              * (transitively) points to a missing
 +                              * in-tree file
 +                              */
 +      SYMLINK_LOOP = -5,
 +      NOT_DIR = -6, /*
 +                     * Somewhere along the symlink chain, a path is
 +                     * requested which contains a file as a
 +                     * non-final element.
 +                     */
 +};
 +
  extern int get_oid(const char *str, struct object_id *oid);
  extern int get_oid_commit(const char *str, struct object_id *oid);
  extern int get_oid_committish(const char *str, struct object_id *oid);
@@@ -1359,9 -1339,8 +1359,9 @@@ extern int get_oid_tree(const char *str
  extern int get_oid_treeish(const char *str, struct object_id *oid);
  extern int get_oid_blob(const char *str, struct object_id *oid);
  extern void maybe_die_on_misspelt_object_name(const char *name, const char *prefix);
 -extern int get_oid_with_context(const char *str, unsigned flags, struct object_id *oid, struct object_context *oc);
 -
 +extern enum get_oid_result get_oid_with_context(struct repository *repo, const char *str,
 +                              unsigned flags, struct object_id *oid,
 +                              struct object_context *oc);
  
  typedef int each_abbrev_fn(const struct object_id *oid, void *);
  extern int for_each_abbrev(const char *prefix, each_abbrev_fn, void *);
@@@ -1386,9 -1365,9 +1386,9 @@@ extern int get_oid_hex(const char *hex
  extern int hex_to_bytes(unsigned char *binary, const char *hex, size_t len);
  
  /*
 - * Convert a binary sha1 to its hex equivalent. The `_r` variant is reentrant,
 + * Convert a binary hash to its hex equivalent. The `_r` variant is reentrant,
   * and writes the NUL-terminated output to the buffer `out`, which must be at
 - * least `GIT_SHA1_HEXSZ + 1` bytes, and returns a pointer to out for
 + * least `GIT_MAX_HEXSZ + 1` bytes, and returns a pointer to out for
   * convenience.
   *
   * The non-`_r` variant returns a static buffer, but uses a ring of 4
   *
   *   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 */
 +char *hash_to_hex_algop_r(char *buffer, const unsigned char *hash, const struct git_hash_algo *);
 +char *sha1_to_hex_r(char *out, const unsigned char *sha1);
 +char *oid_to_hex_r(char *out, const struct object_id *oid);
 +char *hash_to_hex_algop(const unsigned char *hash, const struct git_hash_algo *);     /* static buffer result! */
 +char *sha1_to_hex(const unsigned char *sha1);                                         /* same static buffer */
 +char *hash_to_hex(const unsigned char *hash);                                         /* same static buffer */
 +char *oid_to_hex(const struct object_id *oid);                                                /* same static buffer */
  
  /*
   * Parse a 40-character hexadecimal object ID starting from hex, updating the
@@@ -1488,7 -1464,7 +1488,7 @@@ struct date_mode 
  struct date_mode *date_mode_from_type(enum date_mode_type type);
  
  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,
+ void show_date_relative(timestamp_t time, const struct timeval *now,
                        struct strbuf *timebuf);
  int parse_date(const char *date, struct strbuf *out);
  int parse_date_basic(const char *date, timestamp_t *timestamp, int *offset);
@@@ -1812,7 -1788,4 +1812,7 @@@ void safe_create_dir(const char *dir, i
   */
  extern int print_sha1_ellipsis(void);
  
 +/* Return 1 if the file is empty or does not exists, 0 otherwise. */
 +extern int is_empty_or_missing_file(const char *filename);
 +
  #endif /* CACHE_H */
diff --combined convert.c
index 489510c35374ed148bbf578400d7780bf57af9e3,d8d7df3353817535c6e9b093bc5d8b711b872ca4..5d0307fc1004f215c48a6f653e21da41bee71baa
+++ b/convert.c
@@@ -1,3 -1,4 +1,3 @@@
 -#define NO_THE_INDEX_COMPATIBILITY_MACROS
  #include "cache.h"
  #include "config.h"
  #include "object-store.h"
@@@ -91,7 -92,7 +91,7 @@@ static void gather_stats(const char *bu
   * The same heuristics as diff.c::mmfile_is_binary()
   * We treat files with bare CR as binary
   */
- static int convert_is_binary(unsigned long size, const struct text_stat *stats)
+ static int convert_is_binary(const struct text_stat *stats)
  {
        if (stats->lonecr)
                return 1;
@@@ -109,7 -110,7 +109,7 @@@ static unsigned int gather_convert_stat
        if (!data || !size)
                return 0;
        gather_stats(data, size, &stats);
-       if (convert_is_binary(size, &stats))
+       if (convert_is_binary(&stats))
                ret |= CONVERT_STAT_BITS_BIN;
        if (stats.crlf)
                ret |= CONVERT_STAT_BITS_TXT_CRLF;
@@@ -244,7 -245,7 +244,7 @@@ static int has_crlf_in_index(const stru
        return has_crlf;
  }
  
- static int will_convert_lf_to_crlf(size_t len, struct text_stat *stats,
+ static int will_convert_lf_to_crlf(struct text_stat *stats,
                                   enum crlf_action crlf_action)
  {
        if (output_eol(crlf_action) != EOL_CRLF)
                if (stats->lonecr || stats->crlf)
                        return 0;
  
-               if (convert_is_binary(len, stats))
+               if (convert_is_binary(stats))
                        return 0;
        }
        return 1;
@@@ -526,7 -527,7 +526,7 @@@ static int crlf_to_git(const struct ind
        convert_crlf_into_lf = !!stats.crlf;
  
        if (crlf_action == CRLF_AUTO || crlf_action == CRLF_AUTO_INPUT || crlf_action == CRLF_AUTO_CRLF) {
-               if (convert_is_binary(len, &stats))
+               if (convert_is_binary(&stats))
                        return 0;
                /*
                 * If the file in the index has any CR in it, do not
                        new_stats.crlf = 0;
                }
                /* simulate "git checkout" */
-               if (will_convert_lf_to_crlf(len, &new_stats, crlf_action)) {
+               if (will_convert_lf_to_crlf(&new_stats, crlf_action)) {
                        new_stats.crlf += new_stats.lonelf;
                        new_stats.lonelf = 0;
                }
        return 1;
  }
  
- static int crlf_to_worktree(const char *path, const char *src, size_t len,
+ static int crlf_to_worktree(const char *src, size_t len,
                            struct strbuf *buf, enum crlf_action crlf_action)
  {
        char *to_free = NULL;
                return 0;
  
        gather_stats(src, len, &stats);
-       if (!will_convert_lf_to_crlf(len, &stats, crlf_action))
+       if (!will_convert_lf_to_crlf(&stats, crlf_action))
                return 0;
  
        /* are we "faking" in place editing ? */
@@@ -1090,7 -1091,7 +1090,7 @@@ static int count_ident(const char *cp, 
        return cnt;
  }
  
- static int ident_to_git(const char *path, const char *src, size_t len,
+ static int ident_to_git(const char *src, size_t len,
                        struct strbuf *buf, int ident)
  {
        char *dst, *dollar;
        return 1;
  }
  
- static int ident_to_worktree(const char *path, const char *src, size_t len,
+ static int ident_to_worktree(const char *src, size_t len,
                             struct strbuf *buf, int ident)
  {
        struct object_id oid;
@@@ -1415,7 -1416,7 +1415,7 @@@ int convert_to_git(const struct index_s
                        len = dst->len;
                }
        }
-       return ret | ident_to_git(path, src, len, dst, ca.ident);
+       return ret | ident_to_git(src, len, dst, ca.ident);
  }
  
  void convert_to_git_filter_fd(const struct index_state *istate,
  
        encode_to_git(path, dst->buf, dst->len, dst, ca.working_tree_encoding, conv_flags);
        crlf_to_git(istate, path, dst->buf, dst->len, dst, ca.crlf_action, conv_flags);
-       ident_to_git(path, dst->buf, dst->len, dst, ca.ident);
+       ident_to_git(dst->buf, dst->len, dst, ca.ident);
  }
  
  static int convert_to_working_tree_internal(const struct index_state *istate,
  
        convert_attrs(istate, &ca, path);
  
-       ret |= ident_to_worktree(path, src, len, dst, ca.ident);
+       ret |= ident_to_worktree(src, len, dst, ca.ident);
        if (ret) {
                src = dst->buf;
                len = dst->len;
         * support smudge).  The filters might expect CRLFs.
         */
        if ((ca.drv && (ca.drv->smudge || ca.drv->process)) || !normalizing) {
-               ret |= crlf_to_worktree(path, src, len, dst, ca.crlf_action);
+               ret |= crlf_to_worktree(src, len, dst, ca.crlf_action);
                if (ret) {
                        src = dst->buf;
                        len = dst->len;
diff --combined match-trees.c
index 18ab825bef57f3ea63f70adf9a5c4e4a4f000bc4,e65e665bf526c5169a734ee6bbd9a4013c9bc059..ddc4d398456363cede9f3f5d4fa602efb402b5bd
@@@ -3,7 -3,7 +3,7 @@@
  #include "tree-walk.h"
  #include "object-store.h"
  
- static int score_missing(unsigned mode, const char *path)
+ static int score_missing(unsigned mode)
  {
        int score;
  
@@@ -16,7 -16,7 +16,7 @@@
        return score;
  }
  
- static int score_differs(unsigned mode1, unsigned mode2, const char *path)
+ static int score_differs(unsigned mode1, unsigned mode2)
  {
        int score;
  
@@@ -29,7 -29,7 +29,7 @@@
        return score;
  }
  
- static int score_matches(unsigned mode1, unsigned mode2, const char *path)
+ static int score_matches(unsigned mode1, unsigned mode2)
  {
        int score;
  
@@@ -98,24 -98,22 +98,22 @@@ static int score_trees(const struct obj
  
                if (cmp < 0) {
                        /* path1 does not appear in two */
-                       score += score_missing(one.entry.mode, one.entry.path);
+                       score += score_missing(one.entry.mode);
                        update_tree_entry(&one);
                } else if (cmp > 0) {
                        /* path2 does not appear in one */
-                       score += score_missing(two.entry.mode, two.entry.path);
+                       score += score_missing(two.entry.mode);
                        update_tree_entry(&two);
                } else {
                        /* path appears in both */
 -                      if (!oideq(one.entry.oid, two.entry.oid)) {
 +                      if (!oideq(&one.entry.oid, &two.entry.oid)) {
                                /* they are different */
                                score += score_differs(one.entry.mode,
-                                                      two.entry.mode,
-                                                      one.entry.path);
+                                                      two.entry.mode);
                        } else {
                                /* same subtree or blob */
                                score += score_matches(one.entry.mode,
-                                                      two.entry.mode,
-                                                      one.entry.path);
+                                                      two.entry.mode);
                        }
                        update_tree_entry(&one);
                        update_tree_entry(&two);
@@@ -179,7 -177,7 +177,7 @@@ static int splice_tree(const struct obj
        char *buf;
        unsigned long sz;
        struct tree_desc desc;
 -      struct object_id *rewrite_here;
 +      unsigned char *rewrite_here;
        const struct object_id *rewrite_with;
        struct object_id subtree;
        enum object_type type;
        while (desc.size) {
                const char *name;
                unsigned mode;
 -              const struct object_id *oid;
  
 -              oid = tree_entry_extract(&desc, &name, &mode);
 +              tree_entry_extract(&desc, &name, &mode);
                if (strlen(name) == toplen &&
                    !memcmp(name, prefix, toplen)) {
                        if (!S_ISDIR(mode))
                                die("entry %s in tree %s is not a tree", name,
                                    oid_to_hex(oid1));
 -                      rewrite_here = (struct object_id *)oid;
 +
 +                      /*
 +                       * We cast here for two reasons:
 +                       *
 +                       *   - to flip the "char *" (for the path) to "unsigned
 +                       *     char *" (for the hash stored after it)
 +                       *
 +                       *   - to discard the "const"; this is OK because we
 +                       *     know it points into our non-const "buf"
 +                       */
 +                      rewrite_here = (unsigned char *)(desc.entry.path +
 +                                                       strlen(desc.entry.path) +
 +                                                       1);
                        break;
                }
                update_tree_entry(&desc);
                die("entry %.*s not found in tree %s", toplen, prefix,
                    oid_to_hex(oid1));
        if (*subpath) {
 -              status = splice_tree(rewrite_here, subpath, oid2, &subtree);
 +              struct object_id tree_oid;
 +              hashcpy(tree_oid.hash, rewrite_here);
 +              status = splice_tree(&tree_oid, subpath, oid2, &subtree);
                if (status)
                        return status;
                rewrite_with = &subtree;
        } else {
                rewrite_with = oid2;
        }
 -      oidcpy(rewrite_here, rewrite_with);
 +      hashcpy(rewrite_here, rewrite_with->hash);
        status = write_object_file(buf, sz, tree_type, result);
        free(buf);
        return status;