1
0
Fork 0
mirror of https://github.com/git/git.git synced 2024-05-08 10:56:08 +02:00
git/merge.c
Eric W. Biederman efed687edc tree-walk: init_tree_desc take an oid to get the hash algorithm
To make it possible for git ls-tree to display the tree encoded
in the hash algorithm of the oid specified to git ls-tree, update
init_tree_desc to take as a parameter the oid of the tree object.

Update all callers of init_tree_desc and init_tree_desc_gently
to pass the oid of the tree object.

Use the oid of the tree object to discover the hash algorithm
of the oid and store that hash algorithm in struct tree_desc.

Use the hash algorithm in decode_tree_entry and
update_tree_entry_internal to handle reading a tree object encoded in
a hash algorithm that differs from the repositories hash algorithm.

Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-10-02 14:57:40 -07:00

112 lines
2.8 KiB
C

#include "git-compat-util.h"
#include "diff.h"
#include "diffcore.h"
#include "gettext.h"
#include "hash.h"
#include "hex.h"
#include "lockfile.h"
#include "merge.h"
#include "commit.h"
#include "repository.h"
#include "run-command.h"
#include "resolve-undo.h"
#include "tree.h"
#include "tree-walk.h"
#include "unpack-trees.h"
#include "dir.h"
static const char *merge_argument(struct commit *commit)
{
return oid_to_hex(commit ? &commit->object.oid : the_hash_algo->empty_tree);
}
int try_merge_command(struct repository *r,
const char *strategy, size_t xopts_nr,
const char **xopts, struct commit_list *common,
const char *head_arg, struct commit_list *remotes)
{
struct child_process cmd = CHILD_PROCESS_INIT;
int i, ret;
struct commit_list *j;
strvec_pushf(&cmd.args, "merge-%s", strategy);
for (i = 0; i < xopts_nr; i++)
strvec_pushf(&cmd.args, "--%s", xopts[i]);
for (j = common; j; j = j->next)
strvec_push(&cmd.args, merge_argument(j->item));
strvec_push(&cmd.args, "--");
strvec_push(&cmd.args, head_arg);
for (j = remotes; j; j = j->next)
strvec_push(&cmd.args, merge_argument(j->item));
cmd.git_cmd = 1;
ret = run_command(&cmd);
discard_index(r->index);
if (repo_read_index(r) < 0)
die(_("failed to read the cache"));
resolve_undo_clear_index(r->index);
return ret;
}
int checkout_fast_forward(struct repository *r,
const struct object_id *head,
const struct object_id *remote,
int overwrite_ignore)
{
struct tree *trees[MAX_UNPACK_TREES];
struct unpack_trees_options opts;
struct tree_desc t[MAX_UNPACK_TREES];
int i, nr_trees = 0;
struct lock_file lock_file = LOCK_INIT;
refresh_index(r->index, REFRESH_QUIET, NULL, NULL, NULL);
if (repo_hold_locked_index(r, &lock_file, LOCK_REPORT_ON_ERROR) < 0)
return -1;
memset(&trees, 0, sizeof(trees));
memset(&t, 0, sizeof(t));
trees[nr_trees] = parse_tree_indirect(head);
if (!trees[nr_trees++]) {
rollback_lock_file(&lock_file);
return -1;
}
trees[nr_trees] = parse_tree_indirect(remote);
if (!trees[nr_trees++]) {
rollback_lock_file(&lock_file);
return -1;
}
for (i = 0; i < nr_trees; i++) {
parse_tree(trees[i]);
init_tree_desc(t+i, &trees[i]->object.oid,
trees[i]->buffer, trees[i]->size);
}
memset(&opts, 0, sizeof(opts));
opts.preserve_ignored = !overwrite_ignore;
opts.head_idx = 1;
opts.src_index = r->index;
opts.dst_index = r->index;
opts.update = 1;
opts.verbose_update = 1;
opts.merge = 1;
opts.fn = twoway_merge;
init_checkout_metadata(&opts.meta, NULL, remote, NULL);
setup_unpack_trees_porcelain(&opts, "merge");
if (unpack_trees(nr_trees, t, &opts)) {
rollback_lock_file(&lock_file);
clear_unpack_trees_porcelain(&opts);
return -1;
}
clear_unpack_trees_porcelain(&opts);
if (write_locked_index(r->index, &lock_file, COMMIT_LOCK))
return error(_("unable to write new index file"));
return 0;
}