Skip to content

Commit

Permalink
merge-ort: add implementation of checkout()
Browse files Browse the repository at this point in the history
Since merge-ort creates a tree for its output, when there are no
conflicts, updating the working tree and index is as simple as using the
unpack_trees() machinery with a twoway_merge (i.e. doing the equivalent
of a "checkout" operation).

If there were conflicts in the merge, then since the tree we created
included all the conflict markers, then using the unpack_trees machinery
in this manner will still update the working tree correctly.  Further,
all index entries corresponding to cleanly merged files will also be
updated correctly by this procedure.  Index entries corresponding to
conflicted entries will appear as though the user had run "git add -u"
after the merge to accept all files as-is with conflict markers.

Thus, after running unpack_trees(), there needs to be a separate step
for updating the entries in the index corresponding to conflicted files.
This will be the job for the function record_conflicted_index_entris(),
which will be implemented in a subsequent commit.

Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
  • Loading branch information
newren authored and gitster committed Dec 13, 2020
1 parent 9fefce6 commit 6681ce5
Showing 1 changed file with 44 additions and 1 deletion.
45 changes: 44 additions & 1 deletion merge-ort.c
Expand Up @@ -19,9 +19,11 @@

#include "diff.h"
#include "diffcore.h"
#include "dir.h"
#include "object-store.h"
#include "strmap.h"
#include "tree.h"
#include "unpack-trees.h"
#include "xdiff-interface.h"

/*
Expand Down Expand Up @@ -975,7 +977,48 @@ static int checkout(struct merge_options *opt,
struct tree *prev,
struct tree *next)
{
die("Not yet implemented.");
/* Switch the index/working copy from old to new */
int ret;
struct tree_desc trees[2];
struct unpack_trees_options unpack_opts;

memset(&unpack_opts, 0, sizeof(unpack_opts));
unpack_opts.head_idx = -1;
unpack_opts.src_index = opt->repo->index;
unpack_opts.dst_index = opt->repo->index;

setup_unpack_trees_porcelain(&unpack_opts, "merge");

/*
* NOTE: if this were just "git checkout" code, we would probably
* read or refresh the cache and check for a conflicted index, but
* builtin/merge.c or sequencer.c really needs to read the index
* and check for conflicted entries before starting merging for a
* good user experience (no sense waiting for merges/rebases before
* erroring out), so there's no reason to duplicate that work here.
*/

/* 2-way merge to the new branch */
unpack_opts.update = 1;
unpack_opts.merge = 1;
unpack_opts.quiet = 0; /* FIXME: sequencer might want quiet? */
unpack_opts.verbose_update = (opt->verbosity > 2);
unpack_opts.fn = twoway_merge;
if (1/* FIXME: opts->overwrite_ignore*/) {
unpack_opts.dir = xcalloc(1, sizeof(*unpack_opts.dir));
unpack_opts.dir->flags |= DIR_SHOW_IGNORED;
setup_standard_excludes(unpack_opts.dir);
}
parse_tree(prev);
init_tree_desc(&trees[0], prev->buffer, prev->size);
parse_tree(next);
init_tree_desc(&trees[1], next->buffer, next->size);

ret = unpack_trees(2, trees, &unpack_opts);
clear_unpack_trees_porcelain(&unpack_opts);
dir_clear(unpack_opts.dir);
FREE_AND_NULL(unpack_opts.dir);
return ret;
}

static int record_conflicted_index_entries(struct merge_options *opt,
Expand Down

0 comments on commit 6681ce5

Please sign in to comment.