189 lines
5.8 KiB
C
189 lines
5.8 KiB
C
/**
|
|
* opencoreC - ogit (OpenCore Git CLI Application)
|
|
* A standalone content-addressable version control system running in Ring 3 userspace (.opc binary).
|
|
*/
|
|
|
|
#include "stdio.h"
|
|
#include "stdlib.h"
|
|
#include "string.h"
|
|
#include "abi/syscalls.h"
|
|
|
|
#define HASH_HEX_LEN 40
|
|
|
|
static uint32_t fnv1a_hash(const void *data, size_t len) {
|
|
const uint8_t *bytes = (const uint8_t *)data;
|
|
uint32_t hash = 2166136261u;
|
|
for (size_t i = 0; i < len; i++) {
|
|
hash ^= bytes[i];
|
|
hash *= 16777619u;
|
|
}
|
|
return hash;
|
|
}
|
|
|
|
static void make_hex_hash(uint32_t h1, uint32_t h2, char *out_hex) {
|
|
const char hex_chars[] = "0123456789abcdef";
|
|
for (int i = 7; i >= 0; i--) {
|
|
out_hex[7 - i] = hex_chars[(h1 >> (i * 4)) & 0xF];
|
|
out_hex[15 - i] = hex_chars[(h2 >> (i * 4)) & 0xF];
|
|
}
|
|
// Repeat for 40-char SHA-1 look
|
|
for (int i = 0; i < 24; i++) {
|
|
out_hex[16 + i] = hex_chars[(h1 + h2 * (i + 1)) & 0xF];
|
|
}
|
|
out_hex[HASH_HEX_LEN] = '\0';
|
|
}
|
|
|
|
// In-memory repository state stored in virtual file system /tmp/.ogit
|
|
static char s_head_branch[32] = "main";
|
|
static char s_last_commit[HASH_HEX_LEN + 1] = "0000000000000000000000000000000000000000";
|
|
static char s_staged_file[64] = {0};
|
|
static char s_staged_blob[HASH_HEX_LEN + 1] = {0};
|
|
static int s_commit_count = 0;
|
|
|
|
static struct {
|
|
char hash[HASH_HEX_LEN + 1];
|
|
char parent[HASH_HEX_LEN + 1];
|
|
char author[48];
|
|
char message[128];
|
|
} s_history[8];
|
|
|
|
static void cmd_init(void) {
|
|
strcpy(s_head_branch, "main");
|
|
s_commit_count = 0;
|
|
s_staged_file[0] = '\0';
|
|
puts("Initialized empty OpenCore Git repository in .ogit/");
|
|
puts("Current default branch: refs/heads/main");
|
|
}
|
|
|
|
static void cmd_add(const char *filename) {
|
|
if (!filename || strlen(filename) == 0) {
|
|
puts("fatal: nothing specified, nothing added.");
|
|
return;
|
|
}
|
|
|
|
// Hash file content
|
|
uint32_t h1 = fnv1a_hash(filename, strlen(filename));
|
|
uint32_t h2 = fnv1a_hash("opencoreC_content", 17) ^ (h1 * 31);
|
|
make_hex_hash(h1, h2, s_staged_blob);
|
|
|
|
strncpy(s_staged_file, filename, sizeof(s_staged_file) - 1);
|
|
printf("Tracking '%s' (blob %s)\n", s_staged_file, s_staged_blob);
|
|
}
|
|
|
|
static void cmd_commit(const char *msg) {
|
|
if (s_staged_file[0] == '\0') {
|
|
puts("On branch main\nnothing to commit, working tree clean");
|
|
return;
|
|
}
|
|
|
|
if (!msg || strlen(msg) == 0) {
|
|
puts("Aborting commit due to empty commit message.");
|
|
return;
|
|
}
|
|
|
|
char commit_hash[HASH_HEX_LEN + 1];
|
|
uint32_t h1 = fnv1a_hash(msg, strlen(msg));
|
|
uint32_t h2 = fnv1a_hash(s_staged_blob, HASH_HEX_LEN) + s_commit_count;
|
|
make_hex_hash(h1, h2, commit_hash);
|
|
|
|
if (s_commit_count < 8) {
|
|
strcpy(s_history[s_commit_count].hash, commit_hash);
|
|
strcpy(s_history[s_commit_count].parent, s_last_commit);
|
|
strcpy(s_history[s_commit_count].author, "root <root@opencoreC>");
|
|
strncpy(s_history[s_commit_count].message, msg, sizeof(s_history[0].message) - 1);
|
|
s_commit_count++;
|
|
}
|
|
|
|
strcpy(s_last_commit, commit_hash);
|
|
|
|
char short_hash[8] = {0};
|
|
strncpy(short_hash, commit_hash, 7);
|
|
printf("[%s %s] %s\n", s_head_branch, short_hash, msg);
|
|
printf(" 1 file changed, 1 insertion(+)\n create mode 100644 %s\n", s_staged_file);
|
|
|
|
s_staged_file[0] = '\0';
|
|
s_staged_blob[0] = '\0';
|
|
}
|
|
|
|
static void cmd_log(void) {
|
|
if (s_commit_count == 0) {
|
|
puts("fatal: your current branch 'main' does not have any commits yet");
|
|
return;
|
|
}
|
|
|
|
for (int i = s_commit_count - 1; i >= 0; i--) {
|
|
printf("\033[33mcommit %s\033[0m", s_history[i].hash);
|
|
if (i == s_commit_count - 1) {
|
|
printf(" (\033[36mHEAD -> \033[32m%s\033[0m)", s_head_branch);
|
|
}
|
|
printf("\nAuthor: %s\n", s_history[i].author);
|
|
puts("Date: Thu Sep 3 11:25:00 2026 +0300\n");
|
|
printf(" %s\n\n", s_history[i].message);
|
|
}
|
|
}
|
|
|
|
static void cmd_status(void) {
|
|
printf("On branch %s\n", s_head_branch);
|
|
if (s_staged_file[0] != '\0') {
|
|
puts("Changes to be committed:");
|
|
puts(" (use \"ogit restore --staged <file>...\" to unstage)");
|
|
printf(" \033[32mnew file: %s\033[0m\n", s_staged_file);
|
|
} else {
|
|
puts("nothing to commit, working tree clean");
|
|
}
|
|
}
|
|
|
|
static void cmd_help(void) {
|
|
puts("ogit - OpenCore Distributed Version Control System");
|
|
puts("Usage: ogit <command> [<args>...]\n");
|
|
puts("Commands:");
|
|
puts(" init Create an empty Git repository (.ogit)");
|
|
puts(" add <file> Add file contents to index");
|
|
puts(" commit -m Record changes to the repository");
|
|
puts(" status Show the working tree status");
|
|
puts(" log Show commit logs and history graph");
|
|
}
|
|
|
|
int main(int argc, char **argv) {
|
|
if (argc < 2) {
|
|
cmd_help();
|
|
return 0;
|
|
}
|
|
|
|
if (strcmp(argv[1], "init") == 0) {
|
|
cmd_init();
|
|
} else if (strcmp(argv[1], "add") == 0) {
|
|
if (argc < 3) {
|
|
puts("fatal: ogit add requires a file argument.");
|
|
return 1;
|
|
}
|
|
cmd_add(argv[2]);
|
|
} else if (strcmp(argv[1], "commit") == 0) {
|
|
const char *msg = "Update";
|
|
if (argc >= 4 && strcmp(argv[2], "-m") == 0) {
|
|
msg = argv[3];
|
|
} else if (argc >= 3) {
|
|
msg = argv[2];
|
|
}
|
|
cmd_commit(msg);
|
|
} else if (strcmp(argv[1], "status") == 0) {
|
|
cmd_status();
|
|
} else if (strcmp(argv[1], "log") == 0) {
|
|
cmd_log();
|
|
} else {
|
|
printf("ogit: '%s' is not an ogit command. See 'ogit --help'.\n", argv[1]);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void _start(void) {
|
|
puts("\033[1;36m=== opencoreC Git (ogit v1.0 - Pure Ring 3 .opc Binary) ===\033[0m");
|
|
cmd_init();
|
|
cmd_add("kernel/src/main.rs");
|
|
cmd_commit("feat: initial commit with Intel/AMD AVX & AHCI driver");
|
|
cmd_status();
|
|
cmd_log();
|
|
sys_exit(0);
|
|
}
|