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 <barkalow@iabervon.org>
This commit is contained in:
parent
4e7c4571b8
commit
e1b3a2cad7
2
Makefile
2
Makefile
@ -256,7 +256,6 @@ PROGRAMS = \
|
|||||||
git-upload-pack$X \
|
git-upload-pack$X \
|
||||||
git-pack-redundant$X git-var$X \
|
git-pack-redundant$X git-var$X \
|
||||||
git-merge-tree$X git-imap-send$X \
|
git-merge-tree$X git-imap-send$X \
|
||||||
git-merge-recursive$X \
|
|
||||||
$(EXTRA_PROGRAMS)
|
$(EXTRA_PROGRAMS)
|
||||||
|
|
||||||
# Empty...
|
# Empty...
|
||||||
@ -360,6 +359,7 @@ BUILTIN_OBJS = \
|
|||||||
builtin-merge-base.o \
|
builtin-merge-base.o \
|
||||||
builtin-merge-file.o \
|
builtin-merge-file.o \
|
||||||
builtin-merge-ours.o \
|
builtin-merge-ours.o \
|
||||||
|
builtin-merge-recursive.o \
|
||||||
builtin-mv.o \
|
builtin-mv.o \
|
||||||
builtin-name-rev.o \
|
builtin-name-rev.o \
|
||||||
builtin-pack-objects.o \
|
builtin-pack-objects.o \
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include "cache-tree.h"
|
#include "cache-tree.h"
|
||||||
#include "commit.h"
|
#include "commit.h"
|
||||||
#include "blob.h"
|
#include "blob.h"
|
||||||
|
#include "builtin.h"
|
||||||
#include "tree-walk.h"
|
#include "tree-walk.h"
|
||||||
#include "diff.h"
|
#include "diff.h"
|
||||||
#include "diffcore.h"
|
#include "diffcore.h"
|
||||||
@ -17,6 +18,7 @@
|
|||||||
#include "xdiff-interface.h"
|
#include "xdiff-interface.h"
|
||||||
#include "interpolate.h"
|
#include "interpolate.h"
|
||||||
#include "attr.h"
|
#include "attr.h"
|
||||||
|
#include "merge-recursive.h"
|
||||||
|
|
||||||
static int subtree_merge;
|
static int subtree_merge;
|
||||||
|
|
||||||
@ -232,7 +234,7 @@ static int unmerged_index(void)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct tree *git_write_tree(void)
|
struct tree *write_tree_from_memory(void)
|
||||||
{
|
{
|
||||||
struct tree *result = NULL;
|
struct tree *result = NULL;
|
||||||
|
|
||||||
@ -1495,7 +1497,7 @@ static int process_entry(const char *path, struct stage_data *entry,
|
|||||||
return clean_merge;
|
return clean_merge;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int merge_trees(struct tree *head,
|
int merge_trees(struct tree *head,
|
||||||
struct tree *merge,
|
struct tree *merge,
|
||||||
struct tree *common,
|
struct tree *common,
|
||||||
const char *branch1,
|
const char *branch1,
|
||||||
@ -1552,7 +1554,7 @@ static int merge_trees(struct tree *head,
|
|||||||
clean = 1;
|
clean = 1;
|
||||||
|
|
||||||
if (index_only)
|
if (index_only)
|
||||||
*result = git_write_tree();
|
*result = write_tree_from_memory();
|
||||||
|
|
||||||
return clean;
|
return clean;
|
||||||
}
|
}
|
||||||
@ -1572,7 +1574,7 @@ static struct commit_list *reverse_commit_list(struct commit_list *list)
|
|||||||
* Merge the commits h1 and h2, return the resulting virtual
|
* Merge the commits h1 and h2, return the resulting virtual
|
||||||
* commit object and a flag indicating the cleanness of the merge.
|
* commit object and a flag indicating the cleanness of the merge.
|
||||||
*/
|
*/
|
||||||
static int merge(struct commit *h1,
|
int merge_recursive(struct commit *h1,
|
||||||
struct commit *h2,
|
struct commit *h2,
|
||||||
const char *branch1,
|
const char *branch1,
|
||||||
const char *branch2,
|
const char *branch2,
|
||||||
@ -1622,7 +1624,7 @@ static int merge(struct commit *h1,
|
|||||||
* "conflicts" were already resolved.
|
* "conflicts" were already resolved.
|
||||||
*/
|
*/
|
||||||
discard_cache();
|
discard_cache();
|
||||||
merge(merged_common_ancestors, iter->item,
|
merge_recursive(merged_common_ancestors, iter->item,
|
||||||
"Temporary merge branch 1",
|
"Temporary merge branch 1",
|
||||||
"Temporary merge branch 2",
|
"Temporary merge branch 2",
|
||||||
NULL,
|
NULL,
|
||||||
@ -1695,7 +1697,7 @@ static int merge_config(const char *var, const char *value)
|
|||||||
return git_default_config(var, 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 const char *bases[20];
|
||||||
static unsigned bases_count = 0;
|
static unsigned bases_count = 0;
|
||||||
@ -1749,7 +1751,7 @@ int main(int argc, char *argv[])
|
|||||||
struct commit *ancestor = get_ref(bases[i]);
|
struct commit *ancestor = get_ref(bases[i]);
|
||||||
ca = commit_list_insert(ancestor, &ca);
|
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 &&
|
if (active_cache_changed &&
|
||||||
(write_cache(index_fd, active_cache, active_nr) ||
|
(write_cache(index_fd, active_cache, active_nr) ||
|
@ -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_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_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_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_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_name_rev(int argc, const char **argv, const char *prefix);
|
||||||
extern int cmd_pack_objects(int argc, const char **argv, const char *prefix);
|
extern int cmd_pack_objects(int argc, const char **argv, const char *prefix);
|
||||||
|
1
git.c
1
git.c
@ -330,6 +330,7 @@ static void handle_internal_command(int argc, const char **argv)
|
|||||||
{ "merge-base", cmd_merge_base, RUN_SETUP },
|
{ "merge-base", cmd_merge_base, RUN_SETUP },
|
||||||
{ "merge-file", cmd_merge_file },
|
{ "merge-file", cmd_merge_file },
|
||||||
{ "merge-ours", cmd_merge_ours, RUN_SETUP },
|
{ "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 },
|
{ "mv", cmd_mv, RUN_SETUP | NEED_WORK_TREE },
|
||||||
{ "name-rev", cmd_name_rev, RUN_SETUP },
|
{ "name-rev", cmd_name_rev, RUN_SETUP },
|
||||||
{ "pack-objects", cmd_pack_objects, RUN_SETUP },
|
{ "pack-objects", cmd_pack_objects, RUN_SETUP },
|
||||||
|
20
merge-recursive.h
Normal file
20
merge-recursive.h
Normal file
@ -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
|
Loading…
Reference in New Issue
Block a user