/* * Get the new blocks that need to be checked out if we ff to @remote. */ static int get_new_blocks_ff (SeafRepo *repo, SeafCommit *head, SeafCommit *remote, BlockList **bl) { SeafRepoManager *mgr = repo->manager; char index_path[SEAF_PATH_MAX]; struct tree_desc trees[2]; struct unpack_trees_options topts; struct index_state istate; int ret = 0; memset (&istate, 0, sizeof(istate)); snprintf (index_path, SEAF_PATH_MAX, "%s/%s", mgr->index_dir, repo->id); if (read_index_from (&istate, index_path) < 0) { g_warning ("Failed to load index.\n"); return -1; } fill_tree_descriptor (&trees[0], head->root_id); fill_tree_descriptor (&trees[1], remote->root_id); memset(&topts, 0, sizeof(topts)); topts.base = repo->worktree; topts.head_idx = -1; topts.src_index = &istate; topts.update = 1; topts.merge = 1; topts.fn = twoway_merge; /* unpack_trees() doesn't update index or worktree. */ if (unpack_trees (2, trees, &topts) < 0) { g_warning ("Failed to ff to commit %s.\n", remote->commit_id); ret = -1; goto out; } *bl = block_list_new (); collect_new_blocks_from_index (&topts.result, *bl); out: tree_desc_free (&trees[0]); tree_desc_free (&trees[1]); discard_index (&istate); discard_index (&topts.result); return ret; }
static int seafile_merge_trees(struct merge_options *o, struct unpack_trees_options *opts, SeafDir *common, SeafDir *head, SeafDir *merge, char **error) { int rc; struct tree_desc t[3]; memset(opts, 0, sizeof(*opts)); if (o->call_depth) opts->index_only = 1; else opts->update = 1; opts->merge = 1; opts->head_idx = 2; opts->base = o->worktree; opts->fn = threeway_merge; opts->src_index = o->index; opts->dst_index = o->index; if (o->crypt) opts->crypt = o->crypt; fill_tree_descriptor(t+0, common->dir_id); fill_tree_descriptor(t+1, head->dir_id); fill_tree_descriptor(t+2, merge->dir_id); rc = unpack_trees(3, t, opts); if (rc == 0) { discard_index(o->index); *(o->index) = opts->result; if (o->collect_blocks_only) collect_new_blocks_from_index (o->index, o->bl); } tree_desc_free (t); tree_desc_free (t+1); tree_desc_free (t+2); return rc; }