mirror of
https://github.com/Savapitech/42sh.git
synced 2026-03-18 21:50:35 +01:00
Add git integration
This commit is contained in:
90
src/git.c
Normal file
90
src/git.c
Normal file
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
** EPITECH PROJECT, 2025
|
||||
** __
|
||||
** File description:
|
||||
** _
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "git.h"
|
||||
|
||||
static
|
||||
int read_head_branch(char *branch, size_t size)
|
||||
{
|
||||
FILE *f = fopen(".git/HEAD", "r");
|
||||
char line[MAX_LINE];
|
||||
|
||||
if (!f)
|
||||
return -1;
|
||||
if (!fgets(line, sizeof(line), f)) {
|
||||
fclose(f);
|
||||
return -1;
|
||||
}
|
||||
fclose(f);
|
||||
if (strncmp(line, "ref: refs/heads/", 16) != 0)
|
||||
return -1;
|
||||
strncpy(branch, line + 16, size - 1);
|
||||
branch[strcspn(branch, "\n")] = '\0';
|
||||
return 0;
|
||||
}
|
||||
|
||||
static
|
||||
int read_git_ref(const char *path, char *hash, size_t size)
|
||||
{
|
||||
FILE *f = fopen(path, "r");
|
||||
|
||||
if (!f)
|
||||
return -1;
|
||||
if (!fgets(hash, size, f)) {
|
||||
fclose(f);
|
||||
return -1;
|
||||
}
|
||||
fclose(f);
|
||||
hash[strcspn(hash, "\n")] = '\0';
|
||||
return 0;
|
||||
}
|
||||
|
||||
static
|
||||
int compare_hashes(const char *local, const char *remote)
|
||||
{
|
||||
if (strcmp(local, remote) == 0)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static
|
||||
int analyze_divergence(git_status_t *status)
|
||||
{
|
||||
if (compare_hashes(status->local_hash, status->remote_hash) == 0) {
|
||||
status->ahead = 0;
|
||||
status->behind = 0;
|
||||
} else {
|
||||
status->ahead = 1;
|
||||
status->behind = 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool get_git_status(git_status_t *status)
|
||||
{
|
||||
char local_path[256];
|
||||
char remote_path[256];
|
||||
|
||||
if (read_head_branch(status->branch, sizeof(status->branch)) != 0)
|
||||
return false;
|
||||
snprintf(local_path, sizeof(local_path),
|
||||
".git/refs/heads/%s", status->branch);
|
||||
snprintf(remote_path, sizeof(remote_path),
|
||||
".git/refs/remotes/origin/%s", status->branch);
|
||||
if (read_git_ref(local_path, status->local_hash,
|
||||
sizeof(status->local_hash)) != 0)
|
||||
return false;
|
||||
if (read_git_ref(remote_path, status->remote_hash,
|
||||
sizeof(status->remote_hash)) != 0)
|
||||
return false;
|
||||
analyze_divergence(status);
|
||||
return true;
|
||||
}
|
||||
23
src/git.h
Normal file
23
src/git.h
Normal file
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
** EPITECH PROJECT, 2025
|
||||
** __
|
||||
** File description:
|
||||
** _
|
||||
*/
|
||||
|
||||
#ifndef GIT_H
|
||||
#define GIT_H
|
||||
#define MAX_LINE 256
|
||||
#define MAX_BRANCH 128
|
||||
#define HASH_LEN 41
|
||||
|
||||
typedef struct {
|
||||
char branch[MAX_BRANCH];
|
||||
char local_hash[HASH_LEN];
|
||||
char remote_hash[HASH_LEN];
|
||||
int ahead;
|
||||
int behind;
|
||||
} git_status_t;
|
||||
|
||||
bool get_git_status(git_status_t *status);
|
||||
#endif /* GIT_H */
|
||||
@@ -10,12 +10,13 @@
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "ast.h"
|
||||
#include "common.h"
|
||||
#include "debug.h"
|
||||
#include "git.h"
|
||||
#include "repl.h"
|
||||
#include "repl/key_handler.h"
|
||||
#include "u_str.h"
|
||||
#include "visitor.h"
|
||||
#include "vt100_esc_codes.h"
|
||||
|
||||
const key_handler_t KEY_HANDLERS[] = {
|
||||
@@ -53,20 +54,30 @@ void print_second_shell_prompt(exec_ctx_t *ec)
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
void print_git_prompt(git_status_t *gs)
|
||||
{
|
||||
if (!gs->ahead && !gs->behind)
|
||||
printf(BLUE " [" RED "%s" BLUE "] " RESET "-", gs->branch);
|
||||
}
|
||||
|
||||
static
|
||||
void print_prompt(env_t *env_ptr, char *hostname, exec_ctx_t *ec)
|
||||
{
|
||||
char const *username = get_env_value(env_ptr, "USER");
|
||||
git_status_t gs = {0};
|
||||
|
||||
if (username == nullptr)
|
||||
username = "?";
|
||||
printf(BLUE PROMPT_HEADER GREEN "%s" RESET "@" CYAN "%s" BLUE "] "
|
||||
RESET "-" BLUE " [" RESET "%s" BLUE
|
||||
"] " RESET "-" BLUE " [" YELLOW "%d" BLUE
|
||||
"]\n└─[" PURPLE "%s%s" BLUE "] " RESET,
|
||||
"] " RESET "-",
|
||||
username,
|
||||
hostname,
|
||||
get_env_value(env_ptr, "PWD"),
|
||||
get_env_value(env_ptr, "PWD"));
|
||||
if (get_git_status(&gs))
|
||||
print_git_prompt(&gs);
|
||||
printf(BLUE " [" YELLOW "%d" BLUE "]\n└─[" PURPLE "%s%s" BLUE "] " RESET,
|
||||
ec->history_command->sz + 1,
|
||||
ec->history->last_exit_code == 0 ? "" : RED,
|
||||
strcmp(username, "root") == 0 ? "#" : "$");
|
||||
|
||||
Reference in New Issue
Block a user