From e1b3a2cad79a8138d18593c6eb3c46906ad2ee42 Mon Sep 17 00:00:00 2001 From: Daniel Barkalow Date: Thu, 7 Feb 2008 11:40:05 -0500 Subject: [PATCH] Build-in merge-recursive This makes write_tree_from_memory(), which writes the active cache as a tree and returns the struct tree for it, available to other code. It also makes available merge_trees(), which does the internal merge of two trees with a known base, and merge_recursive(), which does the recursive internal merge of two commits with a list of common ancestors. The first two of these will be used by checkout -m, and the third is presumably useful in general, although the implementation of checkout -m which entirely matches the behavior of the shell version does not use it (since it ignores the difference of ancestry between the old branch and the new branch). Signed-off-by: Daniel Barkalow --- Makefile | 2 +- ...e-recursive.c => builtin-merge-recursive.c | 44 ++++++++++--------- builtin.h | 1 + git.c | 1 + merge-recursive.h | 20 +++++++++ 5 files changed, 46 insertions(+), 22 deletions(-) rename merge-recursive.c => builtin-merge-recursive.c (98%) create mode 100644 merge-recursive.h diff --git a/Makefile b/Makefile index 5aac0c0c8..6f08bccbc 100644 --- a/Makefile +++ b/Makefile @@ -256,7 +256,6 @@ PROGRAMS = \ git-upload-pack$X \ git-pack-redundant$X git-var$X \ git-merge-tree$X git-imap-send$X \ - git-merge-recursive$X \ $(EXTRA_PROGRAMS) # Empty... @@ -360,6 +359,7 @@ BUILTIN_OBJS = \ builtin-merge-base.o \ builtin-merge-file.o \ builtin-merge-ours.o \ + builtin-merge-recursive.o \ builtin-mv.o \ builtin-name-rev.o \ builtin-pack-objects.o \ diff --git a/merge-recursive.c b/builtin-merge-recursive.c similarity index 98% rename from merge-recursive.c rename to builtin-merge-recursive.c index bdf03b1f1..45d460153 100644 --- a/merge-recursive.c +++ b/builtin-merge-recursive.c @@ -7,6 +7,7 @@ #include "cache-tree.h" #include "commit.h" #include "blob.h" +#include "builtin.h" #include "tree-walk.h" #include "diff.h" #include "diffcore.h" @@ -17,6 +18,7 @@ #include "xdiff-interface.h" #include "interpolate.h" #include "attr.h" +#include "merge-recursive.h" static int subtree_merge; @@ -232,7 +234,7 @@ static int unmerged_index(void) return 0; } -static struct tree *git_write_tree(void) +struct tree *write_tree_from_memory(void) { struct tree *result = NULL; @@ -1495,12 +1497,12 @@ static int process_entry(const char *path, struct stage_data *entry, return clean_merge; } -static int merge_trees(struct tree *head, - struct tree *merge, - struct tree *common, - const char *branch1, - const char *branch2, - struct tree **result) +int merge_trees(struct tree *head, + struct tree *merge, + struct tree *common, + const char *branch1, + const char *branch2, + struct tree **result) { int code, clean; @@ -1552,7 +1554,7 @@ static int merge_trees(struct tree *head, clean = 1; if (index_only) - *result = git_write_tree(); + *result = write_tree_from_memory(); return clean; } @@ -1572,12 +1574,12 @@ static struct commit_list *reverse_commit_list(struct commit_list *list) * Merge the commits h1 and h2, return the resulting virtual * commit object and a flag indicating the cleanness of the merge. */ -static int merge(struct commit *h1, - struct commit *h2, - const char *branch1, - const char *branch2, - struct commit_list *ca, - struct commit **result) +int merge_recursive(struct commit *h1, + struct commit *h2, + const char *branch1, + const char *branch2, + struct commit_list *ca, + struct commit **result) { struct commit_list *iter; struct commit *merged_common_ancestors; @@ -1622,11 +1624,11 @@ static int merge(struct commit *h1, * "conflicts" were already resolved. */ discard_cache(); - merge(merged_common_ancestors, iter->item, - "Temporary merge branch 1", - "Temporary merge branch 2", - NULL, - &merged_common_ancestors); + merge_recursive(merged_common_ancestors, iter->item, + "Temporary merge branch 1", + "Temporary merge branch 2", + NULL, + &merged_common_ancestors); call_depth--; if (!merged_common_ancestors) @@ -1695,7 +1697,7 @@ static int merge_config(const char *var, const char *value) return git_default_config(var, value); } -int main(int argc, char *argv[]) +int cmd_merge_recursive(int argc, const char **argv, const char *prefix) { static const char *bases[20]; static unsigned bases_count = 0; @@ -1749,7 +1751,7 @@ int main(int argc, char *argv[]) struct commit *ancestor = get_ref(bases[i]); ca = commit_list_insert(ancestor, &ca); } - clean = merge(h1, h2, branch1, branch2, ca, &result); + clean = merge_recursive(h1, h2, branch1, branch2, ca, &result); if (active_cache_changed && (write_cache(index_fd, active_cache, active_nr) || diff --git a/builtin.h b/builtin.h index cb675c4d7..428160d0e 100644 --- a/builtin.h +++ b/builtin.h @@ -57,6 +57,7 @@ extern int cmd_mailsplit(int argc, const char **argv, const char *prefix); extern int cmd_merge_base(int argc, const char **argv, const char *prefix); extern int cmd_merge_ours(int argc, const char **argv, const char *prefix); extern int cmd_merge_file(int argc, const char **argv, const char *prefix); +extern int cmd_merge_recursive(int argc, const char **argv, const char *prefix); extern int cmd_mv(int argc, const char **argv, const char *prefix); extern int cmd_name_rev(int argc, const char **argv, const char *prefix); extern int cmd_pack_objects(int argc, const char **argv, const char *prefix); diff --git a/git.c b/git.c index 15fec8974..114ea75ee 100644 --- a/git.c +++ b/git.c @@ -330,6 +330,7 @@ static void handle_internal_command(int argc, const char **argv) { "merge-base", cmd_merge_base, RUN_SETUP }, { "merge-file", cmd_merge_file }, { "merge-ours", cmd_merge_ours, RUN_SETUP }, + { "merge-recursive", cmd_merge_recursive, RUN_SETUP | NEED_WORK_TREE }, { "mv", cmd_mv, RUN_SETUP | NEED_WORK_TREE }, { "name-rev", cmd_name_rev, RUN_SETUP }, { "pack-objects", cmd_pack_objects, RUN_SETUP }, diff --git a/merge-recursive.h b/merge-recursive.h new file mode 100644 index 000000000..f37630a8a --- /dev/null +++ b/merge-recursive.h @@ -0,0 +1,20 @@ +#ifndef MERGE_RECURSIVE_H +#define MERGE_RECURSIVE_H + +int merge_recursive(struct commit *h1, + struct commit *h2, + const char *branch1, + const char *branch2, + struct commit_list *ancestors, + struct commit **result); + +int merge_trees(struct tree *head, + struct tree *merge, + struct tree *common, + const char *branch1, + const char *branch2, + struct tree **result); + +struct tree *write_tree_from_memory(void); + +#endif -- 2.26.2