summaryrefslogtreecommitdiff
path: root/tests/merge
diff options
context:
space:
mode:
authorEdward Thomson <ethomson@edwardthomson.com>2015-12-23 10:23:08 -0600
committerEdward Thomson <ethomson@github.com>2016-03-17 11:02:26 -0400
commit3f04219fcdcbc6369270eaf2d878d4fe7064254d (patch)
tree38163746ebb430e787d7a82bdec44cac5d82df4c /tests/merge
parent7a74590d8f952971088a90c584945ceefe1bf90e (diff)
downloadlibgit2-3f04219fcdcbc6369270eaf2d878d4fe7064254d.tar.gz
merge driver: introduce custom merge drivers
Consumers can now register custom merged drivers with `git_merge_driver_register`. This allows consumers to support the merge drivers, as configured in `.gitattributes`. Consumers will be asked to perform the file-level merge when a custom driver is configured.
Diffstat (limited to 'tests/merge')
-rw-r--r--tests/merge/driver.c208
1 files changed, 208 insertions, 0 deletions
diff --git a/tests/merge/driver.c b/tests/merge/driver.c
new file mode 100644
index 000000000..34ed914dc
--- /dev/null
+++ b/tests/merge/driver.c
@@ -0,0 +1,208 @@
+#include "clar_libgit2.h"
+#include "git2/repository.h"
+#include "git2/merge.h"
+#include "buffer.h"
+#include "merge.h"
+
+#define TEST_REPO_PATH "merge-resolve"
+#define BRANCH_ID "7cb63eed597130ba4abb87b3e544b85021905520"
+
+static git_repository *repo;
+static git_index *repo_index;
+
+static void test_drivers_register(void);
+static void test_drivers_unregister(void);
+
+void test_merge_driver__initialize(void)
+{
+ git_config *cfg;
+
+ repo = cl_git_sandbox_init(TEST_REPO_PATH);
+ git_repository_index(&repo_index, repo);
+
+ /* Ensure that the user's merge.conflictstyle doesn't interfere */
+ cl_git_pass(git_repository_config(&cfg, repo));
+
+ cl_git_pass(git_config_set_string(cfg, "merge.conflictstyle", "merge"));
+ cl_git_pass(git_config_set_bool(cfg, "core.autocrlf", false));
+
+ test_drivers_register();
+
+ git_config_free(cfg);
+}
+
+void test_merge_driver__cleanup(void)
+{
+ test_drivers_unregister();
+
+ git_index_free(repo_index);
+ cl_git_sandbox_cleanup();
+}
+
+struct test_merge_driver {
+ git_merge_driver base;
+ int initialized;
+ int shutdown;
+};
+
+static int test_driver_init(git_merge_driver *s)
+{
+ struct test_merge_driver *self = (struct test_merge_driver *)s;
+ self->initialized = 1;
+ return 0;
+}
+
+static void test_driver_shutdown(git_merge_driver *s)
+{
+ struct test_merge_driver *self = (struct test_merge_driver *)s;
+ self->shutdown = 1;
+}
+
+static int test_driver_check(
+ git_merge_driver *s,
+ void **payload,
+ const char *name,
+ const git_merge_driver_source *src)
+{
+ GIT_UNUSED(s);
+ GIT_UNUSED(src);
+
+ *payload = git__strdup(name);
+ GITERR_CHECK_ALLOC(*payload);
+
+ return 0;
+}
+
+static int test_driver_apply(
+ git_merge_driver *s,
+ void **payload,
+ const char **path_out,
+ uint32_t *mode_out,
+ git_buf *merged_out,
+ const git_merge_driver_source *src)
+{
+ GIT_UNUSED(s);
+ GIT_UNUSED(src);
+
+ *path_out = "applied.txt";
+ *mode_out = GIT_FILEMODE_BLOB;
+
+ return git_buf_printf(merged_out, "This is the `%s` driver.\n",
+ (char *)*payload);
+}
+
+static void test_driver_cleanup(git_merge_driver *s, void *payload)
+{
+ GIT_UNUSED(s);
+
+ git__free(payload);
+}
+
+
+static struct test_merge_driver test_driver_custom = {
+ {
+ GIT_MERGE_DRIVER_VERSION,
+ test_driver_init,
+ test_driver_shutdown,
+ test_driver_check,
+ test_driver_apply,
+ test_driver_cleanup
+ },
+ 0,
+ 0,
+};
+
+static struct test_merge_driver test_driver_wildcard = {
+ {
+ GIT_MERGE_DRIVER_VERSION,
+ test_driver_init,
+ test_driver_shutdown,
+ test_driver_check,
+ test_driver_apply,
+ test_driver_cleanup
+ },
+ 0,
+ 0,
+};
+
+static void test_drivers_register(void)
+{
+ cl_git_pass(git_merge_driver_register("custom", &test_driver_custom.base));
+ cl_git_pass(git_merge_driver_register("*", &test_driver_wildcard.base));
+}
+
+static void test_drivers_unregister(void)
+{
+ cl_git_pass(git_merge_driver_unregister("custom"));
+ cl_git_pass(git_merge_driver_unregister("*"));
+}
+
+static void set_gitattributes_to(const char *driver)
+{
+ git_buf line = GIT_BUF_INIT;
+
+ cl_git_pass(git_buf_printf(&line, "automergeable.txt merge=%s\n", driver));
+ cl_git_mkfile(TEST_REPO_PATH "/.gitattributes", line.ptr);
+ git_buf_free(&line);
+}
+
+static void merge_branch(void)
+{
+ git_oid their_id;
+ git_annotated_commit *their_head;
+
+ cl_git_pass(git_oid_fromstr(&their_id, BRANCH_ID));
+ cl_git_pass(git_annotated_commit_lookup(&their_head, repo, &their_id));
+
+ cl_git_pass(git_merge(repo, (const git_annotated_commit **)&their_head,
+ 1, NULL, NULL));
+
+ git_annotated_commit_free(their_head);
+}
+
+void test_merge_driver__custom(void)
+{
+ const char *expected = "This is the `custom` driver.\n";
+ set_gitattributes_to("custom");
+ merge_branch();
+
+ cl_assert_equal_file(expected, strlen(expected),
+ TEST_REPO_PATH "/applied.txt");
+}
+
+void test_merge_driver__wildcard(void)
+{
+ const char *expected = "This is the `foobar` driver.\n";
+ set_gitattributes_to("foobar");
+ merge_branch();
+
+ cl_assert_equal_file(expected, strlen(expected),
+ TEST_REPO_PATH "/applied.txt");
+}
+
+void test_merge_driver__shutdown_is_called(void)
+{
+ test_driver_custom.initialized = 0;
+ test_driver_custom.shutdown = 0;
+ test_driver_wildcard.initialized = 0;
+ test_driver_wildcard.shutdown = 0;
+
+ /* run the merge with the custom driver */
+ set_gitattributes_to("custom");
+ merge_branch();
+
+ /* unregister the drivers, ensure their shutdown function is called */
+ test_drivers_unregister();
+
+ /* since the `custom` driver was used, it should have been initialized and
+ * shutdown, but the wildcard driver was not used at all and should not
+ * have been initialized or shutdown.
+ */
+ cl_assert(test_driver_custom.initialized);
+ cl_assert(test_driver_custom.shutdown);
+ cl_assert(!test_driver_wildcard.initialized);
+ cl_assert(!test_driver_wildcard.shutdown);
+
+ test_drivers_register();
+}
+