Skip to content

Commit a0c9b1a

Browse files
committed
feat: add "local only" badge for branches with no upstream
1 parent 7836c30 commit a0c9b1a

4 files changed

Lines changed: 36 additions & 2 deletions

File tree

wimygit-tauri/src-tauri/src/git/parsers/branch.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,23 @@ pub async fn get_branches(cwd: String) -> Result<Vec<BranchInfo>, String> {
139139
Ok(branches)
140140
}
141141

142+
/// Get local-only branches (local branches with no upstream configured)
143+
#[tauri::command]
144+
pub async fn get_local_only_branches(cwd: String) -> Result<Vec<String>, String> {
145+
let result = crate::git::run_git(
146+
vec!["branch".to_string(), "-vv".to_string()],
147+
cwd,
148+
)
149+
.await?;
150+
151+
let branches = parse_branches(&result.stdout);
152+
Ok(branches
153+
.into_iter()
154+
.filter(|b| b.upstream.is_none())
155+
.map(|b| b.name)
156+
.collect())
157+
}
158+
142159
/// Get stale remote tracking branches (deleted on remote but still tracked locally)
143160
#[tauri::command]
144161
pub async fn get_stale_remote_branches(cwd: String) -> Result<Vec<String>, String> {

wimygit-tauri/src-tauri/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ pub fn run() {
151151
// Git branch commands
152152
git::get_branches,
153153
git::get_current_branch,
154+
git::get_local_only_branches,
154155
git::get_stale_remote_branches,
155156
// Git remote commands
156157
git::get_remotes,

wimygit-tauri/src/components/tabs/HistoryTab.tsx

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import {
33
getHistory,
44
getCommitFiles,
55
getCommitParents,
6+
getLocalOnlyBranches,
67
getStaleBranches,
78
type CommitInfo,
89
type CommitFile,
@@ -203,6 +204,7 @@ export function HistoryTab({ repoPath, filePath, refreshKey, onRefresh, onFileSe
203204
const [fileCtxMenu, setFileCtxMenu] = useState<{ x: number; y: number; absolutePath: string } | null>(null);
204205
const [allBranches, setAllBranches] = useState(true);
205206
const [staleBranches, setStaleBranches] = useState<Set<string>>(new Set());
207+
const [localOnlyBranches, setLocalOnlyBranches] = useState<Set<string>>(new Set());
206208

207209
// ── load history ──────────────────────────────────────────────────────────
208210

@@ -235,6 +237,9 @@ export function HistoryTab({ repoPath, filePath, refreshKey, onRefresh, onFileSe
235237
getStaleBranches(repoPath)
236238
.then((branches) => setStaleBranches(new Set(branches)))
237239
.catch(() => setStaleBranches(new Set()));
240+
getLocalOnlyBranches(repoPath)
241+
.then((branches) => setLocalOnlyBranches(new Set(branches)))
242+
.catch(() => setLocalOnlyBranches(new Set()));
238243
}, [repoPath, refreshKey]);
239244

240245
// ── select commit → load files + parents ─────────────────────────────────
@@ -346,9 +351,10 @@ export function HistoryTab({ repoPath, filePath, refreshKey, onRefresh, onFileSe
346351
<div className="flex-1 min-w-0 flex items-center gap-1">
347352
{refs.map((r, i) => {
348353
const isStale = r.kind === "remote" && staleBranches.has(r.label);
354+
const isLocalOnly = (r.kind === "branch" || r.kind === "head") && localOnlyBranches.has(r.label);
349355
return (
350-
<span key={i} className={`inline-flex items-center shrink-0 leading-4 overflow-hidden ${isStale ? "rounded border border-red-950 bg-red-600" : "rounded"}`}>
351-
<span className={`text-[10px] px-1 leading-4 inline-flex items-center gap-0.5 ${isStale ? "bg-red-800 text-white" : REF_BADGE[r.kind]}`}>
356+
<span key={i} className={`inline-flex items-center shrink-0 leading-4 overflow-hidden rounded ${isStale ? "border border-red-950 bg-red-600" : isLocalOnly ? "border border-orange-950 bg-orange-500" : ""}`}>
357+
<span className={`text-[10px] px-1 leading-4 inline-flex items-center gap-0.5 ${isStale ? "bg-red-800 text-white" : isLocalOnly ? "bg-orange-700 text-white" : REF_BADGE[r.kind]}`}>
352358
{(r.kind === "head" || r.kind === "branch" || r.kind === "remote") && (
353359
<svg width="10" height="10" viewBox="0 0 16 16" fill="currentColor" className="shrink-0">
354360
<path d="M11.75 2.5a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5zm-2.25.75a2.25 2.25 0 1 1 3 2.122V6A2.5 2.5 0 0 1 10 8.5H6a1 1 0 0 0-1 1v1.128a2.251 2.251 0 1 1-1.5 0V5.372a2.25 2.25 0 1 1 1.5 0v1.836A2.493 2.493 0 0 1 6 7h4a1 1 0 0 0 1-1v-.628A2.25 2.25 0 0 1 9.5 3.25zM4.25 12a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5zM3.5 3.25a.75.75 0 1 1 1.5 0 .75.75 0 0 1-1.5 0z" />
@@ -367,6 +373,12 @@ export function HistoryTab({ repoPath, filePath, refreshKey, onRefresh, onFileSe
367373
<span className="text-[10px] px-1 leading-4 text-white">deleted on remote</span>
368374
</>
369375
)}
376+
{isLocalOnly && (
377+
<>
378+
<span className="self-stretch w-px bg-orange-950" />
379+
<span className="text-[10px] px-1 leading-4 text-white">local only</span>
380+
</>
381+
)}
370382
</span>
371383
);
372384
})}

wimygit-tauri/src/lib/git-api.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,10 @@ export async function getCurrentBranch(cwd: string): Promise<string> {
9494
return invoke<string>("get_current_branch", { cwd });
9595
}
9696

97+
export async function getLocalOnlyBranches(cwd: string): Promise<string[]> {
98+
return invoke<string[]>("get_local_only_branches", { cwd });
99+
}
100+
97101
export async function getStaleBranches(cwd: string): Promise<string[]> {
98102
return invoke<string[]>("get_stale_remote_branches", { cwd });
99103
}

0 commit comments

Comments
 (0)