refactor(tree): removed everything relating to tree diffs
This commit is contained in:
parent
d07c67c35e
commit
afbcd5d338
5 changed files with 22 additions and 337 deletions
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
31
src/object.c
31
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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
320
src/tree.c
320
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;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue