From 967b79d9baee274ff29b4dca33283e89be614ad7 Mon Sep 17 00:00:00 2001 From: lisk77 Date: Thu, 28 Aug 2025 17:01:41 +0200 Subject: [PATCH] feat(cli): added some base functionality to the commit and files command --- src/main.c | 104 ++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 88 insertions(+), 16 deletions(-) diff --git a/src/main.c b/src/main.c index 35a6d4c..505ae9e 100644 --- a/src/main.c +++ b/src/main.c @@ -8,14 +8,14 @@ #include "action_list.h" #include "file.h" #include "myers.h" -#include "utilities.h" #include "tree.h" +#include "base_file_buffer.h" static void usage(int exitcode) { printf("usage: merk []\n\ \n init Initializes a repository in the current directory\ \n diff Displays the difference between the given two files\ - \n files 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"); exit(exitcode); } @@ -29,7 +29,7 @@ int main(int argc, char **argv) { if (strcmp(subcmd, "diff") != 0 && strcmp(subcmd, "init") != 0 && - strcmp(subcmd, "files") != 0 && + strcmp(subcmd, "status") != 0 && strcmp(subcmd, "commit") != 0 ) { fprintf(stderr, "ERROR: Unknown subcommand: '%s'\n", subcmd); @@ -44,7 +44,7 @@ int main(int argc, char **argv) { exit(1); } - if (mkdir(".merk", 0700) == 0) { + if (mkdir(".merk", 0755) == 0) { printf("Initialized merk repository\n"); } @@ -56,13 +56,23 @@ int main(int argc, char **argv) { } } - int fd = open(".merk/HEAD", O_WRONLY | O_CREAT, 0666); - if (fd < 0) return -1; - close(fd); + int branch = open(".merk/BRANCH", O_WRONLY | O_CREAT, 0666); + if (branch < 0) return -1; + write(branch, "main", 4); + close(branch); mkdir(".merk/objects", 0755); mkdir(".merk/refs", 0755); mkdir(".merk/refs/branches", 0755); + mkdir(".merk/info", 0755); + + int main_branch = open(".merk/refs/branches/main", O_WRONLY | O_CREAT, 0666); + if (main_branch < 0) return -1; + close(main_branch); + + int main_info = open(".merk/info/main", O_WRONLY | O_CREAT, 0666); + if (main_info < 0) return -1; + close(main_info); } // Prints out a visual representation of the diff of the files provided @@ -95,39 +105,101 @@ int main(int argc, char **argv) { if (!actions) printf("ERROR: something went wrong while taking the diff!"); else visualize_diff(file1, file2, actions); } - // Gives a list of untracked files in the repo - else if (strcmp(subcmd, "files") == 0) { + // Gives a list of untracked files in the repo as well as meta information + else if (strcmp(subcmd, "status") == 0) { if (argc != 2) { printf("ERROR: too many arguments given!\n"); printf("Usage: merk status"); exit(1); } - PathBuffer* files = new_path_buffer(); + FileInfoBuffer* files = file_info_buffer_new(); char relative[PATH_MAX] = ""; char* root = find_root(relative); if (!root) { - free_path_buffer(files); + list_free(files); return 1; } - walk(root, relative, relative, files); + walk(root, relative, relative, files, 0, root); + file_info_buffer_sort(files); - printf("Untracked files:\n\n"); - for (size_t i = 0; i < files->len; i++) { - printf("%s\n", files->paths[i]); + char branch_path[PATH_MAX]; + snprintf(branch_path, sizeof(branch_path), "%s/.merk/BRANCH", root); + + char* branch = get_file_content(branch_path); + + char info_path[PATH_MAX]; + snprintf(info_path, sizeof(info_path), "%s/.merk/info/%s", root, branch); + + BaseFileBuffer* tracked_list = base_file_buffer_new(); + read_base_file_list(tracked_list, info_path); + + StringBuffer* modified_files = string_buffer_new(); + StringBuffer* untracked_files = string_buffer_new(); + + for (size_t idx = 0; idx < files->len; idx++) { + char* file_name = ((FileInfo*)files->items + idx)->name; + // This if is just for debugging purposes right now and will be + // changed later to the actual implementation + if (base_file_buffer_search(tracked_list, file_name)) { + string_buffer_push(modified_files, file_name); + continue; + } + string_buffer_push(untracked_files, file_name); } - free_path_buffer(files); + 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("\n"); + + 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("\nOn branch \x1b[39;1;4m%s\x1b[0m with 0 commits\n", branch); + + file_info_buffer_free(files); free(root); return 0; } + // Commits changes to the repo else if (strcmp(subcmd, "commit") == 0) { if (argc == 2) { printf("ERROR: too little arguments given!\n"); printf("Usage: merk commit [-m ] ..."); exit(1); } + + char relative[PATH_MAX] = ""; + char* root = find_root(relative); + + char branch_path[PATH_MAX]; + snprintf(branch_path, sizeof(branch_path), "%s/.merk/BRANCH", root); + char* branch = get_file_content(branch_path); + char info_path[PATH_MAX]; + snprintf(info_path, sizeof(info_path), "%s/.merk/info/%s", root, branch); + char* base_file_list = get_file_content(info_path); + + for (size_t i = 2; i < argc; i++) { + char* real = realpath(argv[i], NULL); + if (get_path_type(real) == PT_FILE && is_in_repo(root, real) == 0) { + char* repo_path = get_repo_path(root, real); + free(repo_path); + } + else { + perror("ERROR: given arguments were not all files!"); + free(real); + free(branch); + free(base_file_list); + return 1; + } + } + + free(branch); + free(base_file_list); } else { usage(1);