diff options
Diffstat (limited to 'src/merge.c')
-rw-r--r-- | src/merge.c | 69 |
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; } |