fixed incorrect fetching for git branch status

the ahead and behind wasnt working in the branch view, also pulling didnt work so the entire feature was broken, this is now fixed and works as expected atleast for the small test case i gave it
This commit is contained in:
2025-06-08 22:01:56 +02:00
parent 031d132549
commit 5695b574ca
3 changed files with 69 additions and 57 deletions

View File

@@ -2169,13 +2169,14 @@ void update_sync_status(NCursesDiffViewer *viewer) {
time_t current_time = time(NULL);
// Check if it's time to sync (every 30 seconds)
if (current_time - viewer->last_sync_time >= 30) {
if (current_time - viewer->last_sync_time >= 60) {
viewer->sync_status = SYNC_STATUS_SYNCING_APPEARING;
viewer->last_sync_time = current_time;
viewer->animation_frame = 0;
viewer->text_char_count = 0;
// Do the actual sync work immediately
// Do the actual sync work immediately - fetch remote changes quietly
system("git fetch --all --quiet >/dev/null 2>&1");
get_ncurses_changed_files(viewer);
// Only reload file diff if we're actually in a file-related mode
@@ -2187,6 +2188,7 @@ void update_sync_status(NCursesDiffViewer *viewer) {
}
get_commit_history(viewer);
get_ncurses_git_branches(viewer); // This will now show updated branch status
// If we're in commit view mode, reload the current commit
if (viewer->current_mode == NCURSES_MODE_COMMIT_VIEW &&
@@ -3417,7 +3419,11 @@ int get_ncurses_git_branches(NCursesDiffViewer *viewer) {
return 0;
viewer->branch_count = 0;
// First, fetch from all remotes to get latest status (like lazygit does)
system("git fetch --all --quiet >/dev/null 2>&1");
// Use git branch (without -a) to only show local branches
FILE *fp = popen("git branch 2>/dev/null", "r");
if (!fp) {
return 0;
@@ -3425,80 +3431,86 @@ int get_ncurses_git_branches(NCursesDiffViewer *viewer) {
char line[512];
while (fgets(line, sizeof(line), fp) && viewer->branch_count < MAX_BRANCHES) {
// Remove newline
line[strcspn(line, "\n")] = 0;
if (strlen(line) == 0)
continue;
// Skip empty lines
if (strlen(line) == 0) continue;
// Check if this is the current branch (starts with *)
int is_current = 0;
char *branch_name = line;
while (*branch_name == ' ')
branch_name++;
// Skip leading spaces
while (*branch_name == ' ') branch_name++;
if (*branch_name == '*') {
is_current = 1;
branch_name++;
while (*branch_name == ' ')
branch_name++;
branch_name++; // Skip the *
while (*branch_name == ' ') branch_name++; // Skip spaces after *
}
// Skip any lines that contain "->" (symbolic references like origin/HEAD -> origin/main)
if (strstr(branch_name, "->") != NULL) {
continue;
}
strncpy(viewer->branches[viewer->branch_count].name, branch_name,
// Skip remote branches (shouldn't appear with git branch, but just in case)
if (strncmp(branch_name, "remotes/", 8) == 0) {
continue;
}
// Copy branch name
strncpy(viewer->branches[viewer->branch_count].name, branch_name,
MAX_BRANCHNAME_LEN - 1);
viewer->branches[viewer->branch_count].name[MAX_BRANCHNAME_LEN - 1] = '\0';
viewer->branches[viewer->branch_count].status = is_current;
// Initialize ahead/behind counts
viewer->branches[viewer->branch_count].commits_ahead = 0;
viewer->branches[viewer->branch_count].commits_behind = 0;
char remote_check_cmd[512];
snprintf(remote_check_cmd, sizeof(remote_check_cmd),
"git is-remote --heads origin %s 2>/dev/null", branch_name);
FILE *remote_fp = popen(remote_check_cmd, "r");
if (remote_fp) {
char remote_result[256];
int has_remote =
(fgets(remote_result, sizeof(remote_result), remote_fp) != NULL);
pclose(remote_fp);
if (has_remote) {
char ahead_cmd[512];
snprintf(ahead_cmd, sizeof(ahead_cmd),
"git rev-list --count origin/%s..%s 2>/dev/null", branch_name,
branch_name);
FILE *ahead_fp = popen(ahead_cmd, "r");
if (ahead_fp) {
char ahead_count[32];
if (fgets(ahead_count, sizeof(ahead_count), ahead_fp) != NULL) {
viewer->branches[viewer->branch_count].commits_ahead =
atoi(ahead_count);
}
pclose(ahead_fp);
// Get ahead/behind status using the exact method lazygit uses
// First check if remote branch exists
char remote_exists_cmd[512];
snprintf(remote_exists_cmd, sizeof(remote_exists_cmd),
"git show-ref --verify --quiet refs/remotes/origin/%s", branch_name);
if (system(remote_exists_cmd) == 0) {
// Remote branch exists, now get ahead/behind counts
// Get commits behind (how many commits remote has that we don't)
char behind_cmd[512];
snprintf(behind_cmd, sizeof(behind_cmd),
"git rev-list --count %s..origin/%s 2>/dev/null", branch_name, branch_name);
FILE *behind_fp = popen(behind_cmd, "r");
if (behind_fp) {
char behind_count[32];
if (fgets(behind_count, sizeof(behind_count), behind_fp) != NULL) {
viewer->branches[viewer->branch_count].commits_behind = atoi(behind_count);
}
char behind_cmd[512];
snprintf(behind_cmd, sizeof(behind_cmd),
"git rev-list --count %s--origin/%s 2>/dev/null", branch_name,
branch_name);
FILE *behind_fp = popen(behind_cmd, "r");
if (behind_fp) {
char behind_count[32];
if (fgets(behind_count, sizeof(behind_count), behind_fp) != NULL) {
viewer->branches[viewer->branch_count].commits_behind =
atoi(behind_count);
}
pclose(behind_fp);
pclose(behind_fp);
}
// Get commits ahead (how many commits we have that remote doesn't)
char ahead_cmd[512];
snprintf(ahead_cmd, sizeof(ahead_cmd),
"git rev-list --count origin/%s..%s 2>/dev/null", branch_name, branch_name);
FILE *ahead_fp = popen(ahead_cmd, "r");
if (ahead_fp) {
char ahead_count[32];
if (fgets(ahead_count, sizeof(ahead_count), ahead_fp) != NULL) {
viewer->branches[viewer->branch_count].commits_ahead = atoi(ahead_count);
}
pclose(ahead_fp);
}
}
viewer->branch_count++;
}
pclose(fp);
return 1;
}

Binary file not shown.

BIN
shell

Binary file not shown.