summaryrefslogtreecommitdiffstats
path: root/src/merge.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/merge.c')
-rw-r--r--src/merge.c69
1 files changed, 52 insertions, 17 deletions
diff --git a/src/merge.c b/src/merge.c
index aef3f8f..059523e 100644
--- a/src/merge.c
+++ b/src/merge.c
@@ -7,6 +7,8 @@
#include "md5util.h"
#include "diff.h"
#include "dbutil.h"
+#include "package.h"
+#include "util.h"
struct cb_info {
struct syrep_db_context *c1;
@@ -14,8 +16,10 @@ struct cb_info {
const char *root;
};
-int conflict_phase(DB *ddb, struct syrep_name *name, struct diff_entry *de, void *p) {
+static int conflict_phase(DB *ddb, struct syrep_name *name, struct diff_entry *de, void *p) {
struct cb_info *cb_info = p;
+ struct syrep_md md1, md2;
+ int f1, f2;
char path[PATH_MAX+1];
assert(ddb && name && de && p);
@@ -23,13 +27,34 @@ int conflict_phase(DB *ddb, struct syrep_name *name, struct diff_entry *de, void
if (de->action != DIFF_CONFLICT)
return 0;
+ if ((f1 = get_current_md_by_name(cb_info->c1, name, &md1)) < 0)
+ return -1;
+
+ if ((f2 = get_current_md_by_name(cb_info->c2, name, &md2)) < 0)
+ return -1;
+
snprintf(path, sizeof(path), "%s/%s", cb_info->root, name->path);
- fprintf(stderr, "QUERY %s\n", path);
+ if (f1 && f2) {
+ char d1[SYREP_DIGESTLENGTH*2+1], d2[SYREP_DIGESTLENGTH*2+1];
+
+ fhex(md1.digest, SYREP_DIGESTLENGTH, d1);
+ fhex(md2.digest, SYREP_DIGESTLENGTH, d2);
+ d1[SYREP_DIGESTLENGTH*2] = d2[SYREP_DIGESTLENGTH*2] = 0;
+
+ fprintf(stderr, "CONFLICT: New file '%s' apparead: %s in A vs. %s in B\n", path, d1, d2);
+ } else if (f1 || f2) {
+ char d[SYREP_DIGESTLENGTH*2+1];
+ fhex(f1 ? md1.digest : md2.digest, SYREP_DIGESTLENGTH, d);
+ d[SYREP_DIGESTLENGTH*2] = 0;
+
+ fprintf(stderr, "CONFLICT: File '%s' (%s) appeared in %c, removed in %c\n", path, d, f1 ? 'A' : 'B', f2 ? 'A' : 'B');
+ }
+
return 0;
}
-int copy_phase(DB *ddb, struct syrep_name *name, struct diff_entry *de, void *p) {
+static int copy_phase(DB *ddb, struct syrep_name *name, struct diff_entry *de, void *p) {
struct cb_info *cb_info = p;
struct syrep_name name2;
struct syrep_md md;
@@ -50,7 +75,6 @@ int copy_phase(DB *ddb, struct syrep_name *name, struct diff_entry *de, void *p)
if ((f = get_current_md_by_name(cb_info->c1, name, &md)) < 0)
return -1;
-
if (!f) {
fprintf(stderr, "Diff invalid!\n");
return -1;
@@ -59,26 +83,33 @@ int copy_phase(DB *ddb, struct syrep_name *name, struct diff_entry *de, void *p)
fhex(md.digest, SYREP_DIGESTLENGTH, d);
d[SYREP_DIGESTLENGTH*2] = 0;
- fprintf(stderr, "Searching for %s\n", d);
-
if ((f = get_current_name_by_md(cb_info->c2, &md, &name2)) < 0)
return -1;
if (f) {
char path2[PATH_MAX+1];
snprintf(path2, sizeof(path2), "%s/%s", cb_info->root, name2.path);
- fprintf(stderr, "Linking file <%s> to <%s>\n", path2, path);
- if (link(path2, path) < 0) {
- fprintf(stderr, "Failed to link: %s\n", strerror(errno));
+ fprintf(stderr, "COPY: Linking existing file <%s> to <%s>.\n", path2, path);
+
+ if (copy_or_link_file(path2, path) < 0)
return -1;
- }
- } else
- fprintf(stderr, "MISSING FILE %s\n", path);
+
+ } else {
+ const char* a;
+
+ if ((a = package_get_item(cb_info->c1->package, d, 0))) {
+ fprintf(stderr, "COPY: Copying file <%s> from patch.\n", path);
+
+ if (copy_or_link_file(a, path) < 0)
+ return -1;
+ } else
+ fprintf(stderr, "COPY: File <%s> is missing.\n", path);
+ }
return 0;
}
-int delete_phase(DB *ddb, struct syrep_name *name, struct diff_entry *de, void *p) {
+static int delete_phase(DB *ddb, struct syrep_name *name, struct diff_entry *de, void *p) {
struct cb_info *cb_info = p;
char path[PATH_MAX+1];
@@ -91,10 +122,11 @@ int delete_phase(DB *ddb, struct syrep_name *name, struct diff_entry *de, void *
return 0;
snprintf(path, sizeof(path), "%s/%s", cb_info->root, name->path);
- fprintf(stderr, "Deleting file <%s>\n", path);
+
+ fprintf(stderr, "DELETE: Deleting file <%s>\n", path);
if (unlink(path) < 0) {
- fprintf(stderr, "Failed to unlink: %s\n", strerror(errno));
+ fprintf(stderr, "unlink(%s): %s\n", path, strerror(errno));
return -1;
}
@@ -102,9 +134,10 @@ int delete_phase(DB *ddb, struct syrep_name *name, struct diff_entry *de, void *
}
/* Merges c1 into c2 in directory "root" */
-int merge_snapshot(struct syrep_db_context *c1, struct syrep_db_context *c2, const char* root) {
+int merge(struct syrep_db_context *c1, struct syrep_db_context *c2, const char* root) {
struct cb_info cb_info;
DB *ddb = NULL;
+ int r = -1;
memset(&cb_info, 0, sizeof(cb_info));
cb_info.c1 = c1;
@@ -122,11 +155,13 @@ int merge_snapshot(struct syrep_db_context *c1, struct syrep_db_context *c2, con
if (diff_foreach(ddb, delete_phase, &cb_info) < 0)
goto finish;
+
+ r = 0;
finish:
if (ddb)
ddb->close(ddb, 0);
- return 0;
+ return r;
}