From bd48b0829410c50c357ade211a54b5114339f27e Mon Sep 17 00:00:00 2001 From: Antonin Ruan Date: Mon, 3 Jun 2024 13:45:02 +0200 Subject: [PATCH] Change how diff works --- .gitignore | 11 ++--- src/commit.c | 124 +++++++++++---------------------------------------- src/commit.h | 1 + src/fs.c | 58 ++++++++++++++++++++---- src/fs.h | 3 ++ src/main.c | 18 ++++++-- 6 files changed, 100 insertions(+), 115 deletions(-) diff --git a/.gitignore b/.gitignore index 66959b1..5095925 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ -sample/ -.vscode/ -.cgit/ -build/ -*.out \ No newline at end of file +sample +.vscode +.cgit +build +*.out +.git \ No newline at end of file diff --git a/src/commit.c b/src/commit.c index e54183d..d1f0d9d 100644 --- a/src/commit.c +++ b/src/commit.c @@ -149,109 +149,27 @@ int commit() save_index(&index); } -int diff_blob(char *filename, struct object *a, struct object *b) -{ - char a_path[7 + strlen(filename)], b_path[7 + strlen(filename)]; - sprintf(a_path, "/tmp/a%s", filename); - sprintf(b_path, "/tmp/b%s", filename); +void diff_commit_with_working_tree(struct commit *commit) +{ + struct object obj = {0}; + read_object(commit->tree, &obj); - tmp_dump(a, a_path); - tmp_dump(b, b_path); + struct tree commit_tree = {0}; + get_tree(obj.content, &commit_tree); - char cmd[1000]; - FILE *f; + rmdir(TMP"/a"); + create_dir(TMP"/a"); - snprintf(cmd, sizeof(cmd), "diff -u %s %s", a_path, b_path); - f = popen(cmd, "w"); - pclose(f); -} + dump_tree(TMP"/a", &commit_tree); -int diff_tree(char *cwd, struct tree *tree_a, struct tree *tree_b) -{ - struct entry *current_a = NULL, *current_b = NULL; - if (tree_a == NULL) - current_a = NULL; - else - current_a = tree_a->first_entry; + FILE *p = popen("diff -ruN --exclude-from=.gitignore "TMP"/a ./ > "LOCAL_REPO"/diff", "w"); + pclose(p); - if (tree_b == NULL) - current_b = NULL; - else - current_b = tree_b->first_entry; - - while(current_a != NULL || current_b != NULL) - { - int res = 0; - if (current_a == NULL) - { - res = 1; - } else if (current_b == NULL) - { - res = -1; - } else { - res = strcmp(current_a->filename, current_b->filename); - } - size_t cwd_len = 0; - if (*cwd != '\0') - cwd_len = strlen(cwd); - size_t filename_size = cwd_len + 1; - char *filename = calloc(1, filename_size); - strncpy(filename, cwd, filename_size); - struct object a = {0}, b = {0}; - enum object_type type; - if (res == 0) - { - read_object(current_a->checksum, &a); - read_object(current_b->checksum, &b); - if (current_a->type != current_b->type) - return WRONG_OBJECT_TYPE; - filename_size += strlen(current_a->filename) + 1; - filename = realloc(filename, filename_size); - strcat(filename, "/"); - strncat(filename, current_a->filename, strlen(current_a->filename)); - type = current_a->type; - current_a = current_a->next; - current_b = current_b->next; - } else if (res < 0) - { - read_object(current_a->checksum, &a); - filename_size += strlen(current_a->filename) + 1; - filename = realloc(filename, filename_size); - strcat(filename, "/"); - strncat(filename, current_a->filename, strlen(current_a->filename)); - type = current_a->type; - current_a = current_a->next; - } else - { - read_object(current_b->checksum, &b); - filename_size += strlen(current_b->filename) + 1; - filename = realloc(filename, filename_size); - strcat(filename, "/"); - strncat(filename, current_b->filename, strlen(current_b->filename)); - type = current_b->type; - current_b = current_b->next; - } + p = popen("cat "LOCAL_REPO"/diff", "w"); + pclose(p); - if (type == BLOB) - diff_blob(filename, &a, &b); - else if (type == TREE) - { - struct tree subtree_a = {0}, subtree_b = {0}; - if (res <= 0) - get_tree(a.content, &subtree_a); - - if (res >= 0) - get_tree(b.content, &subtree_b); - - init_tmp_diff_dir(filename); - diff_tree(filename, &subtree_a, &subtree_b); - free_tree(&subtree_a); - free_tree(&subtree_b); - } - free(filename); - free_object(&a); - free_object(&b); - } + free_tree(&commit_tree); + free_object(&obj); } void diff_commit(struct commit *commit_a, struct commit *commit_b) @@ -264,7 +182,17 @@ void diff_commit(struct commit *commit_a, struct commit *commit_b) get_tree(tree_obj_a.content, &tree_a); get_tree(tree_obj_b.content, &tree_b); - diff_tree("", &tree_a, &tree_b); + rmdir(TMP"/a"); + rmdir(TMP"/b"); + + create_dir(TMP"/a"); + create_dir(TMP"/b"); + + dump_tree(TMP"/a", &tree_a); + dump_tree(TMP"/b", &tree_b); + + FILE *f = popen("diff -ruN "TMP"/a "TMP"/b ", "w"); + pclose(f); free_tree(&tree_a); free_tree(&tree_b); diff --git a/src/commit.h b/src/commit.h index f2ce620..a02b916 100644 --- a/src/commit.h +++ b/src/commit.h @@ -6,6 +6,7 @@ int commit_from_object(struct commit *commit, struct object *object); void free_commit(struct commit *commit); void diff_commit(struct commit *commit_a, struct commit *commit_b); +void diff_commit_with_working_tree(struct commit *commit); int commit(); #endif // COMMIT_H \ No newline at end of file diff --git a/src/fs.c b/src/fs.c index 2595058..6309705 100644 --- a/src/fs.c +++ b/src/fs.c @@ -214,6 +214,15 @@ int create_dir(char *dir) } } +void remove_dir(char *dir) +{ + char cmd[strlen(dir) + strlen("rm -rf ") + 1]; + sprintf(cmd, "rm -rf %s", dir); + + FILE *p = popen(cmd, "r"); + pclose(p); +} + int init_tmp_diff_dir(char* dir) { int dirlen = 0; @@ -247,6 +256,41 @@ int tmp_dump(struct object *obj, char* filename) return FS_OK; } +int dump_tree(char *cwd, struct tree *tree) +{ + struct entry *current = tree->first_entry; + while(current != NULL) + { + size_t cwd_len = 0; + if (*cwd != '\0') + cwd_len = strlen(cwd); + size_t filename_size = cwd_len + 2 + strlen(current->filename); + char filename[filename_size]; + sprintf(filename, "%s/%s", cwd, current->filename); + + struct object obj = {0}; + read_object(current->checksum, &obj); + + if(current->type == BLOB) + { + tmp_dump(&obj, filename); + } else if (current->type == TREE) { + struct tree subtree = {0}; + get_tree(obj.content, &subtree); + + create_dir(filename); + dump_tree(filename, &subtree); + + free_tree(&subtree); + } + + free_object(&obj); + current = current->next; + } + + return FS_OK; +} + int load_tree(char* checksum, struct tree *tree) { struct object object; @@ -421,22 +465,20 @@ int new_branch(char* branch_name) return FS_OK; } -int restore_tree(); - int revert(char* commit_checksum) { - struct object commit_obj = {0}; - read_object(commit_checksum, &commit_obj); + struct object obj = {0}; + read_object(commit_checksum, &obj); - if(commit_obj.object_type != COMMIT) + if(obj.object_type != COMMIT) return WRONG_OBJECT_TYPE; struct commit commit = {0}; - commit_from_object(&commit, &commit_obj); - + commit_from_object(&commit, &obj); + diff_commit_with_working_tree(&commit); free_commit(&commit); - free_object(&commit_obj); + free_object(&obj); return FS_OK; } \ No newline at end of file diff --git a/src/fs.h b/src/fs.h index 0ea7afa..efa65cb 100644 --- a/src/fs.h +++ b/src/fs.h @@ -42,4 +42,7 @@ int tmp_dump(struct object *obj, char* filename); int init_tmp_diff_dir(char* dir); int new_branch(char* branch_name); +int create_dir(char *dir); +int dump_tree(char *cwd, struct tree *tree); + #endif // FS_H diff --git a/src/main.c b/src/main.c index fb0626b..4ed1f8a 100644 --- a/src/main.c +++ b/src/main.c @@ -17,20 +17,30 @@ int main(int argc, char** argv) { - - // debug_print("master: %i", branch_exist("master")); - // debug_print("main: %i", branch_exist("main")); // struct tree index = {0}; // load_index(&index); // add_to_index(&index, "src/commit.c"); // add_to_index(&index, "src/commit.h"); + // add_to_index(&index, "src/fs.c"); + // add_to_index(&index, "src/fs.h"); // save_index(&index); // commit(); - new_branch("new_feature"); + struct object a = {0}, b = {0}; + read_object("083fec39f677b81de863cb0b8575ac76e87b7bff", &a); + read_object("fb5d38457520619b6e2f3b162c2a21a22b531cb4", &b); + + struct commit c_a, c_b; + commit_from_object(&c_a, &a); + commit_from_object(&c_b, &b); + + diff_commit_with_working_tree(&c_b); + + free_object(&a); + free_object(&b); return 0; } \ No newline at end of file