about summary refs log tree commit diff
path: root/third_party/git/merge-recursive.h
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/git/merge-recursive.h')
-rw-r--r--third_party/git/merge-recursive.h164
1 files changed, 72 insertions, 92 deletions
diff --git a/third_party/git/merge-recursive.h b/third_party/git/merge-recursive.h
index 978847e672..c2b7bb65c6 100644
--- a/third_party/git/merge-recursive.h
+++ b/third_party/git/merge-recursive.h
@@ -1,124 +1,104 @@
 #ifndef MERGE_RECURSIVE_H
 #define MERGE_RECURSIVE_H
 
-#include "strbuf.h"
+#include "string-list.h"
+#include "unpack-trees.h"
 
 struct commit;
-struct commit_list;
-struct object_id;
+
 struct repository;
-struct tree;
 
-struct merge_options_internal;
 struct merge_options {
-	struct repository *repo;
-
-	/* ref names used in console messages and conflict markers */
 	const char *ancestor;
 	const char *branch1;
 	const char *branch2;
-
-	/* rename related options */
-	int detect_renames;
 	enum {
-		MERGE_DIRECTORY_RENAMES_NONE = 0,
-		MERGE_DIRECTORY_RENAMES_CONFLICT = 1,
-		MERGE_DIRECTORY_RENAMES_TRUE = 2
-	} detect_directory_renames;
-	int rename_limit;
-	int rename_score;
-	int show_rename_progress;
-
-	/* xdiff-related options (patience, ignore whitespace, ours/theirs) */
-	long xdl_opts;
-	enum {
-		MERGE_VARIANT_NORMAL = 0,
-		MERGE_VARIANT_OURS,
-		MERGE_VARIANT_THEIRS
+		MERGE_RECURSIVE_NORMAL = 0,
+		MERGE_RECURSIVE_OURS,
+		MERGE_RECURSIVE_THEIRS
 	} recursive_variant;
-
-	/* console output related options */
-	int verbosity;
-	unsigned buffer_output; /* 1: output at end, 2: keep buffered */
-	struct strbuf obuf;     /* output buffer; if buffer_output == 2, caller
-				 * must handle and call strbuf_release */
-
-	/* miscellaneous control options */
 	const char *subtree_shift;
+	unsigned buffer_output; /* 1: output at end, 2: keep buffered */
 	unsigned renormalize : 1;
-
-	/* internal fields used by the implementation */
-	struct merge_options_internal *priv;
+	long xdl_opts;
+	int verbosity;
+	int detect_directory_renames;
+	int diff_detect_rename;
+	int merge_detect_rename;
+	int diff_rename_limit;
+	int merge_rename_limit;
+	int rename_score;
+	int needed_rename_limit;
+	int show_rename_progress;
+	int call_depth;
+	struct strbuf obuf;
+	struct hashmap current_file_dir_set;
+	struct string_list df_conflict_file_set;
+	struct unpack_trees_options unpack_opts;
+	struct index_state orig_index;
+	struct repository *repo;
 };
 
-void init_merge_options(struct merge_options *opt, struct repository *repo);
-
-/* parse the option in s and update the relevant field of opt */
-int parse_merge_opt(struct merge_options *opt, const char *s);
-
 /*
- * RETURN VALUES: All the merge_* functions below return a value as follows:
- *   > 0     Merge was clean
- *   = 0     Merge had conflicts
- *   < 0     Merge hit an unexpected and unrecoverable problem (e.g. disk
- *             full) and aborted merge part-way through.
- */
-
-/*
- * rename-detecting three-way merge, no recursion.
+ * For dir_rename_entry, directory names are stored as a full path from the
+ * toplevel of the repository and do not include a trailing '/'.  Also:
  *
- * Outputs:
- *   - See RETURN VALUES above
- *   - No commit is created
- *   - opt->repo->index has the new index
- *   - $GIT_INDEX_FILE is not updated
- *   - The working tree is updated with results of the merge
+ *   dir:                original name of directory being renamed
+ *   non_unique_new_dir: if true, could not determine new_dir
+ *   new_dir:            final name of directory being renamed
+ *   possible_new_dirs:  temporary used to help determine new_dir; see comments
+ *                       in get_directory_renames() for details
  */
-int merge_trees(struct merge_options *opt,
-		struct tree *head,
-		struct tree *merge,
-		struct tree *merge_base);
+struct dir_rename_entry {
+	struct hashmap_entry ent; /* must be the first member! */
+	char *dir;
+	unsigned non_unique_new_dir:1;
+	struct strbuf new_dir;
+	struct string_list possible_new_dirs;
+};
 
-/*
- * merge_recursive is like merge_trees() but with recursive ancestor
- * consolidation and, if the commit is clean, creation of a commit.
- *
- * NOTE: empirically, about a decade ago it was determined that with more
- *       than two merge bases, optimal behavior was found when the
- *       merge_bases were passed in the order of oldest commit to newest
- *       commit.  Also, merge_bases will be consumed (emptied) so make a
- *       copy if you need it.
- *
- * Outputs:
- *   - See RETURN VALUES above
- *   - If merge is clean, a commit is created and its address written to *result
- *   - opt->repo->index has the new index
- *   - $GIT_INDEX_FILE is not updated
- *   - The working tree is updated with results of the merge
- */
-int merge_recursive(struct merge_options *opt,
+struct collision_entry {
+	struct hashmap_entry ent; /* must be the first member! */
+	char *target_file;
+	struct string_list source_files;
+	unsigned reported_already:1;
+};
+
+static inline int merge_detect_rename(struct merge_options *o)
+{
+	return o->merge_detect_rename >= 0 ? o->merge_detect_rename :
+		o->diff_detect_rename >= 0 ? o->diff_detect_rename : 1;
+}
+
+/* merge_trees() but with recursive ancestor consolidation */
+int merge_recursive(struct merge_options *o,
 		    struct commit *h1,
 		    struct commit *h2,
-		    struct commit_list *merge_bases,
+		    struct commit_list *ancestors,
 		    struct commit **result);
 
+/* rename-detecting three-way merge, no recursion */
+int merge_trees(struct merge_options *o,
+		struct tree *head,
+		struct tree *merge,
+		struct tree *common,
+		struct tree **result);
+
 /*
- * merge_recursive_generic can operate on trees instead of commits, by
- * wrapping the trees into virtual commits, and calling merge_recursive().
- * It also writes out the in-memory index to disk if the merge is successful.
- *
- * Outputs:
- *   - See RETURN VALUES above
- *   - If merge is clean, a commit is created and its address written to *result
- *   - opt->repo->index has the new index
- *   - $GIT_INDEX_FILE is updated
- *   - The working tree is updated with results of the merge
+ * "git-merge-recursive" can be fed trees; wrap them into
+ * virtual commits and call merge_recursive() proper.
  */
-int merge_recursive_generic(struct merge_options *opt,
+int merge_recursive_generic(struct merge_options *o,
 			    const struct object_id *head,
 			    const struct object_id *merge,
-			    int num_merge_bases,
-			    const struct object_id **merge_bases,
+			    int num_ca,
+			    const struct object_id **ca,
 			    struct commit **result);
 
+void init_merge_options(struct merge_options *o,
+			struct repository *repo);
+struct tree *write_tree_from_memory(struct merge_options *o);
+
+int parse_merge_opt(struct merge_options *out, const char *s);
+
 #endif