Merge branch 'rs/unpack-trees-plug-leak'
authorJunio C Hamano <gitster@pobox.com>
Tue, 11 Jun 2013 20:30:05 +0000 (13:30 -0700)
committerJunio C Hamano <gitster@pobox.com>
Tue, 11 Jun 2013 20:30:05 +0000 (13:30 -0700)
* rs/unpack-trees-plug-leak:
unpack-trees: free cache_entry array members for merges
diff-lib, read-tree, unpack-trees: mark cache_entry array paramters const
diff-lib, read-tree, unpack-trees: mark cache_entry pointers const
unpack-trees: create working copy of merge entry in merged_entry
unpack-trees: factor out dup_entry
read-cache: mark cache_entry pointers const
cache: mark cache_entry pointers const

builtin/read-tree.c
cache.h
diff-lib.c
read-cache.c
unpack-trees.c
unpack-trees.h
index 042ac1b84f22257d1a8a4d32d34124b6dc372f16..0f5d7fe23f5b1e15e24e93daed68ece7542cf104 100644 (file)
@@ -66,7 +66,7 @@ static int exclude_per_directory_cb(const struct option *opt, const char *arg,
        return 0;
 }
 
-static void debug_stage(const char *label, struct cache_entry *ce,
+static void debug_stage(const char *label, const struct cache_entry *ce,
                        struct unpack_trees_options *o)
 {
        printf("%s ", label);
@@ -80,7 +80,8 @@ static void debug_stage(const char *label, struct cache_entry *ce,
                       sha1_to_hex(ce->sha1));
 }
 
-static int debug_merge(struct cache_entry **stages, struct unpack_trees_options *o)
+static int debug_merge(const struct cache_entry * const *stages,
+                      struct unpack_trees_options *o)
 {
        int i;
 
diff --git a/cache.h b/cache.h
index df532f8e4a597a0c9c4d3cbb4980f5d62a106334..820aa05c7a6f42aa3a3599c48f560a1074132596 100644 (file)
--- a/cache.h
+++ b/cache.h
@@ -190,7 +190,8 @@ struct cache_entry {
  * another. But we never change the name, or the hash state!
  */
 #define CE_STATE_MASK (CE_HASHED | CE_UNHASHED)
-static inline void copy_cache_entry(struct cache_entry *dst, struct cache_entry *src)
+static inline void copy_cache_entry(struct cache_entry *dst,
+                                   const struct cache_entry *src)
 {
        unsigned int state = dst->ce_flags & CE_STATE_MASK;
 
@@ -222,7 +223,8 @@ static inline unsigned int create_ce_mode(unsigned int mode)
                return S_IFGITLINK;
        return S_IFREG | ce_permissions(mode);
 }
-static inline unsigned int ce_mode_from_stat(struct cache_entry *ce, unsigned int mode)
+static inline unsigned int ce_mode_from_stat(const struct cache_entry *ce,
+                                            unsigned int mode)
 {
        extern int trust_executable_bit, has_symlinks;
        if (!has_symlinks && S_ISREG(mode) &&
@@ -480,8 +482,8 @@ extern void *read_blob_data_from_index(struct index_state *, const char *, unsig
 #define CE_MATCH_RACY_IS_DIRTY         02
 /* do stat comparison even if CE_SKIP_WORKTREE is true */
 #define CE_MATCH_IGNORE_SKIP_WORKTREE  04
-extern int ie_match_stat(const struct index_state *, struct cache_entry *, struct stat *, unsigned int);
-extern int ie_modified(const struct index_state *, struct cache_entry *, struct stat *, unsigned int);
+extern int ie_match_stat(const struct index_state *, const struct cache_entry *, struct stat *, unsigned int);
+extern int ie_modified(const struct index_state *, const struct cache_entry *, struct stat *, unsigned int);
 
 #define PATHSPEC_ONESTAR 1     /* the pathspec pattern sastisfies GFNM_ONESTAR */
 
index f35de0ffa0ec263acae7ac6211e3c2817987f760..b6f4b21637fe66a614a0dd6581f90fc12e80a6f8 100644 (file)
@@ -64,8 +64,9 @@ static int check_removed(const struct cache_entry *ce, struct stat *st)
  * commits, untracked content and/or modified content).
  */
 static int match_stat_with_submodule(struct diff_options *diffopt,
-                                     struct cache_entry *ce, struct stat *st,
-                                     unsigned ce_option, unsigned *dirty_submodule)
+                                    const struct cache_entry *ce,
+                                    struct stat *st, unsigned ce_option,
+                                    unsigned *dirty_submodule)
 {
        int changed = ce_match_stat(ce, st, ce_option);
        if (S_ISGITLINK(ce->ce_mode)) {
@@ -237,7 +238,7 @@ int run_diff_files(struct rev_info *revs, unsigned int option)
 /* A file entry went away or appeared */
 static void diff_index_show_file(struct rev_info *revs,
                                 const char *prefix,
-                                struct cache_entry *ce,
+                                const struct cache_entry *ce,
                                 const unsigned char *sha1, int sha1_valid,
                                 unsigned int mode,
                                 unsigned dirty_submodule)
@@ -246,7 +247,7 @@ static void diff_index_show_file(struct rev_info *revs,
                       sha1, sha1_valid, ce->name, dirty_submodule);
 }
 
-static int get_stat_data(struct cache_entry *ce,
+static int get_stat_data(const struct cache_entry *ce,
                         const unsigned char **sha1p,
                         unsigned int *modep,
                         int cached, int match_missing,
@@ -283,7 +284,7 @@ static int get_stat_data(struct cache_entry *ce,
 }
 
 static void show_new_file(struct rev_info *revs,
-                         struct cache_entry *new,
+                         const struct cache_entry *new,
                          int cached, int match_missing)
 {
        const unsigned char *sha1;
@@ -302,8 +303,8 @@ static void show_new_file(struct rev_info *revs,
 }
 
 static int show_modified(struct rev_info *revs,
-                        struct cache_entry *old,
-                        struct cache_entry *new,
+                        const struct cache_entry *old,
+                        const struct cache_entry *new,
                         int report_missing,
                         int cached, int match_missing)
 {
@@ -362,8 +363,8 @@ static int show_modified(struct rev_info *revs,
  * give you the position and number of entries in the index).
  */
 static void do_oneway_diff(struct unpack_trees_options *o,
-       struct cache_entry *idx,
-       struct cache_entry *tree)
+                          const struct cache_entry *idx,
+                          const struct cache_entry *tree)
 {
        struct rev_info *revs = o->unpack_data;
        int match_missing, cached;
@@ -423,10 +424,11 @@ static void do_oneway_diff(struct unpack_trees_options *o,
  * the fairly complex unpack_trees() semantic requirements, including
  * the skipping, the path matching, the type conflict cases etc.
  */
-static int oneway_diff(struct cache_entry **src, struct unpack_trees_options *o)
+static int oneway_diff(const struct cache_entry * const *src,
+                      struct unpack_trees_options *o)
 {
-       struct cache_entry *idx = src[0];
-       struct cache_entry *tree = src[1];
+       const struct cache_entry *idx = src[0];
+       const struct cache_entry *tree = src[1];
        struct rev_info *revs = o->unpack_data;
 
        /*
index 04ed561bfe7dd8fbf1988190f95eb1cc3530ff58..e6e046687e130dd0a926d0761cba95fc18e1a96c 100644 (file)
@@ -91,7 +91,7 @@ void fill_stat_cache_info(struct cache_entry *ce, struct stat *st)
                ce_mark_uptodate(ce);
 }
 
-static int ce_compare_data(struct cache_entry *ce, struct stat *st)
+static int ce_compare_data(const struct cache_entry *ce, struct stat *st)
 {
        int match = -1;
        int fd = open(ce->name, O_RDONLY);
@@ -105,7 +105,7 @@ static int ce_compare_data(struct cache_entry *ce, struct stat *st)
        return match;
 }
 
-static int ce_compare_link(struct cache_entry *ce, size_t expected_size)
+static int ce_compare_link(const struct cache_entry *ce, size_t expected_size)
 {
        int match = -1;
        void *buffer;
@@ -126,7 +126,7 @@ static int ce_compare_link(struct cache_entry *ce, size_t expected_size)
        return match;
 }
 
-static int ce_compare_gitlink(struct cache_entry *ce)
+static int ce_compare_gitlink(const struct cache_entry *ce)
 {
        unsigned char sha1[20];
 
@@ -143,7 +143,7 @@ static int ce_compare_gitlink(struct cache_entry *ce)
        return hashcmp(sha1, ce->sha1);
 }
 
-static int ce_modified_check_fs(struct cache_entry *ce, struct stat *st)
+static int ce_modified_check_fs(const struct cache_entry *ce, struct stat *st)
 {
        switch (st->st_mode & S_IFMT) {
        case S_IFREG:
@@ -163,7 +163,7 @@ static int ce_modified_check_fs(struct cache_entry *ce, struct stat *st)
        return 0;
 }
 
-static int ce_match_stat_basic(struct cache_entry *ce, struct stat *st)
+static int ce_match_stat_basic(const struct cache_entry *ce, struct stat *st)
 {
        unsigned int changed = 0;
 
@@ -239,7 +239,8 @@ static int ce_match_stat_basic(struct cache_entry *ce, struct stat *st)
        return changed;
 }
 
-static int is_racy_timestamp(const struct index_state *istate, struct cache_entry *ce)
+static int is_racy_timestamp(const struct index_state *istate,
+                            const struct cache_entry *ce)
 {
        return (!S_ISGITLINK(ce->ce_mode) &&
                istate->timestamp.sec &&
@@ -255,7 +256,7 @@ static int is_racy_timestamp(const struct index_state *istate, struct cache_entr
 }
 
 int ie_match_stat(const struct index_state *istate,
-                 struct cache_entry *ce, struct stat *st,
+                 const struct cache_entry *ce, struct stat *st,
                  unsigned int options)
 {
        unsigned int changed;
@@ -311,7 +312,8 @@ int ie_match_stat(const struct index_state *istate,
 }
 
 int ie_modified(const struct index_state *istate,
-               struct cache_entry *ce, struct stat *st, unsigned int options)
+               const struct cache_entry *ce,
+               struct stat *st, unsigned int options)
 {
        int changed, changed_fs;
 
index ede4299b833378ef5a4d44dac181d54889343a27..57b40743a1ae047de6837d70124298a49dc668e7 100644 (file)
@@ -116,14 +116,20 @@ static void do_add_entry(struct unpack_trees_options *o, struct cache_entry *ce,
                        ADD_CACHE_OK_TO_ADD | ADD_CACHE_OK_TO_REPLACE);
 }
 
-static void add_entry(struct unpack_trees_options *o, struct cache_entry *ce,
-       unsigned int set, unsigned int clear)
+static struct cache_entry *dup_entry(const struct cache_entry *ce)
 {
        unsigned int size = ce_size(ce);
        struct cache_entry *new = xmalloc(size);
 
        memcpy(new, ce, size);
-       do_add_entry(o, new, set, clear);
+       return new;
+}
+
+static void add_entry(struct unpack_trees_options *o,
+                     const struct cache_entry *ce,
+                     unsigned int set, unsigned int clear)
+{
+       do_add_entry(o, dup_entry(ce), set, clear);
 }
 
 /*
@@ -235,8 +241,11 @@ static int check_updates(struct unpack_trees_options *o)
        return errs != 0;
 }
 
-static int verify_uptodate_sparse(struct cache_entry *ce, struct unpack_trees_options *o);
-static int verify_absent_sparse(struct cache_entry *ce, enum unpack_trees_error_types, struct unpack_trees_options *o);
+static int verify_uptodate_sparse(const struct cache_entry *ce,
+                                 struct unpack_trees_options *o);
+static int verify_absent_sparse(const struct cache_entry *ce,
+                               enum unpack_trees_error_types,
+                               struct unpack_trees_options *o);
 
 static int apply_sparse_checkout(struct cache_entry *ce, struct unpack_trees_options *o)
 {
@@ -291,7 +300,8 @@ static int apply_sparse_checkout(struct cache_entry *ce, struct unpack_trees_opt
        return 0;
 }
 
-static inline int call_unpack_fn(struct cache_entry **src, struct unpack_trees_options *o)
+static inline int call_unpack_fn(const struct cache_entry * const *src,
+                                struct unpack_trees_options *o)
 {
        int ret = o->fn(src, o);
        if (ret > 0)
@@ -320,7 +330,7 @@ static void mark_all_ce_unused(struct index_state *index)
                index->cache[i]->ce_flags &= ~(CE_UNPACKED | CE_ADDED | CE_NEW_SKIP_WORKTREE);
 }
 
-static int locate_in_src_index(struct cache_entry *ce,
+static int locate_in_src_index(const struct cache_entry *ce,
                               struct unpack_trees_options *o)
 {
        struct index_state *index = o->src_index;
@@ -388,7 +398,7 @@ static void add_same_unmerged(struct cache_entry *ce,
 static int unpack_index_entry(struct cache_entry *ce,
                              struct unpack_trees_options *o)
 {
-       struct cache_entry *src[MAX_UNPACK_TREES + 1] = { NULL, };
+       const struct cache_entry *src[MAX_UNPACK_TREES + 1] = { NULL, };
        int ret;
 
        src[0] = ce;
@@ -590,8 +600,16 @@ static int unpack_nondirectories(int n, unsigned long mask,
                src[i + o->merge] = create_ce_entry(info, names + i, stage);
        }
 
-       if (o->merge)
-               return call_unpack_fn(src, o);
+       if (o->merge) {
+               int rc = call_unpack_fn((const struct cache_entry * const *)src,
+                                       o);
+               for (i = 0; i < n; i++) {
+                       struct cache_entry *ce = src[i + o->merge];
+                       if (ce != o->df_conflict_entry)
+                               free(ce);
+               }
+               return rc;
+       }
 
        for (i = 0; i < n; i++)
                if (src[i] && src[i] != o->df_conflict_entry)
@@ -995,7 +1013,9 @@ static void mark_new_skip_worktree(struct exclude_list *el,
                       select_flag, skip_wt_flag, el);
 }
 
-static int verify_absent(struct cache_entry *, enum unpack_trees_error_types, struct unpack_trees_options *);
+static int verify_absent(const struct cache_entry *,
+                        enum unpack_trees_error_types,
+                        struct unpack_trees_options *);
 /*
  * N-way merge "len" trees.  Returns 0 on success, -1 on failure to manipulate the
  * resulting index, -2 on failure to reflect the changes to the work tree.
@@ -1165,12 +1185,13 @@ int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options
 
 /* Here come the merge functions */
 
-static int reject_merge(struct cache_entry *ce, struct unpack_trees_options *o)
+static int reject_merge(const struct cache_entry *ce,
+                       struct unpack_trees_options *o)
 {
        return add_rejected_path(o, ERROR_WOULD_OVERWRITE, ce->name);
 }
 
-static int same(struct cache_entry *a, struct cache_entry *b)
+static int same(const struct cache_entry *a, const struct cache_entry *b)
 {
        if (!!a != !!b)
                return 0;
@@ -1187,9 +1208,9 @@ static int same(struct cache_entry *a, struct cache_entry *b)
  * When a CE gets turned into an unmerged entry, we
  * want it to be up-to-date
  */
-static int verify_uptodate_1(struct cache_entry *ce,
-                                  struct unpack_trees_options *o,
-                                  enum unpack_trees_error_types error_type)
+static int verify_uptodate_1(const struct cache_entry *ce,
+                            struct unpack_trees_options *o,
+                            enum unpack_trees_error_types error_type)
 {
        struct stat st;
 
@@ -1228,7 +1249,7 @@ static int verify_uptodate_1(struct cache_entry *ce,
                add_rejected_path(o, error_type, ce->name);
 }
 
-static int verify_uptodate(struct cache_entry *ce,
+static int verify_uptodate(const struct cache_entry *ce,
                           struct unpack_trees_options *o)
 {
        if (!o->skip_sparse_checkout && (ce->ce_flags & CE_NEW_SKIP_WORKTREE))
@@ -1236,13 +1257,14 @@ static int verify_uptodate(struct cache_entry *ce,
        return verify_uptodate_1(ce, o, ERROR_NOT_UPTODATE_FILE);
 }
 
-static int verify_uptodate_sparse(struct cache_entry *ce,
+static int verify_uptodate_sparse(const struct cache_entry *ce,
                                  struct unpack_trees_options *o)
 {
        return verify_uptodate_1(ce, o, ERROR_SPARSE_NOT_UPTODATE_FILE);
 }
 
-static void invalidate_ce_path(struct cache_entry *ce, struct unpack_trees_options *o)
+static void invalidate_ce_path(const struct cache_entry *ce,
+                              struct unpack_trees_options *o)
 {
        if (ce)
                cache_tree_invalidate_path(o->src_index->cache_tree, ce->name);
@@ -1255,16 +1277,16 @@ static void invalidate_ce_path(struct cache_entry *ce, struct unpack_trees_optio
  * Currently, git does not checkout subprojects during a superproject
  * checkout, so it is not going to overwrite anything.
  */
-static int verify_clean_submodule(struct cache_entry *ce,
-                                     enum unpack_trees_error_types error_type,
-                                     struct unpack_trees_options *o)
+static int verify_clean_submodule(const struct cache_entry *ce,
+                                 enum unpack_trees_error_types error_type,
+                                 struct unpack_trees_options *o)
 {
        return 0;
 }
 
-static int verify_clean_subdirectory(struct cache_entry *ce,
-                                     enum unpack_trees_error_types error_type,
-                                     struct unpack_trees_options *o)
+static int verify_clean_subdirectory(const struct cache_entry *ce,
+                                    enum unpack_trees_error_types error_type,
+                                    struct unpack_trees_options *o)
 {
        /*
         * we are about to extract "ce->name"; we would not want to lose
@@ -1350,7 +1372,7 @@ static int icase_exists(struct unpack_trees_options *o, const char *name, int le
 }
 
 static int check_ok_to_remove(const char *name, int len, int dtype,
-                             struct cache_entry *ce, struct stat *st,
+                             const struct cache_entry *ce, struct stat *st,
                              enum unpack_trees_error_types error_type,
                              struct unpack_trees_options *o)
 {
@@ -1405,9 +1427,9 @@ static int check_ok_to_remove(const char *name, int len, int dtype,
  * We do not want to remove or overwrite a working tree file that
  * is not tracked, unless it is ignored.
  */
-static int verify_absent_1(struct cache_entry *ce,
-                                enum unpack_trees_error_types error_type,
-                                struct unpack_trees_options *o)
+static int verify_absent_1(const struct cache_entry *ce,
+                          enum unpack_trees_error_types error_type,
+                          struct unpack_trees_options *o)
 {
        int len;
        struct stat st;
@@ -1440,7 +1462,7 @@ static int verify_absent_1(struct cache_entry *ce,
        }
 }
 
-static int verify_absent(struct cache_entry *ce,
+static int verify_absent(const struct cache_entry *ce,
                         enum unpack_trees_error_types error_type,
                         struct unpack_trees_options *o)
 {
@@ -1449,9 +1471,9 @@ static int verify_absent(struct cache_entry *ce,
        return verify_absent_1(ce, error_type, o);
 }
 
-static int verify_absent_sparse(struct cache_entry *ce,
-                        enum unpack_trees_error_types error_type,
-                        struct unpack_trees_options *o)
+static int verify_absent_sparse(const struct cache_entry *ce,
+                               enum unpack_trees_error_types error_type,
+                               struct unpack_trees_options *o)
 {
        enum unpack_trees_error_types orphaned_error = error_type;
        if (orphaned_error == ERROR_WOULD_LOSE_UNTRACKED_OVERWRITTEN)
@@ -1460,10 +1482,12 @@ static int verify_absent_sparse(struct cache_entry *ce,
        return verify_absent_1(ce, orphaned_error, o);
 }
 
-static int merged_entry(struct cache_entry *merge, struct cache_entry *old,
-               struct unpack_trees_options *o)
+static int merged_entry(const struct cache_entry *ce,
+                       const struct cache_entry *old,
+                       struct unpack_trees_options *o)
 {
        int update = CE_UPDATE;
+       struct cache_entry *merge = dup_entry(ce);
 
        if (!old) {
                /*
@@ -1481,8 +1505,11 @@ static int merged_entry(struct cache_entry *merge, struct cache_entry *old,
                update |= CE_ADDED;
                merge->ce_flags |= CE_NEW_SKIP_WORKTREE;
 
-               if (verify_absent(merge, ERROR_WOULD_LOSE_UNTRACKED_OVERWRITTEN, o))
+               if (verify_absent(merge,
+                                 ERROR_WOULD_LOSE_UNTRACKED_OVERWRITTEN, o)) {
+                       free(merge);
                        return -1;
+               }
                invalidate_ce_path(merge, o);
        } else if (!(old->ce_flags & CE_CONFLICTED)) {
                /*
@@ -1496,8 +1523,10 @@ static int merged_entry(struct cache_entry *merge, struct cache_entry *old,
                        copy_cache_entry(merge, old);
                        update = 0;
                } else {
-                       if (verify_uptodate(old, o))
+                       if (verify_uptodate(old, o)) {
+                               free(merge);
                                return -1;
+                       }
                        /* Migrate old flags over */
                        update |= old->ce_flags & (CE_SKIP_WORKTREE | CE_NEW_SKIP_WORKTREE);
                        invalidate_ce_path(old, o);
@@ -1510,12 +1539,13 @@ static int merged_entry(struct cache_entry *merge, struct cache_entry *old,
                invalidate_ce_path(old, o);
        }
 
-       add_entry(o, merge, update, CE_STAGEMASK);
+       do_add_entry(o, merge, update, CE_STAGEMASK);
        return 1;
 }
 
-static int deleted_entry(struct cache_entry *ce, struct cache_entry *old,
-               struct unpack_trees_options *o)
+static int deleted_entry(const struct cache_entry *ce,
+                        const struct cache_entry *old,
+                        struct unpack_trees_options *o)
 {
        /* Did it exist in the index? */
        if (!old) {
@@ -1530,7 +1560,8 @@ static int deleted_entry(struct cache_entry *ce, struct cache_entry *old,
        return 1;
 }
 
-static int keep_entry(struct cache_entry *ce, struct unpack_trees_options *o)
+static int keep_entry(const struct cache_entry *ce,
+                     struct unpack_trees_options *o)
 {
        add_entry(o, ce, 0, 0);
        return 1;
@@ -1552,11 +1583,12 @@ static void show_stage_entry(FILE *o,
 }
 #endif
 
-int threeway_merge(struct cache_entry **stages, struct unpack_trees_options *o)
+int threeway_merge(const struct cache_entry * const *stages,
+                  struct unpack_trees_options *o)
 {
-       struct cache_entry *index;
-       struct cache_entry *head;
-       struct cache_entry *remote = stages[o->head_idx + 1];
+       const struct cache_entry *index;
+       const struct cache_entry *head;
+       const struct cache_entry *remote = stages[o->head_idx + 1];
        int count;
        int head_match = 0;
        int remote_match = 0;
@@ -1641,7 +1673,7 @@ int threeway_merge(struct cache_entry **stages, struct unpack_trees_options *o)
        if (o->aggressive) {
                int head_deleted = !head;
                int remote_deleted = !remote;
-               struct cache_entry *ce = NULL;
+               const struct cache_entry *ce = NULL;
 
                if (index)
                        ce = index;
@@ -1724,11 +1756,12 @@ int threeway_merge(struct cache_entry **stages, struct unpack_trees_options *o)
  * "carry forward" rule, please see <Documentation/git-read-tree.txt>.
  *
  */
-int twoway_merge(struct cache_entry **src, struct unpack_trees_options *o)
+int twoway_merge(const struct cache_entry * const *src,
+                struct unpack_trees_options *o)
 {
-       struct cache_entry *current = src[0];
-       struct cache_entry *oldtree = src[1];
-       struct cache_entry *newtree = src[2];
+       const struct cache_entry *current = src[0];
+       const struct cache_entry *oldtree = src[1];
+       const struct cache_entry *newtree = src[2];
 
        if (o->merge_size != 2)
                return error("Cannot do a twoway merge of %d trees",
@@ -1790,11 +1823,11 @@ int twoway_merge(struct cache_entry **src, struct unpack_trees_options *o)
  * Keep the index entries at stage0, collapse stage1 but make sure
  * stage0 does not have anything there.
  */
-int bind_merge(struct cache_entry **src,
-               struct unpack_trees_options *o)
+int bind_merge(const struct cache_entry * const *src,
+              struct unpack_trees_options *o)
 {
-       struct cache_entry *old = src[0];
-       struct cache_entry *a = src[1];
+       const struct cache_entry *old = src[0];
+       const struct cache_entry *a = src[1];
 
        if (o->merge_size != 1)
                return error("Cannot do a bind merge of %d trees",
@@ -1814,10 +1847,11 @@ int bind_merge(struct cache_entry **src,
  * The rule is:
  * - take the stat information from stage0, take the data from stage1
  */
-int oneway_merge(struct cache_entry **src, struct unpack_trees_options *o)
+int oneway_merge(const struct cache_entry * const *src,
+                struct unpack_trees_options *o)
 {
-       struct cache_entry *old = src[0];
-       struct cache_entry *a = src[1];
+       const struct cache_entry *old = src[0];
+       const struct cache_entry *a = src[1];
 
        if (o->merge_size != 1)
                return error("Cannot do a oneway merge of %d trees",
index 5e432f576eb2304a63510a61a71182e11f777092..36a73a6d003b6906dfb402aa930b352f5b368c60 100644 (file)
@@ -8,7 +8,7 @@
 struct unpack_trees_options;
 struct exclude_list;
 
-typedef int (*merge_fn_t)(struct cache_entry **src,
+typedef int (*merge_fn_t)(const struct cache_entry * const *src,
                struct unpack_trees_options *options);
 
 enum unpack_trees_error_types {
@@ -77,9 +77,13 @@ struct unpack_trees_options {
 extern int unpack_trees(unsigned n, struct tree_desc *t,
                struct unpack_trees_options *options);
 
-int threeway_merge(struct cache_entry **stages, struct unpack_trees_options *o);
-int twoway_merge(struct cache_entry **src, struct unpack_trees_options *o);
-int bind_merge(struct cache_entry **src, struct unpack_trees_options *o);
-int oneway_merge(struct cache_entry **src, struct unpack_trees_options *o);
+int threeway_merge(const struct cache_entry * const *stages,
+                  struct unpack_trees_options *o);
+int twoway_merge(const struct cache_entry * const *src,
+                struct unpack_trees_options *o);
+int bind_merge(const struct cache_entry * const *src,
+              struct unpack_trees_options *o);
+int oneway_merge(const struct cache_entry * const *src,
+                struct unpack_trees_options *o);
 
 #endif