Skip to content

Commit 29cb0b0

Browse files
committed
feat: push local-only branches from history context menu
1 parent 67f6935 commit 29cb0b0

1 file changed

Lines changed: 37 additions & 2 deletions

File tree

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

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {
55
getCommitParents,
66
getLocalOnlyBranches,
77
getStaleBranches,
8+
getRemotes,
89
type CommitInfo,
910
type CommitFile,
1011
type SelectedDiffInfo,
@@ -79,11 +80,12 @@ interface ContextMenuProps {
7980
x: number; y: number;
8081
commit: CommitInfo;
8182
repoPath: string;
83+
localOnlyBranches: Set<string>;
8284
onClose: () => void;
8385
onRefresh: () => void;
8486
}
8587

86-
function ContextMenu({ x, y, commit, repoPath, onClose, onRefresh }: ContextMenuProps) {
88+
function ContextMenu({ x, y, commit, repoPath, localOnlyBranches, onClose, onRefresh }: ContextMenuProps) {
8789
const ref = useRef<HTMLDivElement>(null);
8890

8991
useEffect(() => {
@@ -98,6 +100,10 @@ function ContextMenu({ x, y, commit, repoPath, onClose, onRefresh }: ContextMenu
98100
catch (e) { alert(String(e)); }
99101
};
100102

103+
const localOnlyRefsOnCommit = parseRefNames(commit.ref_names)
104+
.filter(r => (r.kind === "branch" || r.kind === "head") && localOnlyBranches.has(r.label))
105+
.map(r => r.label);
106+
101107
const items: { label: string; action: () => void; danger?: boolean }[] = [
102108
{ label: "Checkout", action: () => run(["checkout", commit.hash]) },
103109
{
@@ -131,6 +137,34 @@ function ContextMenu({ x, y, commit, repoPath, onClose, onRefresh }: ContextMenu
131137
{ label: "──", action: () => { } },
132138
{ label: "Copy Commit ID", action: () => { onClose(); navigator.clipboard.writeText(commit.hash).catch(() => { }); } },
133139
{ label: "Copy Short ID", action: () => { onClose(); navigator.clipboard.writeText(commit.short_hash).catch(() => { }); } },
140+
...(localOnlyRefsOnCommit.length > 0 ? [
141+
{ label: "──", action: () => { } },
142+
...localOnlyRefsOnCommit.map(branch => ({
143+
label: `Push "${branch}" to remote…`,
144+
action: async () => {
145+
onClose();
146+
let remotes: { name: string }[];
147+
try { remotes = await getRemotes(repoPath); }
148+
catch { alert("Failed to get remotes."); return; }
149+
if (remotes.length === 0) { alert("No remotes configured."); return; }
150+
151+
let remote: string;
152+
if (remotes.length === 1) {
153+
remote = remotes[0].name;
154+
} else {
155+
const names = remotes.map(r => r.name).join(", ");
156+
const input = prompt(`Push to which remote? (${names})`, remotes[0].name);
157+
if (!input?.trim()) return;
158+
remote = input.trim();
159+
}
160+
161+
try {
162+
await invoke("run_git_simple", { args: ["push", "-u", remote, branch], cwd: repoPath });
163+
onRefresh();
164+
} catch (e) { alert(String(e)); }
165+
},
166+
})),
167+
] : []),
134168
];
135169

136170
return (
@@ -495,7 +529,8 @@ export function HistoryTab({ repoPath, filePath, refreshKey, onRefresh, onFileSe
495529
)}
496530
{contextMenu && (
497531
<ContextMenu x={contextMenu.x} y={contextMenu.y} commit={contextMenu.commit}
498-
repoPath={repoPath} onClose={() => setContextMenu(null)}
532+
repoPath={repoPath} localOnlyBranches={localOnlyBranches}
533+
onClose={() => setContextMenu(null)}
499534
onRefresh={() => { setContextMenu(null); onRefresh(); }} />
500535
)}
501536
</div>

0 commit comments

Comments
 (0)