diff --git a/include/object.h b/include/object.h index 655d22d..7e92fa4 100644 --- a/include/object.h +++ b/include/object.h @@ -28,9 +28,9 @@ char* get_object(char*, size_t*); void* parse_object(char*, ObjectType, size_t*, char*); -int save_diff(ActionList*, char*, char*, size_t, char*, File*, int); +int save_diff(ActionList*, char*, char*, size_t, char*); int read_diff(char*, char*, ActionList*); int save_file_diff(char*, char*, size_t, char*, ActionList*); File* apply_diff(File*, ActionList*); -#endif // OBJECT_H \ No newline at end of file +#endif // OBJECT_H diff --git a/include/tree.h b/include/tree.h index ac50552..aa48e7a 100644 --- a/include/tree.h +++ b/include/tree.h @@ -15,6 +15,5 @@ #define IS_PUNCT(c) ((c >= 33 && c <= 47) || (c >= 58 && c <= 64) || (c >= 91 && c <= 96) || (c >= 123 && c <= 126)) void snapshot_tree(FileInfoBuffer*, char*); -int save_tree_diff(FileInfoBuffer*, char*, char*, size_t, char*, char*); int read_tree(FileInfoBuffer*, char*); #endif // TREE_H diff --git a/src/main.c b/src/main.c index 3cecdde..93df2e4 100644 --- a/src/main.c +++ b/src/main.c @@ -571,7 +571,7 @@ static int commit(int argc, char** argv) { continue; } else { - save_diff(diff, files->items[idx], root, base_file->diff_num, base_file_hash, NULL, 0); + save_diff(diff, files->items[idx], root, base_file->diff_num, base_file_hash); char diff_hash[41]; char id[2 + snprintf(NULL, 0, "%lu", base_file->diff_num) + strlen(files->items[idx])]; @@ -608,7 +608,6 @@ static int commit(int argc, char** argv) { printf("%s: %s\n", ((FileInfo*)tree->items + idx)->name, ((FileInfo*)tree->items + idx)->hash); } - char tree_hash[41]; snapshot_tree(tree, tree_hash); diff --git a/src/object.c b/src/object.c index 4afe1de..e4ed47a 100644 --- a/src/object.c +++ b/src/object.c @@ -17,7 +17,7 @@ char* get_object(char* hash, size_t* size_out) { free(compressed_data); return NULL; } - + size_t idx = 0; while (idx < compressed_size && IS_DIGIT(compressed_data[idx])) { @@ -152,7 +152,7 @@ static int mkdir_recursive(const char *path, mode_t mode) { return 0; } -int save_diff(ActionList* diff, char* path, char* root, size_t diff_id, char* basefile_hash, File* modified_file, int tree) { +int save_diff(ActionList* diff, char* path, char* root, size_t diff_id, char* basefile_hash) { size_t buffer_size = 41; buffer_size += 1 + snprintf(NULL, 0, "%d", diff->len); @@ -186,20 +186,20 @@ int save_diff(ActionList* diff, char* path, char* root, size_t diff_id, char* ba size_t remaining = sizeof(tmp) - offset; if (action.type == DELETE) { - offset += snprintf(tmp + offset, - remaining, - "0 %zu %zu ", - action.line_original, + offset += snprintf(tmp + offset, + remaining, + "0 %zu %zu ", + action.line_original, action.line_changed ); continue; } - offset += snprintf(tmp + offset, remaining, - "1 %zu %zu %zu %s ", - action.line_original, - action.line_changed, - strlen(action.content), + offset += snprintf(tmp + offset, remaining, + "1 %zu %zu %zu %s ", + action.line_original, + action.line_changed, + strlen(action.content), action.content ); } @@ -207,8 +207,7 @@ int save_diff(ActionList* diff, char* path, char* root, size_t diff_id, char* ba char id[2+snprintf(NULL, 0, "%d", diff_id)+strlen(path)]; snprintf(id, sizeof(id), "%s %d", path, diff_id); char hash[41]; - if (tree) object_hash(TreeDiffObject, id, hash); - else object_hash(FileDiffObject, id, hash); + object_hash(FileDiffObject, id, hash); char dir_path[PATH_MAX]; char file_path[PATH_MAX]; @@ -287,7 +286,7 @@ int read_diff(char* content, char* basefile_hash, ActionList* diff_out) { char* end; long actions = strtol(number_of_actions, &end, 10); - + if (end == number_of_actions || *end != '\0' || actions < 0) { perror("ERROR: invalid number of actions in read_diff!"); free(number_of_actions); @@ -375,7 +374,7 @@ int read_diff(char* content, char* basefile_hash, ActionList* diff_out) { } int save_file_diff(char* path, char* root, size_t diff_id, char* basefile_hash, ActionList* diff) { - + return 1; } @@ -419,4 +418,4 @@ File* apply_diff(File* basefile, ActionList* diff) { } return copy; -} \ No newline at end of file +} diff --git a/src/tree.c b/src/tree.c index 67d6fc8..c23542f 100644 --- a/src/tree.c +++ b/src/tree.c @@ -34,7 +34,7 @@ void snapshot_tree(FileInfoBuffer* tree, char* hash) { FileInfo* file_info = (FileInfo*)tree->items + idx; size_t remaining = buffer_size - offset; - int written = snprintf(tmp + offset, remaining, "%o %s %s\n", + int written = snprintf(tmp + offset, remaining, "%o %s %s\n", file_info->mode, file_info->name, file_info->hash); if (written < 0 || (size_t)written >= remaining) { @@ -63,7 +63,7 @@ void snapshot_tree(FileInfoBuffer* tree, char* hash) { } FILE* fp = fopen(file_path, "wb"); - if (!fp) { + if (!fp) { perror("ERROR: cannot open path in snapshot_tree!"); free(tmp); file_info_buffer_free(tree); @@ -81,7 +81,7 @@ void snapshot_tree(FileInfoBuffer* tree, char* hash) { free(root); return; } - + if (compress(compressed, &compressedLen, (const Bytef*)tmp, originalLen) != Z_OK) { perror("ERROR: compression failed in snapshot_tree!"); free(compressed); @@ -98,325 +98,13 @@ void snapshot_tree(FileInfoBuffer* tree, char* hash) { fclose(fp); chmod(file_path, S_IRUSR | S_IRGRP | S_IROTH); - + free(compressed); free(tmp); file_info_buffer_free(tree); free(root); } -int save_tree_diff(FileInfoBuffer* current_tree, char* root, char* branch_name, size_t diff_id, char* base_tree_hash, char* hash) { - if (!current_tree || !root || !branch_name || !base_tree_hash || !hash) { - return 0; - } - - char base_tree_location[PATH_MAX]; - snprintf(base_tree_location, sizeof(base_tree_location), "%s/.merk/objects/%.2s/%s", root, base_tree_hash, base_tree_hash+2); - - size_t compressed_size; - unsigned char* compressed_data = (unsigned char*)get_file_content_with_size(base_tree_location, &compressed_size); - if (!compressed_data) { - return 0; - } - - size_t idx = 0; - while (idx < compressed_size && IS_DIGIT(compressed_data[idx])) { - idx++; - } - - if (idx == 0) { - perror("ERROR: no length found in base tree file!"); - free(compressed_data); - return 0; - } - - char* size_str = calloc(idx + 1, sizeof(char)); - if (!size_str) { - free(compressed_data); - return 0; - } - - memcpy(size_str, compressed_data, idx); - size_str[idx] = '\0'; - - char* end; - long size = strtol(size_str, &end, 10); - if (end == size_str || *end != '\0' || size <= 0) { - perror("ERROR: invalid length in base tree file"); - free(size_str); - free(compressed_data); - return 0; - } - - size_t offset = strlen(size_str) + 1; - free(size_str); - - char* base_tree_content = calloc(size + 1, sizeof(char)); - if (!base_tree_content) { - free(compressed_data); - return 0; - } - - uLongf dest_len = (uLongf)size; - int result = uncompress((unsigned char*)base_tree_content, &dest_len, compressed_data + offset, compressed_size - offset); - free(compressed_data); - - if (result != Z_OK) { - perror("ERROR: decompression of base tree failed!"); - free(base_tree_content); - return 0; - } - - base_tree_content[dest_len] = '\0'; - - File* base_tree_file = from_string(base_tree_content); - if (!base_tree_file) { - free(base_tree_content); - return 0; - } - - size_t buffer_size = 0; - for (size_t i = 0; i < current_tree->len; i++) { - FileInfo* file_info = (FileInfo*)current_tree->items + i; - buffer_size += snprintf(NULL, 0, "%o %s %s\n", file_info->mode, file_info->name, file_info->hash); - } - buffer_size += 1; - - char* current_tree_content = malloc(buffer_size); - if (!current_tree_content) { - free(base_tree_content); - free(base_tree_file->content[0]); - free(base_tree_file->content); - free(base_tree_file); - return 0; - } - - size_t content_offset = 0; - for (size_t i = 0; i < current_tree->len; i++) { - FileInfo* file_info = (FileInfo*)current_tree->items + i; - size_t remaining = buffer_size - content_offset; - int written = snprintf(current_tree_content + content_offset, remaining, "%o %s %s\n", - file_info->mode, file_info->name, file_info->hash); - if (written < 0 || (size_t)written >= remaining) { - perror("ERROR: buffer overflow in current tree content!"); - free(current_tree_content); - free(base_tree_content); - free(base_tree_file->content[0]); - free(base_tree_file->content); - free(base_tree_file); - return 0; - } - content_offset += (size_t)written; - } - current_tree_content[content_offset] = '\0'; - - File* current_tree_file = from_string(current_tree_content); - if (!current_tree_file) { - free(current_tree_content); - free(base_tree_content); - free(base_tree_file->content[0]); - free(base_tree_file->content); - free(base_tree_file); - return 0; - } - - ActionList* diff = myers_diff(base_tree_file, current_tree_file, 0, 0); - - if (!diff || diff->len == 0) { - strcpy(hash, base_tree_hash); - - free(current_tree_content); - free(base_tree_content); - free(base_tree_file->content[0]); - free(base_tree_file->content); - free(base_tree_file); - free(current_tree_file->content[0]); - free(current_tree_file->content); - free(current_tree_file); - if (diff) { - free(diff->actions); - free(diff); - } - return 1; - } - - size_t diff_buffer_size = strlen(base_tree_hash) + 1; - diff_buffer_size += snprintf(NULL, 0, "%zu ", diff->len); - - for (size_t i = 0; i < diff->len; i++) { - Action action = diff->actions[i]; - if (action.type == DELETE) { - diff_buffer_size += snprintf(NULL, 0, "0 %zu %zu ", action.line_original, action.line_changed); - } else { - diff_buffer_size += snprintf(NULL, 0, "1 %zu %zu %s ", - action.line_original, action.line_changed, current_tree_file->content[action.line_changed]); - } - } - diff_buffer_size += 1; - - char* diff_content = malloc(diff_buffer_size); - if (!diff_content) { - perror("ERROR: memory allocation failed for diff content!"); - free(current_tree_content); - free(base_tree_content); - free(base_tree_file->content[0]); - free(base_tree_file->content); - free(base_tree_file); - free(current_tree_file->content[0]); - free(current_tree_file->content); - free(current_tree_file); - free(diff->actions); - free(diff); - return 0; - } - - size_t diff_offset = 0; - diff_offset += snprintf(diff_content, diff_buffer_size, "%s %zu ", base_tree_hash, diff->len); - - for (size_t i = 0; i < diff->len; i++) { - Action action = diff->actions[i]; - size_t remaining = diff_buffer_size - diff_offset; - - if (action.type == DELETE) { - int written = snprintf(diff_content + diff_offset, remaining, "0 %zu %zu ", - action.line_original, action.line_changed); - if (written < 0 || (size_t)written >= remaining) { - perror("ERROR: buffer overflow in diff content!"); - free(diff_content); - free(current_tree_content); - free(base_tree_content); - free(base_tree_file->content[0]); - free(base_tree_file->content); - free(base_tree_file); - free(current_tree_file->content[0]); - free(current_tree_file->content); - free(current_tree_file); - free(diff->actions); - free(diff); - return 0; - } - diff_offset += (size_t)written; - } else { - int written = snprintf(diff_content + diff_offset, remaining, "1 %zu %zu %s ", - action.line_original, action.line_changed, current_tree_file->content[action.line_changed]); - if (written < 0 || (size_t)written >= remaining) { - perror("ERROR: buffer overflow in diff content!"); - free(diff_content); - free(current_tree_content); - free(base_tree_content); - free(base_tree_file->content[0]); - free(base_tree_file->content); - free(base_tree_file); - free(current_tree_file->content[0]); - free(current_tree_file->content); - free(current_tree_file); - free(diff->actions); - free(diff); - return 0; - } - diff_offset += (size_t)written; - } - } - - object_hash(TreeDiffObject, diff_content, hash); - - char dir_path[PATH_MAX]; - char file_path[PATH_MAX]; - snprintf(dir_path, sizeof(dir_path), "%s/.merk/objects/%.2s", root, hash); - if (mkdir(dir_path, 0755) != 0 && errno != EEXIST) { - perror("ERROR: failed to create directory!"); - free(diff_content); - free(current_tree_content); - free(base_tree_content); - free(base_tree_file->content[0]); - free(base_tree_file->content); - free(base_tree_file); - free(current_tree_file->content[0]); - free(current_tree_file->content); - free(current_tree_file); - free(diff->actions); - free(diff); - return 0; - } - snprintf(file_path, sizeof(file_path), "%s/%s", dir_path, hash+2); - - FILE* fp = fopen(file_path, "wb"); - if (!fp) { - perror("ERROR: cannot open file for writing!"); - free(diff_content); - free(current_tree_content); - free(base_tree_content); - free(base_tree_file->content[0]); - free(base_tree_file->content); - free(base_tree_file); - free(current_tree_file->content[0]); - free(current_tree_file->content); - free(current_tree_file); - free(diff->actions); - free(diff); - return 0; - } - - uLong originalLen = strlen(diff_content) + 1; - uLong compressedLen = compressBound(originalLen); - Bytef* compressed = malloc(compressedLen); - if (!compressed) { - perror("ERROR: memory allocation failed for compression!"); - fclose(fp); - free(diff_content); - free(current_tree_content); - free(base_tree_content); - free(base_tree_file->content[0]); - free(base_tree_file->content); - free(base_tree_file); - free(current_tree_file->content[0]); - free(current_tree_file->content); - free(current_tree_file); - free(diff->actions); - free(diff); - return 0; - } - - if (compress(compressed, &compressedLen, (const Bytef*)diff_content, originalLen) != Z_OK) { - perror("ERROR: compression failed!"); - free(compressed); - fclose(fp); - free(diff_content); - free(current_tree_content); - free(base_tree_content); - free(base_tree_file->content[0]); - free(base_tree_file->content); - free(base_tree_file); - free(current_tree_file->content[0]); - free(current_tree_file->content); - free(current_tree_file); - free(diff->actions); - free(diff); - return 0; - } - - fprintf(fp, "%lu ", (unsigned long)originalLen); - fwrite(compressed, 1, compressedLen, fp); - fclose(fp); - - chmod(file_path, S_IRUSR | S_IRGRP | S_IROTH); - - free(compressed); - free(diff_content); - free(current_tree_content); - free(base_tree_content); - free(base_tree_file->content[0]); - free(base_tree_file->content); - free(base_tree_file); - free(current_tree_file->content[0]); - free(current_tree_file->content); - free(current_tree_file); - free(diff->actions); - free(diff); - - return 1; -} - int read_tree(FileInfoBuffer* tree_out, char* hash) { if (!tree_out || !hash) { return 0;