Change how diff works
This commit is contained in:
9
.gitignore
vendored
9
.gitignore
vendored
@@ -1,5 +1,6 @@
|
|||||||
sample/
|
sample
|
||||||
.vscode/
|
.vscode
|
||||||
.cgit/
|
.cgit
|
||||||
build/
|
build
|
||||||
*.out
|
*.out
|
||||||
|
.git
|
||||||
122
src/commit.c
122
src/commit.c
@@ -149,109 +149,27 @@ int commit()
|
|||||||
save_index(&index);
|
save_index(&index);
|
||||||
}
|
}
|
||||||
|
|
||||||
int diff_blob(char *filename, struct object *a, struct object *b)
|
void diff_commit_with_working_tree(struct commit *commit)
|
||||||
{
|
{
|
||||||
char a_path[7 + strlen(filename)], b_path[7 + strlen(filename)];
|
struct object obj = {0};
|
||||||
sprintf(a_path, "/tmp/a%s", filename);
|
read_object(commit->tree, &obj);
|
||||||
sprintf(b_path, "/tmp/b%s", filename);
|
|
||||||
|
|
||||||
tmp_dump(a, a_path);
|
struct tree commit_tree = {0};
|
||||||
tmp_dump(b, b_path);
|
get_tree(obj.content, &commit_tree);
|
||||||
|
|
||||||
char cmd[1000];
|
rmdir(TMP"/a");
|
||||||
FILE *f;
|
create_dir(TMP"/a");
|
||||||
|
|
||||||
snprintf(cmd, sizeof(cmd), "diff -u %s %s", a_path, b_path);
|
dump_tree(TMP"/a", &commit_tree);
|
||||||
f = popen(cmd, "w");
|
|
||||||
pclose(f);
|
|
||||||
}
|
|
||||||
|
|
||||||
int diff_tree(char *cwd, struct tree *tree_a, struct tree *tree_b)
|
FILE *p = popen("diff -ruN --exclude-from=.gitignore "TMP"/a ./ > "LOCAL_REPO"/diff", "w");
|
||||||
{
|
pclose(p);
|
||||||
struct entry *current_a = NULL, *current_b = NULL;
|
|
||||||
if (tree_a == NULL)
|
|
||||||
current_a = NULL;
|
|
||||||
else
|
|
||||||
current_a = tree_a->first_entry;
|
|
||||||
|
|
||||||
if (tree_b == NULL)
|
p = popen("cat "LOCAL_REPO"/diff", "w");
|
||||||
current_b = NULL;
|
pclose(p);
|
||||||
else
|
|
||||||
current_b = tree_b->first_entry;
|
|
||||||
|
|
||||||
while(current_a != NULL || current_b != NULL)
|
free_tree(&commit_tree);
|
||||||
{
|
free_object(&obj);
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void diff_commit(struct commit *commit_a, struct commit *commit_b)
|
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_a.content, &tree_a);
|
||||||
get_tree(tree_obj_b.content, &tree_b);
|
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_a);
|
||||||
free_tree(&tree_b);
|
free_tree(&tree_b);
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
int commit_from_object(struct commit *commit, struct object *object);
|
int commit_from_object(struct commit *commit, struct object *object);
|
||||||
void free_commit(struct commit *commit);
|
void free_commit(struct commit *commit);
|
||||||
void diff_commit(struct commit *commit_a, struct commit *commit_b);
|
void diff_commit(struct commit *commit_a, struct commit *commit_b);
|
||||||
|
void diff_commit_with_working_tree(struct commit *commit);
|
||||||
int commit();
|
int commit();
|
||||||
|
|
||||||
#endif // COMMIT_H
|
#endif // COMMIT_H
|
||||||
58
src/fs.c
58
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 init_tmp_diff_dir(char* dir)
|
||||||
{
|
{
|
||||||
int dirlen = 0;
|
int dirlen = 0;
|
||||||
@@ -247,6 +256,41 @@ int tmp_dump(struct object *obj, char* filename)
|
|||||||
return FS_OK;
|
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)
|
int load_tree(char* checksum, struct tree *tree)
|
||||||
{
|
{
|
||||||
struct object object;
|
struct object object;
|
||||||
@@ -421,22 +465,20 @@ int new_branch(char* branch_name)
|
|||||||
return FS_OK;
|
return FS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int restore_tree();
|
|
||||||
|
|
||||||
int revert(char* commit_checksum)
|
int revert(char* commit_checksum)
|
||||||
{
|
{
|
||||||
struct object commit_obj = {0};
|
struct object obj = {0};
|
||||||
read_object(commit_checksum, &commit_obj);
|
read_object(commit_checksum, &obj);
|
||||||
|
|
||||||
if(commit_obj.object_type != COMMIT)
|
if(obj.object_type != COMMIT)
|
||||||
return WRONG_OBJECT_TYPE;
|
return WRONG_OBJECT_TYPE;
|
||||||
|
|
||||||
struct commit commit = {0};
|
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_commit(&commit);
|
||||||
free_object(&commit_obj);
|
free_object(&obj);
|
||||||
return FS_OK;
|
return FS_OK;
|
||||||
}
|
}
|
||||||
3
src/fs.h
3
src/fs.h
@@ -42,4 +42,7 @@ int tmp_dump(struct object *obj, char* filename);
|
|||||||
int init_tmp_diff_dir(char* dir);
|
int init_tmp_diff_dir(char* dir);
|
||||||
int new_branch(char* branch_name);
|
int new_branch(char* branch_name);
|
||||||
|
|
||||||
|
int create_dir(char *dir);
|
||||||
|
int dump_tree(char *cwd, struct tree *tree);
|
||||||
|
|
||||||
#endif // FS_H
|
#endif // FS_H
|
||||||
|
|||||||
18
src/main.c
18
src/main.c
@@ -17,20 +17,30 @@
|
|||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
|
|
||||||
// debug_print("master: %i", branch_exist("master"));
|
|
||||||
// debug_print("main: %i", branch_exist("main"));
|
|
||||||
// struct tree index = {0};
|
// struct tree index = {0};
|
||||||
// load_index(&index);
|
// load_index(&index);
|
||||||
|
|
||||||
// add_to_index(&index, "src/commit.c");
|
// add_to_index(&index, "src/commit.c");
|
||||||
// add_to_index(&index, "src/commit.h");
|
// add_to_index(&index, "src/commit.h");
|
||||||
|
// add_to_index(&index, "src/fs.c");
|
||||||
|
// add_to_index(&index, "src/fs.h");
|
||||||
|
|
||||||
// save_index(&index);
|
// save_index(&index);
|
||||||
|
|
||||||
// commit();
|
// 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;
|
return 0;
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user