commit 38e627ae5e6913749226f9a30d99bcfd5b3820fb
parent caf27eab05b07fdd04ee621cbf0041783bad2f6b
Author: Mohamed Aslan <maslan@sce.carleton.ca>
Date: Sat, 4 Oct 2014 19:57:32 -0600
add support for recursive diff of files in cmd-diff
Diffstat:
M | cmd-diff.c | | | 193 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------- |
1 file changed, 146 insertions(+), 47 deletions(-)
diff --git a/cmd-diff.c b/cmd-diff.c
@@ -138,14 +138,15 @@ ext_diff_proc(struct session *s, struct dirent *ent, char *fifo)
}
static void
-ext_diff(struct session *s, const char *tmpdir, struct dirent *ent1, struct dirent *ent2)
+ext_diff(struct session *s, const char *tmpdir, struct dirent *ent1, struct dirent *ent2, const char *path)
{
char *dir;
char *label1, *label2;
char *fifo1 = NULL, *fifo2 = NULL;
pid_t pid1, pid2;
-
+ label1 = NULL;
+ label2 = NULL;
if (ent1 == NULL && ent2 == NULL)
return;
@@ -153,15 +154,20 @@ ext_diff(struct session *s, const char *tmpdir, struct dirent *ent1, struct dire
asprintf(&dir, "%s/old", tmpdir);
fifo1 = make_fifo(dir, ent1->name);
free(dir);
+ if (strlen(path) > 0)
+ asprintf(&label1, "%s/%s", path, ent1->name);
+ else
+ asprintf(&label1, "%s", ent1->name);
}
if(ent2 != NULL) {
asprintf(&dir, "%s/new", tmpdir);
fifo2 = make_fifo(dir, ent2->name);
free(dir);
+ if (strlen(path) > 0)
+ asprintf(&label2, "%s/%s", path, ent2->name);
+ else
+ asprintf(&label2, "%s", ent2->name);
}
- /* FIXME */
- label1 = fifo1;
- label2 = fifo2;
pid1 = fork();
if (pid1 < 0) {
@@ -198,6 +204,139 @@ ext_diff(struct session *s, const char *tmpdir, struct dirent *ent1, struct dire
free(fifo2);
}
+
+static void
+diff_r(struct session *s, struct dir *d1, struct dir *d2, const char *p)
+{
+ char *tmpdir = NULL;
+ char *pnext = NULL;
+ struct dir *child1, *child2;
+ struct dirent *ent1 = NULL, *ent2 = NULL;
+
+ tmpdir = make_tmpdir();
+
+ if (d1 != NULL)
+ ent1 = d1->children;
+ if (d2 != NULL)
+ ent2 = d2->children;
+ if (p == NULL)
+ return;
+ if (*p == '/')
+ p++;
+ while (1) {
+ if (ent1 == NULL && ent2 == NULL)
+ break;
+ else if (ent1 == NULL) {
+ /* +++ ent2 */
+ if (S_ISREG(ent2->mode))
+ ext_diff(s, tmpdir, NULL, ent2, p);
+ else if (S_ISDIR(ent2->mode)) {
+ asprintf(&pnext, "%s/%s", p, ent2->name);
+ child2 = baseline_dir_new();
+ s->db_ops->select_dir(s->db_ctx, ent2->id, child2);
+ diff_r(s, NULL, child2, pnext);
+ baseline_dir_free(child2);
+ free(pnext);
+ }
+ else
+ errx(EXIT_FAILURE, "error, file mode not supported.");
+ ent2 = ent2->next;
+ }
+ else if (ent2 == NULL) {
+ /* --- ent1 */
+ if (S_ISREG(ent1->mode))
+ ext_diff(s, tmpdir, ent1, NULL, p);
+ else if (S_ISDIR(ent1->mode)) {
+ asprintf(&pnext, "%s/%s", p, ent1->name);
+ child1 = baseline_dir_new();
+ s->db_ops->select_dir(s->db_ctx, ent1->id, child1);
+ diff_r(s, child1, NULL, pnext);
+ baseline_dir_free(child1);
+ free(pnext);
+ }
+ else
+ errx(EXIT_FAILURE, "error, file mode not supported.");
+ ent1 = ent1->next;
+ }
+ else if (!strcmp(ent1->name, ent2->name)) {
+ if (strcmp(ent1->id, ent2->id)) {
+ /* *** ent1 & ent2 */
+ if (S_ISREG(ent1->mode) && S_ISREG(ent2->mode))
+ ext_diff(s, tmpdir, ent1, ent2, p);
+ else if (S_ISREG(ent1->mode) && S_ISDIR(ent2->mode)) {
+ /* delete old file */
+ ext_diff(s, tmpdir, ent1, NULL, p);
+ /* add new dir */
+ asprintf(&pnext, "%s/%s", p, ent2->name);
+ child2 = baseline_dir_new();
+ s->db_ops->select_dir(s->db_ctx, ent2->id, child2);
+ diff_r(s, NULL, child2, pnext);
+ baseline_dir_free(child2);
+ free(pnext);
+ }
+ else if (S_ISDIR(ent1->mode) && S_ISREG(ent2->mode)) {
+ /* delete old dir */
+ asprintf(&pnext, "%s/%s", p, ent1->name);
+ child1 = baseline_dir_new();
+ s->db_ops->select_dir(s->db_ctx, ent1->id, child1);
+ diff_r(s, child1, NULL, pnext);
+ baseline_dir_free(child1);
+ free(pnext);
+ /* add new file */
+ ext_diff(s, tmpdir, NULL, ent2, p);
+ }
+ else if (S_ISDIR(ent1->mode) && S_ISDIR(ent2->mode)) {
+ asprintf(&pnext, "%s/%s", p, ent1->name);
+ child1 = baseline_dir_new();
+ child2 = baseline_dir_new();
+ s->db_ops->select_dir(s->db_ctx, ent1->id, child1);
+ s->db_ops->select_dir(s->db_ctx, ent2->id, child2);
+ diff_r(s, child1, child2, pnext);
+ baseline_dir_free(child1);
+ baseline_dir_free(child2);
+ free(pnext);
+ }
+ else
+ errx(EXIT_FAILURE, "error, file mode not supported.");
+ }
+ ent1 = ent1->next;
+ ent2 = ent2->next;
+ }
+ else if (strcmp(ent1->name, ent2->name) < 0) {
+ /* --- ent1 */
+ if (S_ISREG(ent1->mode))
+ ext_diff(s, tmpdir, ent1, NULL, p);
+ else if (S_ISDIR(ent1->mode)) {
+ asprintf(&pnext, "%s/%s", p, ent1->name);
+ child1 = baseline_dir_new();
+ s->db_ops->select_dir(s->db_ctx, ent1->id, child1);
+ diff_r(s, child1, NULL, pnext);
+ baseline_dir_free(child1);
+ free(pnext);
+ }
+ else
+ errx(EXIT_FAILURE, "error, file mode not supported.");
+ ent1 = ent1->next;
+ }
+ else if (strcmp(ent1->name, ent2->name) > 0) {
+ /* +++ ent2 */
+ if (S_ISREG(ent2->mode))
+ ext_diff(s, tmpdir, NULL, ent2, p);
+ else if (S_ISDIR(ent2->mode)) {
+ asprintf(&pnext, "%s/%s", p, ent2->name);
+ child2 = baseline_dir_new();
+ s->db_ops->select_dir(s->db_ctx, ent2->id, child2);
+ diff_r(s, NULL, child2, pnext);
+ baseline_dir_free(child2);
+ free(pnext);
+ }
+ else
+ errx(EXIT_FAILURE, "error, file mode not supported.");
+ ent2 = ent2->next;
+ }
+ }
+}
+
int
cmd_diff(int argc, char **argv)
{
@@ -206,7 +345,6 @@ cmd_diff(int argc, char **argv)
struct session s;
struct commit *comm_old, *comm_new;
struct dir *dir_old, *dir_new;
- struct dirent *ent_old, *ent_new;
if (argc != 3) {
errx(EXIT_FAILURE, "wrong number of arguments (%d)\n", argc);
@@ -216,7 +354,7 @@ cmd_diff(int argc, char **argv)
baseline_session_begin(&s, 0);
- tmpdir = make_tmpdir();
+ //tmpdir = make_tmpdir();
/*
s.db_ops->branch_get_head(s.db_ctx, s.branch, &head);
@@ -236,46 +374,7 @@ cmd_diff(int argc, char **argv)
dir_new = baseline_dir_new();
s.db_ops->select_dir(s.db_ctx, comm_new->dir, dir_new);
- ent_old = dir_old->children;
- ent_new = dir_new->children;
- while (1) {
- if (ent_old == NULL && ent_new == NULL)
- break;
- else if (ent_old == NULL) {
- /* printf("+++ %s\n", ent_new->name); */
- ext_diff(&s, tmpdir, NULL, ent_new);
- ent_new = ent_new->next;
- }
- else if (ent_new == NULL) {
- /* printf("--- %s\n", ent_old->name); */
- ext_diff(&s, tmpdir, ent_old, NULL);
- ent_old = ent_old->next;
- }
- else if (!strcmp(ent_old->name, ent_new->name)) {
- if (strcmp(ent_old->id, ent_new->id)) {
- /* printf("*** %s\n", ent_old->name); */
- ext_diff(&s, tmpdir, ent_old, ent_new);
- }
- ent_old = ent_old->next;
- ent_new = ent_new->next;
- }
- else if (strcmp(ent_old->name, ent_new->name) < 0) {
- /* printf("--- %s\n", ent_old->name); */
- ext_diff(&s, tmpdir, ent_old, NULL);
- ent_old = ent_old->next;
- }
- else if (strcmp(ent_old->name, ent_new->name) > 0) {
- /* printf("+++ %s\n", ent_new->name); */
- ext_diff(&s, tmpdir, NULL, ent_new);
- ent_new = ent_new->next;
- }
- /*
- if (S_ISDIR(ent->mode))
- printf("%s/\n", ent->name);
- else
- printf("%s\n", ent->name);
- */
- }
+ diff_r(&s, dir_old, dir_new, "");
baseline_dir_free(dir_old);
baseline_dir_free(dir_new);