diff --git a/src/tree.c b/src/tree.c index 0a6a80e..72e4075 100644 --- a/src/tree.c +++ b/src/tree.c @@ -1,27 +1,20 @@ #include "tree.h" void snapshot_tree(FileInfoBuffer* tree, char* hash) { - FileInfoBuffer* files = file_info_buffer_new(); - if (!files) { - perror("ERROR: failed to create file info buffer!"); - return; - } - char relative[PATH_MAX] = ""; char* root = find_root(relative); if (!root) { perror("ERROR: unable to find root directory of the repository!"); - file_info_buffer_free(files); + file_info_buffer_free(tree); return; } - walk(root, relative, relative, files, 1, root); - file_info_buffer_sort(files); + file_info_buffer_sort(tree); size_t buffer_size = 0; - for (size_t idx = 0; idx < files->len; idx++) { - FileInfo* file_info = (FileInfo*)files->items + idx; + for (size_t idx = 0; idx < tree->len; idx++) { + FileInfo* file_info = (FileInfo*)tree->items + idx; buffer_size += snprintf(NULL, 0, "%o %s %s\n", file_info->mode, file_info->name, file_info->hash); } @@ -30,15 +23,15 @@ void snapshot_tree(FileInfoBuffer* tree, char* hash) { char* tmp = calloc(buffer_size, sizeof(char)); if (!tmp) { perror("ERROR: memory allocation failed in snapshot_tree!"); - file_info_buffer_free(files); + file_info_buffer_free(tree); free(root); return; } size_t offset = 0; - for (size_t idx = 0; idx < files->len; idx++) { - FileInfo* file_info = (FileInfo*)files->items + idx; + for (size_t idx = 0; idx < tree->len; idx++) { + FileInfo* file_info = (FileInfo*)tree->items + idx; size_t remaining = buffer_size - offset; int written = snprintf(tmp + offset, remaining, "%o %s %s\n", @@ -47,7 +40,7 @@ void snapshot_tree(FileInfoBuffer* tree, char* hash) { if (written < 0 || (size_t)written >= remaining) { perror("ERROR: buffer overflow in snapshot_tree!"); free(tmp); - file_info_buffer_free(files); + file_info_buffer_free(tree); free(root); return; } @@ -64,7 +57,7 @@ void snapshot_tree(FileInfoBuffer* tree, char* hash) { if (access(file_path, F_OK) == 0) { free(tmp); - file_info_buffer_free(files); + file_info_buffer_free(tree); free(root); return; } @@ -73,7 +66,7 @@ void snapshot_tree(FileInfoBuffer* tree, char* hash) { if (!fp) { perror("ERROR: cannot open path in snapshot_tree!"); free(tmp); - file_info_buffer_free(files); + file_info_buffer_free(tree); free(root); return; } @@ -84,7 +77,7 @@ void snapshot_tree(FileInfoBuffer* tree, char* hash) { if (!compressed) { fclose(fp); free(tmp); - file_info_buffer_free(files); + file_info_buffer_free(tree); free(root); return; } @@ -94,7 +87,7 @@ void snapshot_tree(FileInfoBuffer* tree, char* hash) { free(compressed); free(tmp); fclose(fp); - file_info_buffer_free(files); + file_info_buffer_free(tree); free(root); return; } @@ -108,7 +101,7 @@ void snapshot_tree(FileInfoBuffer* tree, char* hash) { free(compressed); free(tmp); - file_info_buffer_free(files); + file_info_buffer_free(tree); free(root); } @@ -117,7 +110,6 @@ int save_tree_diff(FileInfoBuffer* current_tree, char* root, char* branch_name, return 0; } - // Step 1: Read the base tree file and convert to File* 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); @@ -127,7 +119,6 @@ int save_tree_diff(FileInfoBuffer* current_tree, char* root, char* branch_name, return 0; } - // Parse length from compressed data size_t idx = 0; while (idx < compressed_size && IS_DIGIT(compressed_data[idx])) { idx++; @@ -157,10 +148,9 @@ int save_tree_diff(FileInfoBuffer* current_tree, char* root, char* branch_name, return 0; } - size_t offset = strlen(size_str) + 1; // +1 for space after length + size_t offset = strlen(size_str) + 1; free(size_str); - // Decompress base tree content char* base_tree_content = calloc(size + 1, sizeof(char)); if (!base_tree_content) { free(compressed_data); @@ -179,20 +169,18 @@ int save_tree_diff(FileInfoBuffer* current_tree, char* root, char* branch_name, base_tree_content[dest_len] = '\0'; - // Convert base tree content to File* File* base_tree_file = from_string(base_tree_content); if (!base_tree_file) { free(base_tree_content); return 0; } - // Step 2: Convert FileInfoBuffer to string (same as snapshot_tree logic) 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; // null terminator + buffer_size += 1; char* current_tree_content = malloc(buffer_size); if (!current_tree_content) { @@ -222,7 +210,6 @@ int save_tree_diff(FileInfoBuffer* current_tree, char* root, char* branch_name, } current_tree_content[content_offset] = '\0'; - // Convert current tree content to File* File* current_tree_file = from_string(current_tree_content); if (!current_tree_file) { free(current_tree_content); @@ -233,14 +220,11 @@ int save_tree_diff(FileInfoBuffer* current_tree, char* root, char* branch_name, return 0; } - // Step 3: Generate diff using Myers algorithm ActionList* diff = myers_diff(base_tree_file, current_tree_file, 0, 0); - // Handle case where trees are identical if (!diff || diff->len == 0) { strcpy(hash, base_tree_hash); - // Cleanup free(current_tree_content); free(base_tree_content); free(base_tree_file->content[0]); @@ -256,23 +240,20 @@ int save_tree_diff(FileInfoBuffer* current_tree, char* root, char* branch_name, return 1; } - // Step 4: Save the diff - // Calculate size for diff content string - size_t diff_buffer_size = strlen(base_tree_hash) + 1; // base hash + space - diff_buffer_size += snprintf(NULL, 0, "%zu ", diff->len); // action count + space + 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 { // INSERT + } 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; // null terminator + diff_buffer_size += 1; - // Build diff content string char* diff_content = malloc(diff_buffer_size); if (!diff_content) { perror("ERROR: memory allocation failed for diff content!"); @@ -315,7 +296,7 @@ int save_tree_diff(FileInfoBuffer* current_tree, char* root, char* branch_name, return 0; } diff_offset += (size_t)written; - } else { // INSERT + } 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) { @@ -337,10 +318,8 @@ int save_tree_diff(FileInfoBuffer* current_tree, char* root, char* branch_name, } } - // Generate hash from the actual diff content object_hash(TreeDiffObject, diff_content, hash); - // Create directory structure char dir_path[PATH_MAX]; char file_path[PATH_MAX]; snprintf(dir_path, sizeof(dir_path), "%s/.merk/objects/%.2s", root, hash); @@ -361,7 +340,6 @@ int save_tree_diff(FileInfoBuffer* current_tree, char* root, char* branch_name, } snprintf(file_path, sizeof(file_path), "%s/%s", dir_path, hash+2); - // Open file for writing FILE* fp = fopen(file_path, "wb"); if (!fp) { perror("ERROR: cannot open file for writing!"); @@ -379,7 +357,6 @@ int save_tree_diff(FileInfoBuffer* current_tree, char* root, char* branch_name, return 0; } - // Compress the diff content uLong originalLen = strlen(diff_content) + 1; uLong compressedLen = compressBound(originalLen); Bytef* compressed = malloc(compressedLen); @@ -418,15 +395,12 @@ int save_tree_diff(FileInfoBuffer* current_tree, char* root, char* branch_name, return 0; } - // Write length prefix and compressed data fprintf(fp, "%lu ", (unsigned long)originalLen); fwrite(compressed, 1, compressedLen, fp); fclose(fp); - // Set file permissions chmod(file_path, S_IRUSR | S_IRGRP | S_IROTH); - // Cleanup free(compressed); free(diff_content); free(current_tree_content);