fix(object): read_diff didnt read correctly
This commit is contained in:
parent
c1f11eceb2
commit
a8a5408db4
2 changed files with 32 additions and 98 deletions
|
|
@ -27,9 +27,10 @@
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
char* get_object(char*, size_t*);
|
char* get_object(char*, size_t*);
|
||||||
void* parse_object(char*, ObjectType, 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*, File*, int);
|
||||||
int read_diff(char*, char*, ActionList*);
|
int read_diff(char*, char*, ActionList*);
|
||||||
int save_file_diff(char*, char*, size_t, char*, Changes*);
|
int save_file_diff(char*, char*, size_t, char*, ActionList*);
|
||||||
|
File* apply_diff(File*, ActionList*);
|
||||||
|
|
||||||
#endif // OBJECT_H
|
#endif // OBJECT_H
|
||||||
125
src/object.c
125
src/object.c
|
|
@ -1,19 +1,23 @@
|
||||||
#include "object.h"
|
#include "object.h"
|
||||||
|
|
||||||
char* get_object(char* hash, size_t* size_out) {
|
char* get_object(char* hash, size_t* size_out) {
|
||||||
char dir_path[PATH_MAX];
|
char* root = find_root(NULL);
|
||||||
char repo_path[PATH_MAX];
|
if (!root) {
|
||||||
char file_path[PATH_MAX];
|
perror("ERROR: unable to find root directory of the repository!");
|
||||||
snprintf(dir_path, sizeof(dir_path), ".merk/objects/%.2s", hash);
|
return NULL;
|
||||||
snprintf(repo_path, sizeof(repo_path), "%s/%s", dir_path, hash+2);
|
}
|
||||||
realpath(repo_path, file_path);
|
|
||||||
|
|
||||||
|
char dir_path[PATH_MAX];
|
||||||
|
char file_path[PATH_MAX];
|
||||||
|
snprintf(dir_path, sizeof(dir_path), "%s/.merk/objects/%.2s", root, hash);
|
||||||
|
snprintf(file_path, sizeof(file_path), "%s/%s", dir_path, hash+2);
|
||||||
size_t compressed_size;
|
size_t compressed_size;
|
||||||
unsigned char* compressed_data = (unsigned char*)get_file_content_with_size(file_path, &compressed_size);
|
unsigned char* compressed_data = (unsigned char*)get_file_content_with_size(file_path, &compressed_size);
|
||||||
if (!compressed_data || compressed_size == 0) {
|
if (!compressed_data || compressed_size == 0) {
|
||||||
free(compressed_data);
|
free(compressed_data);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
size_t idx = 0;
|
size_t idx = 0;
|
||||||
while (idx < compressed_size && IS_DIGIT(compressed_data[idx])) {
|
while (idx < compressed_size && IS_DIGIT(compressed_data[idx])) {
|
||||||
|
|
@ -73,7 +77,7 @@ char* get_object(char* hash, size_t* size_out) {
|
||||||
return decompressed;
|
return decompressed;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* parse_object(char* hash, ObjectType type, size_t* size_out) {
|
void* parse_object(char* hash, ObjectType type, size_t* size_out, char* meta_hash) {
|
||||||
size_t line_count;
|
size_t line_count;
|
||||||
char* content = get_object(hash, &line_count);
|
char* content = get_object(hash, &line_count);
|
||||||
if (!content) return NULL;
|
if (!content) return NULL;
|
||||||
|
|
@ -109,7 +113,12 @@ void* parse_object(char* hash, ObjectType type, size_t* size_out) {
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
case FileDiffObject: {
|
case FileDiffObject: {
|
||||||
|
ActionList* diff = new_list();
|
||||||
|
if (!read_diff(content, meta_hash, diff)) {
|
||||||
|
free(content);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return diff;
|
||||||
}
|
}
|
||||||
|
|
||||||
default: free(content); return NULL;
|
default: free(content); return NULL;
|
||||||
|
|
@ -163,8 +172,8 @@ int save_diff(ActionList* diff, char* path, char* root, size_t diff_id, char* ba
|
||||||
6 +
|
6 +
|
||||||
snprintf(NULL, 0, "%d", action.line_original) +
|
snprintf(NULL, 0, "%d", action.line_original) +
|
||||||
snprintf(NULL, 0, "%d", action.line_changed) +
|
snprintf(NULL, 0, "%d", action.line_changed) +
|
||||||
snprintf(NULL, 0, "%zu", strlen(modified_file->content[action.line_changed])) +
|
snprintf(NULL, 0, "%zu", strlen(action.content)) +
|
||||||
strlen(modified_file->content[action.line_changed]);
|
strlen(action.content);
|
||||||
}
|
}
|
||||||
|
|
||||||
char tmp[buffer_size];
|
char tmp[buffer_size];
|
||||||
|
|
@ -190,8 +199,8 @@ int save_diff(ActionList* diff, char* path, char* root, size_t diff_id, char* ba
|
||||||
"1 %zu %zu %zu %s ",
|
"1 %zu %zu %zu %s ",
|
||||||
action.line_original,
|
action.line_original,
|
||||||
action.line_changed,
|
action.line_changed,
|
||||||
strlen(modified_file->content[action.line_changed]),
|
strlen(action.content),
|
||||||
modified_file->content[action.line_changed]
|
action.content
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -250,7 +259,7 @@ int save_diff(ActionList* diff, char* path, char* root, size_t diff_id, char* ba
|
||||||
}
|
}
|
||||||
|
|
||||||
int read_diff(char* content, char* basefile_hash, ActionList* diff_out) {
|
int read_diff(char* content, char* basefile_hash, ActionList* diff_out) {
|
||||||
if (!content || !basefile_hash || !diff_out) {
|
if (!content || !diff_out) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -278,18 +287,19 @@ int read_diff(char* content, char* basefile_hash, ActionList* diff_out) {
|
||||||
|
|
||||||
char* end;
|
char* end;
|
||||||
long actions = strtol(number_of_actions, &end, 10);
|
long actions = strtol(number_of_actions, &end, 10);
|
||||||
free(number_of_actions);
|
|
||||||
|
|
||||||
if (end == number_of_actions || *end != '\0' || actions <= 0) {
|
if (end == number_of_actions || *end != '\0' || actions <= 0) {
|
||||||
perror("ERROR: invalid number of actions in read_diff!");
|
perror("ERROR: invalid number of actions in read_diff!");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
free(number_of_actions);
|
||||||
|
|
||||||
size_t action_idx = 0;
|
size_t action_idx = 0;
|
||||||
while (content[idx] && action_idx < (size_t)actions) {
|
while (content[idx] && action_idx < (size_t)actions) {
|
||||||
idx++;
|
idx++;
|
||||||
|
|
||||||
Action action = {0};
|
Action action;
|
||||||
|
|
||||||
if (content[idx] == '0') {
|
if (content[idx] == '0') {
|
||||||
idx++;
|
idx++;
|
||||||
|
|
@ -313,6 +323,8 @@ int read_diff(char* content, char* basefile_hash, ActionList* diff_out) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
idx = endptr - content;
|
idx = endptr - content;
|
||||||
|
action.content = NULL;
|
||||||
|
action.type = DELETE;
|
||||||
} else if (content[idx] == '1') {
|
} else if (content[idx] == '1') {
|
||||||
idx++;
|
idx++;
|
||||||
if (content[idx] != ' ') {
|
if (content[idx] != ' ') {
|
||||||
|
|
@ -349,6 +361,7 @@ int read_diff(char* content, char* basefile_hash, ActionList* diff_out) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
idx += content_length;
|
idx += content_length;
|
||||||
|
action.type = INSERT;
|
||||||
} else {
|
} else {
|
||||||
perror("ERROR: unknown action type in read_diff!");
|
perror("ERROR: unknown action type in read_diff!");
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -362,89 +375,9 @@ int read_diff(char* content, char* basefile_hash, ActionList* diff_out) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int save_file_diff(char* path, char* root, size_t diff_id, char* basefile_hash, Changes* changes) {
|
int save_file_diff(char* path, char* root, size_t diff_id, char* basefile_hash, ActionList* diff) {
|
||||||
char basefile_location[2+strlen(root)+strlen("/.merk/objects/")+strlen(basefile_hash)];
|
|
||||||
snprintf(basefile_location, sizeof(basefile_location), "%s/.merk/objects/%.2s/%s", root, basefile_hash, basefile_hash+2);
|
|
||||||
|
|
||||||
size_t compressed_size;
|
|
||||||
unsigned char* compressed_data = (unsigned char*)get_file_content_with_size(basefile_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 at start of save_file_diff!");
|
|
||||||
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') {
|
|
||||||
perror("ERROR: invalid length in base_file_list");
|
|
||||||
free(size_str);
|
|
||||||
free(compressed_data);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t offset = strlen(size_str) + 1;
|
|
||||||
free(size_str);
|
|
||||||
|
|
||||||
char* basefile_content = calloc(size+1, sizeof(char));
|
|
||||||
if (!basefile_content) {
|
|
||||||
free(compressed_data);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
uLongf dest_len = (uLongf)size;
|
|
||||||
|
|
||||||
int result = uncompress((unsigned char*)basefile_content, &dest_len, compressed_data+offset, compressed_size);
|
|
||||||
free(compressed_data);
|
|
||||||
|
|
||||||
if (result != Z_OK) {
|
|
||||||
perror("ERROR: decompression of the base file list failed!");
|
|
||||||
free(basefile_content);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
basefile_content[dest_len] = '\0';
|
|
||||||
|
|
||||||
File* basefile = from_string(basefile_content);
|
|
||||||
char* modified_file_path = realpath(path, NULL);
|
|
||||||
File* modified_file = new_file(modified_file_path);
|
|
||||||
|
|
||||||
ActionList* diff = myers_diff(basefile, modified_file, 0, 0);
|
|
||||||
if (diff->len == 0) {
|
|
||||||
free(basefile_content);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
for (size_t idx = 0; idx < diff->len; idx++) {
|
|
||||||
Action action = diff->actions[idx];
|
|
||||||
if (action.type == INSERT) {
|
|
||||||
changes->insertions += 1;
|
|
||||||
} else if (action.type == DELETE) {
|
|
||||||
changes->deletions += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
save_diff(diff, path, root, diff_id, basefile_hash, modified_file, 0);
|
|
||||||
|
|
||||||
free(basefile_content);
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue