static int git_merge_trees(int index_only, struct tree *common, struct tree *head, struct tree *merge) { int rc; struct tree_desc t[3]; struct unpack_trees_options opts; memset(&opts, 0, sizeof(opts)); if (index_only) opts.index_only = 1; else opts.update = 1; opts.merge = 1; opts.head_idx = 2; opts.fn = threeway_merge; opts.src_index = &the_index; opts.dst_index = &the_index; opts.msgs = get_porcelain_error_msgs(); init_tree_desc_from_tree(t+0, common); init_tree_desc_from_tree(t+1, head); init_tree_desc_from_tree(t+2, merge); rc = unpack_trees(3, t, &opts); cache_tree_free(&active_cache_tree); return rc; }
static int checkout_fast_forward(unsigned char *head, unsigned char *remote) { struct tree *trees[MAX_UNPACK_TREES]; struct unpack_trees_options opts; struct tree_desc t[MAX_UNPACK_TREES]; int i, fd, nr_trees = 0; struct dir_struct dir; struct lock_file *lock_file = xcalloc(1, sizeof(struct lock_file)); refresh_cache(REFRESH_QUIET); fd = hold_locked_index(lock_file, 1); memset(&trees, 0, sizeof(trees)); memset(&opts, 0, sizeof(opts)); memset(&t, 0, sizeof(t)); memset(&dir, 0, sizeof(dir)); dir.flags |= DIR_SHOW_IGNORED; dir.exclude_per_dir = ".gitignore"; opts.dir = &dir; opts.head_idx = 1; opts.src_index = &the_index; opts.dst_index = &the_index; opts.update = 1; opts.verbose_update = 1; opts.merge = 1; opts.fn = twoway_merge; opts.msgs = get_porcelain_error_msgs(); trees[nr_trees] = parse_tree_indirect(head); if (!trees[nr_trees++]) return -1; trees[nr_trees] = parse_tree_indirect(remote); if (!trees[nr_trees++]) return -1; for (i = 0; i < nr_trees; i++) { parse_tree(trees[i]); init_tree_desc(t+i, trees[i]->buffer, trees[i]->size); } if (unpack_trees(nr_trees, t, &opts)) return -1; if (write_cache(fd, active_cache, active_nr) || commit_locked_index(lock_file)) die("unable to write new index file"); return 0; }