diff --git a/builtin-read-tree.c b/builtin-read-tree.c index 2a3a32cbfe..0c1f40d10d 100644 --- a/builtin-read-tree.c +++ b/builtin-read-tree.c @@ -64,6 +64,34 @@ 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, + struct unpack_trees_options *o) +{ + printf("%s ", label); + if (!ce) + printf("(missing)\n"); + else if (ce == o->df_conflict_entry) + printf("(conflict)\n"); + else + printf("%06o #%d %s %.8s\n", + ce->ce_mode, ce_stage(ce), ce->name, + sha1_to_hex(ce->sha1)); +} + +static int debug_merge(struct cache_entry **stages, struct unpack_trees_options *o) +{ + int i; + + printf("* %d-way merge\n", o->merge_size); + debug_stage("index", stages[0], o); + for (i = 1; i <= o->merge_size; i++) { + char buf[24]; + sprintf(buf, "ent#%d", i); + debug_stage(buf, stages[i], o); + } + return 0; +} + static struct lock_file lock_file; int cmd_read_tree(int argc, const char **argv, const char *unused_prefix) @@ -98,6 +126,8 @@ int cmd_read_tree(int argc, const char **argv, const char *unused_prefix) PARSE_OPT_NONEG, exclude_per_directory_cb }, OPT_SET_INT('i', NULL, &opts.index_only, "don't check the working tree after merging", 1), + OPT_SET_INT(0, "debug-unpack", &opts.debug_unpack, + "debug unpack-trees", 1), OPT_END() }; @@ -165,6 +195,9 @@ int cmd_read_tree(int argc, const char **argv, const char *unused_prefix) opts.head_idx = 1; } + if (opts.debug_unpack) + opts.fn = debug_merge; + cache_tree_free(&active_cache_tree); for (i = 0; i < nr_trees; i++) { struct tree *tree = trees[i]; @@ -174,6 +207,9 @@ int cmd_read_tree(int argc, const char **argv, const char *unused_prefix) if (unpack_trees(nr_trees, t, &opts)) return 128; + if (opts.debug_unpack) + return 0; /* do not write the index out */ + /* * When reading only one tree (either the most basic form, * "-m ent" or "--reset ent" form), we can obtain a fully diff --git a/unpack-trees.c b/unpack-trees.c index 74cabc36ff..10e8871a74 100644 --- a/unpack-trees.c +++ b/unpack-trees.c @@ -501,6 +501,38 @@ static struct cache_entry *find_cache_entry(struct traverse_info *info, return NULL; } +static void debug_path(struct traverse_info *info) +{ + if (info->prev) { + debug_path(info->prev); + if (*info->prev->name.path) + putchar('/'); + } + printf("%s", info->name.path); +} + +static void debug_name_entry(int i, struct name_entry *n) +{ + printf("ent#%d %06o %s\n", i, + n->path ? n->mode : 0, + n->path ? n->path : "(missing)"); +} + +static void debug_unpack_callback(int n, + unsigned long mask, + unsigned long dirmask, + struct name_entry *names, + struct traverse_info *info) +{ + int i; + printf("* unpack mask %lu, dirmask %lu, cnt %d ", + mask, dirmask, n); + debug_path(info); + putchar('\n'); + for (i = 0; i < n; i++) + debug_name_entry(i, names + i); +} + static int unpack_callback(int n, unsigned long mask, unsigned long dirmask, struct name_entry *names, struct traverse_info *info) { struct cache_entry *src[MAX_UNPACK_TREES + 1] = { NULL, }; @@ -511,6 +543,9 @@ static int unpack_callback(int n, unsigned long mask, unsigned long dirmask, str while (!p->mode) p++; + if (o->debug_unpack) + debug_unpack_callback(n, mask, dirmask, names, info); + /* Are we supposed to look at the index too? */ if (o->merge) { while (1) { diff --git a/unpack-trees.h b/unpack-trees.h index 9a0733ea85..701dca59a8 100644 --- a/unpack-trees.h +++ b/unpack-trees.h @@ -28,6 +28,7 @@ struct unpack_trees_options { skip_unmerged, initial_checkout, diff_index_cached, + debug_unpack, gently; const char *prefix; int cache_bottom;