({
folderPath,
folderName,
folderId,
onPushed,
}: PushWorkspaceProps)
| 283 | } |
| 284 | |
| 285 | export function PushWorkspace({ |
| 286 | folderPath, |
| 287 | folderName, |
| 288 | folderId, |
| 289 | onPushed, |
| 290 | }: PushWorkspaceProps) { |
| 291 | const t = useTranslations("Folder.pushWindow") |
| 292 | const tLog = useTranslations("Folder.gitLogTab") |
| 293 | const { withCredentialRetry } = useGitCredential() |
| 294 | |
| 295 | const [pushInfoData, setPushInfoData] = useState<GitPushInfo | null>(null) |
| 296 | const [selectedRemote, setSelectedRemote] = useState<string | null>(null) |
| 297 | const [commits, setCommits] = useState<GitLogEntry[]>([]) |
| 298 | const [hasUpstream, setHasUpstream] = useState(true) |
| 299 | const [listLoading, setListLoading] = useState(false) |
| 300 | const [openByCommit, setOpenByCommit] = useState<Record<string, boolean>>({}) |
| 301 | const [pushing, setPushing] = useState(false) |
| 302 | |
| 303 | const [selectedFile, setSelectedFile] = useState<string | null>(null) |
| 304 | const [selectedCommit, setSelectedCommit] = useState<string | null>(null) |
| 305 | const [originalContent, setOriginalContent] = useState("") |
| 306 | const [modifiedContent, setModifiedContent] = useState("") |
| 307 | const [diffLoading, setDiffLoading] = useState(false) |
| 308 | |
| 309 | const unpushedCommits = useMemo( |
| 310 | () => commits.filter((c) => c.pushed === false), |
| 311 | [commits] |
| 312 | ) |
| 313 | |
| 314 | // Load push info (branch, remotes, tracking remote) |
| 315 | useEffect(() => { |
| 316 | gitPushInfo(folderPath) |
| 317 | .then((info) => { |
| 318 | setPushInfoData(info) |
| 319 | // Default to tracking remote or first remote |
| 320 | const defaultRemote = |
| 321 | info.tracking_remote ?? |
| 322 | (info.remotes.length > 0 ? info.remotes[0].name : null) |
| 323 | setSelectedRemote(defaultRemote) |
| 324 | }) |
| 325 | .catch((err) => { |
| 326 | toast.error(toErrorMessage(err)) |
| 327 | }) |
| 328 | }, [folderPath]) |
| 329 | |
| 330 | // Deduplicate remotes (git remote -v returns fetch + push entries) |
| 331 | const uniqueRemotes = useMemo(() => { |
| 332 | if (!pushInfoData) return [] |
| 333 | const seen = new Set<string>() |
| 334 | return pushInfoData.remotes.filter((r) => { |
| 335 | if (seen.has(r.name)) return false |
| 336 | seen.add(r.name) |
| 337 | return true |
| 338 | }) |
| 339 | }, [pushInfoData]) |
| 340 | |
| 341 | const loadCommits = useCallback( |
| 342 | async (remote?: string) => { |
nothing calls this directly
no test coverage detected