Skip to content

Commit 6681ce5

Browse files
newrengitster
authored andcommitted
merge-ort: add implementation of checkout()
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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 9fefce6 commit 6681ce5

File tree

1 file changed

+44
-1
lines changed

1 file changed

+44
-1
lines changed

merge-ort.c

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,11 @@
1919

2020
#include "diff.h"
2121
#include "diffcore.h"
22+
#include "dir.h"
2223
#include "object-store.h"
2324
#include "strmap.h"
2425
#include "tree.h"
26+
#include "unpack-trees.h"
2527
#include "xdiff-interface.h"
2628

2729
/*
@@ -975,7 +977,48 @@ static int checkout(struct merge_options *opt,
975977
struct tree *prev,
976978
struct tree *next)
977979
{
978-
die("Not yet implemented.");
980+
/* Switch the index/working copy from old to new */
981+
int ret;
982+
struct tree_desc trees[2];
983+
struct unpack_trees_options unpack_opts;
984+
985+
memset(&unpack_opts, 0, sizeof(unpack_opts));
986+
unpack_opts.head_idx = -1;
987+
unpack_opts.src_index = opt->repo->index;
988+
unpack_opts.dst_index = opt->repo->index;
989+
990+
setup_unpack_trees_porcelain(&unpack_opts, "merge");
991+
992+
/*
993+
* NOTE: if this were just "git checkout" code, we would probably
994+
* read or refresh the cache and check for a conflicted index, but
995+
* builtin/merge.c or sequencer.c really needs to read the index
996+
* and check for conflicted entries before starting merging for a
997+
* good user experience (no sense waiting for merges/rebases before
998+
* erroring out), so there's no reason to duplicate that work here.
999+
*/
1000+
1001+
/* 2-way merge to the new branch */
1002+
unpack_opts.update = 1;
1003+
unpack_opts.merge = 1;
1004+
unpack_opts.quiet = 0; /* FIXME: sequencer might want quiet? */
1005+
unpack_opts.verbose_update = (opt->verbosity > 2);
1006+
unpack_opts.fn = twoway_merge;
1007+
if (1/* FIXME: opts->overwrite_ignore*/) {
1008+
unpack_opts.dir = xcalloc(1, sizeof(*unpack_opts.dir));
1009+
unpack_opts.dir->flags |= DIR_SHOW_IGNORED;
1010+
setup_standard_excludes(unpack_opts.dir);
1011+
}
1012+
parse_tree(prev);
1013+
init_tree_desc(&trees[0], prev->buffer, prev->size);
1014+
parse_tree(next);
1015+
init_tree_desc(&trees[1], next->buffer, next->size);
1016+
1017+
ret = unpack_trees(2, trees, &unpack_opts);
1018+
clear_unpack_trees_porcelain(&unpack_opts);
1019+
dir_clear(unpack_opts.dir);
1020+
FREE_AND_NULL(unpack_opts.dir);
1021+
return ret;
9791022
}
9801023

9811024
static int record_conflicted_index_entries(struct merge_options *opt,

0 commit comments

Comments
 (0)