mirror of
https://github.com/git/git
synced 2024-08-27 11:39:22 +00:00
![Jeff King](/assets/img/avatar_default.png)
The "argc" and "argv" names made sense when the struct was argv_array, but now they're just confusing. Let's rename them to "nr" (which we use for counts elsewhere) and "v" (which is rather terse, but reads well when combined with typical variable names like "args.v"). Note that we have to update all of the callers immediately. Playing tricks with the preprocessor is hard here, because we wouldn't want to rewrite unrelated tokens. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
111 lines
2.8 KiB
C
111 lines
2.8 KiB
C
#include "cache.h"
|
|
#include "diff.h"
|
|
#include "diffcore.h"
|
|
#include "lockfile.h"
|
|
#include "commit.h"
|
|
#include "run-command.h"
|
|
#include "resolve-undo.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 strvec args = STRVEC_INIT;
|
|
int i, ret;
|
|
struct commit_list *j;
|
|
|
|
strvec_pushf(&args, "merge-%s", strategy);
|
|
for (i = 0; i < xopts_nr; i++)
|
|
strvec_pushf(&args, "--%s", xopts[i]);
|
|
for (j = common; j; j = j->next)
|
|
strvec_push(&args, merge_argument(j->item));
|
|
strvec_push(&args, "--");
|
|
strvec_push(&args, head_arg);
|
|
for (j = remotes; j; j = j->next)
|
|
strvec_push(&args, merge_argument(j->item));
|
|
|
|
ret = run_command_v_opt(args.v, RUN_GIT_CMD);
|
|
strvec_clear(&args);
|
|
|
|
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 dir_struct dir;
|
|
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]->buffer, trees[i]->size);
|
|
}
|
|
|
|
memset(&opts, 0, sizeof(opts));
|
|
if (overwrite_ignore) {
|
|
memset(&dir, 0, sizeof(dir));
|
|
dir.flags |= DIR_SHOW_IGNORED;
|
|
setup_standard_excludes(&dir);
|
|
opts.dir = &dir;
|
|
}
|
|
|
|
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;
|
|
}
|