feat(commit): added proper file to hash mapping

This commit is contained in:
lisk77 2025-09-24 19:24:53 +02:00
parent a495fb6ce8
commit 1fdcda6b42

View file

@ -11,13 +11,16 @@
#include "commit.h" #include "commit.h"
#include "hash.h" #include "hash.h"
#include "object.h" #include "object.h"
#include "utilities.h"
static void usage(int exitcode) { static void usage(int exitcode) {
printf("usage: merk <command> [<args>]\n\ printf("usage: merk <command> [<args>]\n\
\n init Initializes a repository in the current directory\ \n init Initializes a repository in the current directory\
\n diff Displays the difference between the given two files\ \n diff Displays the difference between the given two files\
\n status Displays a list of modified and untracked files in the repository\ \n status Displays a list of modified and untracked files in the repository\
\n commit Record changes made to the repository\n"); \n commit Record changes made to the repository\n\
\n log Displays the list of commits on the current branch\n"
);
exit(exitcode); exit(exitcode);
} }
@ -146,8 +149,8 @@ static int status() {
if (base_file_buffer_search(tracked_list, file_name)) { if (base_file_buffer_search(tracked_list, file_name)) {
BaseFileInfo* base_file = base_file_buffer_search(tracked_list, file_name); BaseFileInfo* base_file = base_file_buffer_search(tracked_list, file_name);
char base_file_hash[41]; char base_file_hash[41];
char id[2 + snprintf(NULL, 0, "%d", base_file->base_num) + strlen(file_name)]; char id[2 + snprintf(NULL, 0, "%lu", base_file->base_num) + strlen(file_name)];
snprintf(id, sizeof(id), "%s %d", file_name, base_file->base_num); snprintf(id, sizeof(id), "%s %lu", file_name, base_file->base_num);
object_hash(BaseFileObject, id, base_file_hash); object_hash(BaseFileObject, id, base_file_hash);
File* basefile = parse_object(base_file_hash, BaseFileObject, NULL, NULL); File* basefile = parse_object(base_file_hash, BaseFileObject, NULL, NULL);
if (!basefile) { if (!basefile) {
@ -162,7 +165,7 @@ static int status() {
} }
File* comparison_file = basefile; File* comparison_file = basefile;
if (base_file->diff_num > 0) { if (base_file->diff_num > 0) {
size_t prev_diff = base_file->diff_num - 1; size_t prev_diff = base_file->diff_num - 1;
char prev_diff_hash[41]; char prev_diff_hash[41];
@ -197,7 +200,7 @@ static int status() {
} }
string_buffer_push(modified_files, file_name); string_buffer_push(modified_files, file_name);
} }
free_action_list(diff); free_action_list(diff);
free_file(modified_file); free_file(modified_file);
if (comparison_file != basefile) { if (comparison_file != basefile) {
@ -214,20 +217,20 @@ static int status() {
} }
for (size_t idx = 0; idx < modified_files->len; idx++) { for (size_t idx = 0; idx < modified_files->len; idx++) {
printf("\x1b[36;1mM\x1b[0m \x1b[36m%s\x1b[0m\n", modified_files->items[idx]); printf("\x1b[36;1mM\x1b[0m \x1b[36m%s\x1b[0m\n", (char*)modified_files->items[idx]);
} }
for (size_t idx = 0; idx < deleted_files->len; idx++) { for (size_t idx = 0; idx < deleted_files->len; idx++) {
printf("\x1b[31;4mD\x1b[0m \x1b[31;9m%s\x1b[0m\n", deleted_files->items[idx]); printf("\x1b[31;4mD\x1b[0m \x1b[31;9m%s\x1b[0m\n", (char*)deleted_files->items[idx]);
} }
if (modified_files->len != 0 || deleted_files->len != 0) printf("\n"); if (modified_files->len != 0 || deleted_files->len != 0) printf("\n");
for (size_t idx = 0; idx < untracked_files->len; idx++) { for (size_t idx = 0; idx < untracked_files->len; idx++) {
printf("\x1b[31;1mU\x1b[0m \x1b[31m%s\x1b[0m\n", untracked_files->items[idx]); printf("\x1b[31;1mU\x1b[0m \x1b[31m%s\x1b[0m\n", (char*)untracked_files->items[idx]);
} }
printf("\n\x1b[32;1m%d+\x1b[0m \x1b[31;1m%d-\x1b[0m on branch \x1b[39;1;4m%s\x1b[0m with %d commits\n", changes->insertions, changes->deletions, branch, log->len); printf("\n\x1b[32;1m%d+\x1b[0m \x1b[31;1m%d-\x1b[0m on branch \x1b[39;1;4m%s\x1b[0m with %lu commits\n", changes->insertions, changes->deletions, branch, log->len);
file_info_buffer_free(files); file_info_buffer_free(files);
free(root); free(root);
@ -394,6 +397,7 @@ static int commit(int argc, char** argv) {
} }
} }
FlatMap* file_hash_map = flat_map_new();
Changes* changes = calloc(1, sizeof(Changes)); Changes* changes = calloc(1, sizeof(Changes));
if (!changes) { if (!changes) {
free(commit_message); free(commit_message);
@ -426,15 +430,16 @@ static int commit(int argc, char** argv) {
return 1; return 1;
} }
changes->insertions += modified_file->lines; changes->insertions += modified_file->lines;
char file_hash[41]; char file_hash[41];
snapshot_file(files->items[idx], root, 0, file_hash); snapshot_file(files->items[idx], root, 0, file_hash);
flat_map_put(file_hash_map, files->items[idx], file_hash);
continue; continue;
} }
char base_file_hash[41]; char base_file_hash[41];
char id[2 + snprintf(NULL, 0, "%d", base_file->base_num) + strlen(files->items[idx])]; char id[2 + snprintf(NULL, 0, "%lu", base_file->base_num) + strlen(files->items[idx])];
snprintf(id, sizeof(id), "%s %d", files->items[idx], base_file->base_num); snprintf(id, sizeof(id), "%s %lu", (char*)files->items[idx], base_file->base_num);
object_hash(BaseFileObject, id, base_file_hash); object_hash(BaseFileObject, id, base_file_hash);
File* basefile = parse_object(base_file_hash, BaseFileObject, NULL, NULL); File* basefile = parse_object(base_file_hash, BaseFileObject, NULL, NULL);
if (!basefile) { if (!basefile) {
@ -490,7 +495,7 @@ static int commit(int argc, char** argv) {
size_t prev_diff = base_file->diff_num - 1; size_t prev_diff = base_file->diff_num - 1;
char prev_diff_hash[41]; char prev_diff_hash[41];
char id2[2 + snprintf(NULL, 0, "%zu", prev_diff) + strlen(files->items[idx])]; char id2[2 + snprintf(NULL, 0, "%zu", prev_diff) + strlen(files->items[idx])];
snprintf(id2, sizeof(id2), "%s %zu", files->items[idx], prev_diff); snprintf(id2, sizeof(id2), "%s %zu", (char*)files->items[idx], prev_diff);
object_hash(FileDiffObject, id2, prev_diff_hash); object_hash(FileDiffObject, id2, prev_diff_hash);
char hash[41]; char hash[41];
ActionList* last_diff = parse_object(prev_diff_hash, FileDiffObject, NULL, hash); ActionList* last_diff = parse_object(prev_diff_hash, FileDiffObject, NULL, hash);
@ -550,15 +555,39 @@ static int commit(int argc, char** argv) {
} }
} }
save_diff(diff, files->items[idx], root, base_file->diff_num, base_file_hash, NULL, 0); if (diff->len > 200) {
char new_base_hash[41];
snapshot_file(files->items[idx], root, base_file->base_num+1, new_base_hash);
base_file_buffer_remove(base_files, files->items[idx]); flat_map_put(file_hash_map, files->items[idx], new_base_hash);
BaseFileInfo new_info = (BaseFileInfo){
.base_num = base_file->base_num, base_file_buffer_remove(base_files, files->items[idx]);
.diff_num = base_file->diff_num + 1, BaseFileInfo new_info = (BaseFileInfo){
.name = strdup(files->items[idx]) .base_num = base_file->base_num + 1,
}; .diff_num = base_file->diff_num,
base_file_buffer_push(base_files, new_info); .name = strdup(files->items[idx])
};
base_file_buffer_push(base_files, new_info);
continue;
}
else {
save_diff(diff, files->items[idx], root, base_file->diff_num, base_file_hash, NULL, 0);
char diff_hash[41];
char id[2 + snprintf(NULL, 0, "%lu", base_file->diff_num) + strlen(files->items[idx])];
snprintf(id, sizeof(id), "%s %lu", (char*)files->items[idx], base_file->diff_num);
object_hash(BaseFileObject, id, diff_hash);
flat_map_put(file_hash_map, files->items[idx], diff_hash);
base_file_buffer_remove(base_files, files->items[idx]);
BaseFileInfo new_info = (BaseFileInfo){
.base_num = base_file->base_num,
.diff_num = base_file->diff_num + 1,
.name = strdup(files->items[idx])
};
base_file_buffer_push(base_files, new_info);
}
} }
base_file_buffer_sort(base_files); base_file_buffer_sort(base_files);
@ -575,21 +604,11 @@ static int commit(int argc, char** argv) {
} }
for (size_t idx = 0; idx < tree->len; idx++) { for (size_t idx = 0; idx < tree->len; idx++) {
FileInfo* info = (FileInfo*)tree->items + idx; ((FileInfo*)tree->items + idx)->hash = strdup(flat_map_get(file_hash_map, ((FileInfo*)tree->items + idx)->name));
BaseFileInfo* base_info = base_file_buffer_search(base_files, info->name); printf("%s: %s\n", ((FileInfo*)tree->items + idx)->name, ((FileInfo*)tree->items + idx)->hash);
char hash[41];
if (base_info->diff_num == 0) {
char id[2 + snprintf(NULL, 0, "%d", base_info->base_num) + strlen(info->name)];
snprintf(id, sizeof(id), "%s %d", info->name, base_info->base_num);
object_hash(BaseFileObject, id, hash);
} else {
char id[2 + snprintf(NULL, 0, "%d", base_info->diff_num-1) + strlen(info->name)];
snprintf(id, sizeof(id), "%s %d", info->name, base_info->diff_num-1);
object_hash(FileDiffObject, id, hash);
}
info->hash = strdup(hash);
} }
char tree_hash[41]; char tree_hash[41];
snapshot_tree(tree, tree_hash); snapshot_tree(tree, tree_hash);
@ -610,7 +629,7 @@ static int commit(int argc, char** argv) {
} }
read_commit_log(log, log_path); read_commit_log(log, log_path);
char parent_hash[41]; char parent_hash[41];
if (log->len != 0) { if (log->len != 0) {
snprintf(parent_hash, sizeof(parent_hash), "%s", ((Commit*)log->items + (log->len - 1))->hash); snprintf(parent_hash, sizeof(parent_hash), "%s", ((Commit*)log->items + (log->len - 1))->hash);
@ -673,11 +692,11 @@ static int commit(int argc, char** argv) {
write(ref, commit_hash, 40); write(ref, commit_hash, 40);
close(ref); close(ref);
printf("(\x1b[33;1m%.7s\x1b[0m on \x1b[39;1;4m%s\x1b[0m \x1b[32;1m%d+\x1b[0m \x1b[31;1m%d-\x1b[0m) %s\n", printf("(\x1b[33;1m%.7s\x1b[0m on \x1b[39;1;4m%s\x1b[0m \x1b[32;1m%d+\x1b[0m \x1b[31;1m%d-\x1b[0m) %s\n",
commit_hash, commit_hash,
branch, branch,
changes->insertions, changes->insertions,
changes->deletions, changes->deletions,
commit_message commit_message
); );
@ -789,7 +808,7 @@ int main(int argc, char** argv) {
printf("Usage: merk diff <PATH> <PATH>"); printf("Usage: merk diff <PATH> <PATH>");
exit(1); exit(1);
} }
diff(argv[2], argv[3]); diff(argv[2], argv[3]);
} }
// Gives a list of untracked files in the repo as well as meta information // Gives a list of untracked files in the repo as well as meta information
@ -828,4 +847,3 @@ int main(int argc, char** argv) {
return 0; return 0;
} }