Skip to content

feat: Add VS Code-style Source Control panel with AI commit messages#44

Open
enesteve0 wants to merge 7 commits into
collabs-inc:devfrom
enesteve0:dev
Open

feat: Add VS Code-style Source Control panel with AI commit messages#44
enesteve0 wants to merge 7 commits into
collabs-inc:devfrom
enesteve0:dev

Conversation

@enesteve0

@enesteve0 enesteve0 commented Mar 23, 2026

Copy link
Copy Markdown

Summary

VS Code–style Source Control in the navigator SCM tab: workspace-scoped git IPC, stage/commit/sync, branches/tags/stashes, merge conflicts, interactive rebase, submodules, LFS badges, and AI commit messages.

Phase 0 — Foundation

  • Workspace-scoped git — All git:* IPC/preload/API calls take workspacePath for multi-workspace repos
  • Porcelain v2 statusrepoState (clean, merging, rebasing, interactive-rebase, cherry-picking, reverting), ahead/behind, selected remote
  • Changes UI — Staged / Changes / Merge Changes; stage & unstage all; discard all (confirm); commit blocked while conflicts exist
  • Commit actions — Auto-stage on commit, Amend, Commit & Push, Commit & Sync
  • Sync — Push / Pull / Sync with badges; remote picker; Publish Branch
  • Branches & tags — Switch/create/delete; checkout tags (detached HEAD warning)
  • Stashes — Save, pop, apply, drop
  • Initialize repository when workspace is not a git repo
  • AI commit messages — CLI agents (Claude Code, Codex, Gemini) or Settings → AI API key fallback

Phase 2 — Advanced SCM

  • Viewer diff — Click changed file → Monaco diff in viewer tile; Compare with Branch
  • Clone & remotes — Clone Repository; manage remotes (add/remove)
  • Merge / rebase banners — Continue / Abort during merge or rebase; conflict resolution (Accept Current / Incoming / Mark Resolved)
  • Context menus — File: stage, unstage, discard, open changes, reveal; SCM header: refresh, pull, push, open .gitignore
  • History — Commit list with revert / cherry-pick / reset; Open Graph replay
  • Interactive rebase — Todo list with reorder/actions; Continue / Abort / Skip
  • Submodules — List from .gitmodules; Update
  • Worktrees — Listed when multiple exist
  • Partial staging — Stage hunk from diff viewer (when hunks available)
  • Signing & config — Sign commit when commit.gpgsign set; Settings → Git read-only user.name, email, credential.helper
  • Git LFSLFS badge on changed files tracked via .gitattributes filter

Architecture

  • git-source-control.ts — porcelain v2 (-z), merge/rebase/submodule/LFS helpers
  • ipc-git.ts — workspace path resolution for all handlers
  • UI: packages/components/src/SourceControl/

QA fixtures

Tracked scripts under fixtures/git/; run ./fixtures/git/setup-all.sh then open generated workspaces:

Fixture Covers
fixtures/git/dirty-worktree Staged/unstaged/untracked, tags, stashes, sync bar
fixtures/git/merge-conflict Merge banner, conflict markers
fixtures/git/submodule Submodule section
fixtures/git/rebase-todo Interactive rebase paused at break

Manual checklist: collab-electron/docs/SCM_TEST_MATRIX.md (Phases A–I). Automated fixture results: collab-electron/docs/screenshots/scm/QA_RESULTS.md.

Screenshots

Dark mode captures from production SCM components via a Vite + Playwright harness, with a local git bridge calling git-source-control.ts against real fixtures/git/ repos (not mocked status). Regenerate: collab-electron/docs/screenshots/scm/README.md.

01 — SCM overview 02 — Commit box
01 SCM overview 02 Commit box
03 — Branch picker 04 — Sync / remotes
03 Branch picker 04 Sync remotes
05 — Merge conflicts 06 — History
05 Merge conflicts 06 History
07 — Interactive rebase 08 — Stash
07 Interactive rebase 08 Stash
09 — Viewer diff 10 — Settings → Git
09 Viewer diff 10 Settings Git

Test plan

  • Single workspace: stage, commit, push, pull, sync, publish, branches, stash
  • Two workspaces: SCM for A must not show B’s changes
  • fixtures/git/merge-conflict: Merge Changes; commit blocked until resolved
  • fixtures/git/rebase-todo: interactive rebase panel; Continue / Abort
  • fixtures/git/submodule: Submodules section; Update
  • LFS repo: LFS badge on matching paths in Changes
  • Amend, init repo, AI commit message (CLI + Settings key)
  • npm run build in collab-electron passes
  • Fixture smoke: bun test src/main/git-source-control.fixture.test.ts (see QA_RESULTS.md)

Copilot AI review requested due to automatic review settings March 23, 2026 20:11
@cla-bot

cla-bot Bot commented Mar 23, 2026

Copy link
Copy Markdown

Thanks for the pull request! It looks like @enesteve0 haven't signed our Contributor License Agreement yet. Please read and agree to the CLA, then let us know here.

@enesteve0

Copy link
Copy Markdown
Author

I have read and agree to the CLA.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a VS Code-style Source Control (SCM) view to the app’s navigator, backed by new main-process git IPC handlers and optional AI-powered commit message generation (CLI-first with API-key fallback). Also introduces an AI Settings pane for configuring the fallback API key.

Changes:

  • Add new scm navigator mode that renders a full Source Control sidebar (status, staging, commit, sync, branch picker, inline diff).
  • Implement git IPC surface area (status/stage/unstage/discard/commit/diff, sync, branches, stash, show-file) in the main process and expose it via preload + shared window API typings.
  • Add AI commit message generation via installed CLI agents, with an Anthropic API fallback + Settings UI for validating/saving an API key.

Reviewed changes

Copilot reviewed 19 out of 20 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
collab-electron/src/windows/settings/src/App.tsx Adds an “AI” settings pane for API key validation/storage.
collab-electron/src/windows/nav/src/App.tsx Adds scm as a third navigator tab and renders the SCM view.
collab-electron/src/preload/universal.ts Exposes new git:* and ai:* IPC APIs to renderer.
collab-electron/src/main/ipc.ts Registers IPC handlers for git operations + AI commit generation.
collab-electron/src/main/integrations.ts Exports agentDetected for reuse by AI commit generation.
collab-electron/src/main/index.ts Prevents renderer pref:get reads of ai.apiKey.
collab-electron/src/main/git-source-control.ts Implements git operations via execFile("git", ...).
collab-electron/src/main/ai-commit.ts Implements commit-message generation via CLI agents or Anthropic API.
collab-electron/packages/shared/src/window-api.d.ts Extends window.api typing for git/AI features.
collab-electron/packages/shared/src/git-types.ts Defines shared git status/branch/remote/stash types.
collab-electron/packages/components/src/SourceControl/SourceControlView.tsx Main SCM UI view (status, staging, commit, sync, branch picker, diff).
collab-electron/packages/components/src/SourceControl/CommitBox.tsx Commit message input + commit + AI-generate controls.
collab-electron/packages/components/src/SourceControl/ChangeSectionHeader.tsx Collapsible section header for staged/unstaged lists.
collab-electron/packages/components/src/SourceControl/FileChangeRow.tsx File row UI with stage/unstage/discard actions.
collab-electron/packages/components/src/SourceControl/SyncBar.tsx Push/pull/sync/publish controls with ahead/behind badges.
collab-electron/packages/components/src/SourceControl/BranchPicker.tsx Branch switch/create/delete dropdown UI.
collab-electron/packages/components/src/SourceControl/DiffView.tsx Inline diff viewer for a selected file.
collab-electron/packages/components/src/SourceControl/StashSection.tsx Stash UI section component (added, not wired into main view here).
collab-electron/packages/components/src/SourceControl/SourceControl.css Styling for the SCM panel components.
collab-electron/packages/components/src/SourceControl/index.ts Re-exports SourceControlView.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +255 to +263
api.getPref("ai.hasKey").then(() => {
// We can't read the key (guarded), so check via aiHasKey
(window as unknown as { api: { aiHasKey: () => Promise<boolean> } }).api
.aiHasKey()
.then((has: boolean) => {
setHasExistingKey(has);
})
.catch(() => {});
}).catch(() => {});

Copilot AI Mar 23, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AiPane calls window.api.aiHasKey() but no aiHasKey API is exposed in the preload typings/implementation, and api.getPref("ai.hasKey") appears to reference a pref key that doesn’t exist. As written this will throw at runtime and hasExistingKey will never be set. Add an explicit IPC/preload API (e.g., ai:has-key) that returns a boolean based on the stored pref, and use that directly here (or remove the unused ai.hasKey pref lookup).

Suggested change
api.getPref("ai.hasKey").then(() => {
// We can't read the key (guarded), so check via aiHasKey
(window as unknown as { api: { aiHasKey: () => Promise<boolean> } }).api
.aiHasKey()
.then((has: boolean) => {
setHasExistingKey(has);
})
.catch(() => {});
}).catch(() => {});
api
.getPref("ai.apiKey")
.then((storedKey: unknown) => {
if (typeof storedKey === "string" && storedKey.trim() !== "") {
setHasExistingKey(true);
} else {
setHasExistingKey(false);
}
})
.catch(() => {
setHasExistingKey(false);
});

Copilot uses AI. Check for mistakes.
Comment on lines +174 to +183
const handleCommit = useCallback(async () => {
if (!commitMessage.trim()) return;
setCommitting(true);
setError(null);
setSuccess(null);
try {
// Auto-stage all if nothing is staged (VS Code behavior)
if (!status || status.staged.length === 0) {
await window.api.gitStageAll();
}

Copilot AI Mar 23, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

handleCommit closes over status but its useCallback dependency list doesn’t include status. This can lead to stale state (e.g., auto-staging all even when there are staged changes, or using an old branch state) depending on when the callback was created. Add status (and any other referenced state) to the dependency array or refactor to read the latest status inside the callback.

Copilot uses AI. Check for mistakes.
Comment on lines +405 to +414
const parts = line.split("|");
const name = parts[0]!.trim();
const isCurrent = parts[1]?.trim() === "*";
const upstream = parts[2]?.trim() || undefined;
const isRemote = name.startsWith("origin/") || name.includes("/");

// Skip HEAD pointers like "origin/HEAD"
if (name.endsWith("/HEAD")) continue;

branches.push({ name, current: isCurrent, upstream, isRemote });

Copilot AI Mar 23, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

gitBranches determines isRemote with name.startsWith("origin/") || name.includes("/"), which misclassifies local branches that contain slashes (e.g. feature/foo) as remote. This breaks grouping in the branch picker and prevents local-only actions like delete. Derive isRemote from the actual ref namespace returned by git branch -a (e.g., refs under remotes/) or use a more precise prefix check than includes("/").

Copilot uses AI. Check for mistakes.
Comment on lines +262 to +270
for (const line of statusRaw.split("\n")) {
if (!line) continue;
const status = line.slice(0, 2);
const filePath = line.slice(3);
if (status === "??") {
untrackedPaths.push(filePath);
} else {
trackedPaths.push(filePath);
}

Copilot AI Mar 23, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

gitDiscard parses git status --porcelain output with const filePath = line.slice(3). For renames, porcelain uses the old -> new format, so filePath becomes old -> new and later git checkout -- ... will fail. Consider using git status -z for unambiguous parsing, or explicitly handle the rename arrow format (extract the destination path) before building trackedPaths/untrackedPaths.

Copilot uses AI. Check for mistakes.
Comment on lines +77 to +80
const raw = await git(
["status", "--porcelain=v2", "--branch", "-uall"],
cwd,
);

Copilot AI Mar 23, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

gitStatus parses git status --porcelain=v2 --branch by splitting on spaces / tabs, but without -z the porcelain format can C-quote/escape paths (depending on core.quotePath) and paths with spaces/special chars won’t round-trip correctly into later git commands. Using --porcelain=v2 -z (and parsing NUL-delimited records) avoids quoting/escaping edge cases and makes rename parsing more reliable.

Copilot uses AI. Check for mistakes.
Comment thread collab-electron/src/main/ai-commit.ts Outdated
Comment on lines +128 to +142
result = await runCliAgent("claude", ["-p", fullPrompt], "");
break;
case "codex":
result = await runCliAgent(
"codex",
["--quiet", "--prompt", fullPrompt],
"",
);
break;
case "gemini":
result = await runCliAgent(
"gemini",
["--prompt", fullPrompt],
"",
);

Copilot AI Mar 23, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

generateCommitMessageViaCli passes the entire fullPrompt (which includes up to 100k chars of diff) as a command-line argument (claude -p <prompt>, codex --prompt <prompt>, gemini --prompt <prompt>). This is very likely to exceed OS argv limits (notably Windows’ ~32k limit) and will fail for moderately sized diffs. Prefer sending the prompt via stdin (or a temp file) if the CLI supports it, and keep argv args small.

Suggested change
result = await runCliAgent("claude", ["-p", fullPrompt], "");
break;
case "codex":
result = await runCliAgent(
"codex",
["--quiet", "--prompt", fullPrompt],
"",
);
break;
case "gemini":
result = await runCliAgent(
"gemini",
["--prompt", fullPrompt],
"",
);
// Send the full prompt via stdin instead of as a command-line argument
result = await runCliAgent("claude", [], fullPrompt);
break;
case "codex":
// Keep non-prompt flags small and pass the prompt through stdin
result = await runCliAgent("codex", ["--quiet"], fullPrompt);
break;
case "gemini":
// Pass the prompt through stdin to avoid oversized argv entries
result = await runCliAgent("gemini", [], fullPrompt);

Copilot uses AI. Check for mistakes.
@yiliush

yiliush commented Mar 27, 2026

Copy link
Copy Markdown
Contributor

Code review

Found 7 issues:

  1. AiPane calls window.api.aiHasKey() which does not exist -- it was renamed to aiCanGenerate in a prior commit but this component was not updated. The call throws a TypeError silently swallowed by .catch(() => {}). The "existing key saved" UI state never works. Additionally, api.getPref("ai.hasKey") reads a pref key that is never written (the actual key is "ai.apiKey").

https://github.com/collaborator-ai/collab-public/blob/ff8a9f6053b598669d4a50267ecb6c7de143c92d/collab-electron/src/windows/settings/src/App.tsx#L254-L263

  1. BranchPicker.loadBranches silently catches errors and resets branches to []. The component accepts an onError prop and uses it in every other handler (handleSwitch, handleCreate, handleDelete), but not here.

https://github.com/collaborator-ai/collab-public/blob/ff8a9f6053b598669d4a50267ecb6c7de143c92d/collab-electron/packages/components/src/SourceControl/BranchPicker.tsx#L42-L49

  1. StashSection.loadStashes has the same pattern -- silently catches errors and resets stashes to [] while the component has onError and uses it everywhere else.

https://github.com/collaborator-ai/collab-public/blob/ff8a9f6053b598669d4a50267ecb6c7de143c92d/collab-electron/packages/components/src/SourceControl/StashSection.tsx#L33-L40

  1. SourceControlView swallows the aiCanGenerate() IPC error with .catch(() => {}).

https://github.com/collaborator-ai/collab-public/blob/ff8a9f6053b598669d4a50267ecb6c7de143c92d/collab-electron/packages/components/src/SourceControl/SourceControlView.tsx#L77-L84

  1. handlePush, handlePull, handleSync, and handlePublish are async functions that await IPC calls but have no try/catch. Git network operations (push rejected, pull merge conflict, auth failure) will produce unhandled promise rejections with no user-visible error. Every other handler in this component wraps IPC calls in try/catch and calls setError().

https://github.com/collaborator-ai/collab-public/blob/ff8a9f6053b598669d4a50267ecb6c7de143c92d/collab-electron/packages/components/src/SourceControl/SourceControlView.tsx#L222-L248

  1. git:generate-commit-message handler destroys the user's staging state. When the diff is empty, it calls gitStageAll() then gitUnstageAll() to capture a diff from untracked files. But the guard (status.untracked.length > 0 || status.unstaged.length > 0) fires even when status.staged.length > 0, meaning a user with a mix of staged and unstaged files will have their curated index wiped by gitUnstageAll.

https://github.com/collaborator-ai/collab-public/blob/ff8a9f6053b598669d4a50267ecb6c7de143c92d/collab-electron/src/main/ipc.ts#L1355-L1375

  1. CommitBox accepts a hasStagedChanges prop but never uses it. canCommit gates only on hasAnyChanges, so the commit button is enabled even when no files are staged. Either the prop should influence the logic or be removed.

https://github.com/collaborator-ai/collab-public/blob/ff8a9f6053b598669d4a50267ecb6c7de143c92d/collab-electron/packages/components/src/SourceControl/CommitBox.tsx#L11-L34

🤖 Generated with Claude Code

- If this code review was useful, please react with 👍. Otherwise, react with 👎.

@yiliush

yiliush commented Mar 27, 2026

Copy link
Copy Markdown
Contributor

Hey, human here. This is a great PR; thanks so much for contributing. I'll work to fix up the issues that the agent identified, as well and syncing the styling to our internal system.

Sorry about the CLA confusion, we're still figuring this part of the process out. The bot might need you to comment again with a specific message.

@cla-bot check

@cla-bot

cla-bot Bot commented Mar 27, 2026

Copy link
Copy Markdown

Thanks for the pull request! It looks like @enesteve0 haven't signed our Contributor License Agreement yet.

Please read the CLA, then sign by posting the following comment on this PR:

I have read the Contributor License Agreement (CLA) and hereby sign the CLA.

After signing, comment @cla-bot check to re-verify.

@cla-bot

cla-bot Bot commented Mar 27, 2026

Copy link
Copy Markdown

The cla-bot has been summoned, and re-checked this pull request!

@enesteve0

Copy link
Copy Markdown
Author

Hey, human here. This is a great PR; thanks so much for contributing. I'll work to fix up the issues that the agent identified, as well and syncing the styling to our internal system.

Sorry about the CLA confusion, we're still figuring this part of the process out. The bot might need you to comment again with a specific message.

@cla-bot check

Thank you so much, it really means a lot. I was already enjoying the project, and the main thing I personally felt was missing was being able to commit, push, and handle git workflow directly in the app, so I decided to take a shot at adding it. I’m really glad it seems helpful.

And no worries about the CLA mix-up — happy to resend the exact comment if needed.

@cla-bot

cla-bot Bot commented Mar 27, 2026

Copy link
Copy Markdown

Thanks for the pull request! It looks like @enesteve0 haven't signed our Contributor License Agreement yet.

Please read the CLA, then sign by posting the following comment on this PR:

I have read the Contributor License Agreement (CLA) and hereby sign the CLA.

After signing, comment @cla-bot check to re-verify.

@cla-bot

cla-bot Bot commented Mar 27, 2026

Copy link
Copy Markdown

The cla-bot has been summoned, and re-checked this pull request!

@enesteve0

Copy link
Copy Markdown
Author

I have read the Contributor License Agreement (CLA) and hereby sign the CLA.

@yiliush

yiliush commented Mar 27, 2026

Copy link
Copy Markdown
Contributor

@cla-bot check

@cla-bot

cla-bot Bot commented Mar 27, 2026

Copy link
Copy Markdown

Thanks for the pull request! It looks like @enesteve0 haven't signed our Contributor License Agreement yet.

Please read the CLA, then sign by posting the following comment on this PR:

I have read the Contributor License Agreement (CLA) and hereby sign the CLA.

After signing, comment @cla-bot check to re-verify.

@cla-bot

cla-bot Bot commented Mar 27, 2026

Copy link
Copy Markdown

The cla-bot has been summoned, and re-checked this pull request!

@yiliush

yiliush commented Mar 27, 2026

Copy link
Copy Markdown
Contributor

Don't worry about 'signing' again—I gotta debug this and will manually add you to the .clabot record

@yiliush

yiliush commented Mar 27, 2026

Copy link
Copy Markdown
Contributor

@cla-bot check

@cla-bot

cla-bot Bot commented Mar 27, 2026

Copy link
Copy Markdown

Thanks for the pull request! It looks like @enesteve0 haven't signed our Contributor License Agreement yet.

Please read the CLA, then sign by posting the following comment on this PR:

I have read the Contributor License Agreement (CLA) and hereby sign the CLA.

After signing, comment @cla-bot check to re-verify.

@cla-bot

cla-bot Bot commented Mar 27, 2026

Copy link
Copy Markdown

The cla-bot has been summoned, and re-checked this pull request!

@yiliush

yiliush commented Mar 27, 2026

Copy link
Copy Markdown
Contributor

test comment

@yiliush

yiliush commented Mar 27, 2026

Copy link
Copy Markdown
Contributor

@cla-bot check

@cla-bot

cla-bot Bot commented Mar 27, 2026

Copy link
Copy Markdown

Thanks for the pull request! It looks like @enesteve0 haven't signed our Contributor License Agreement yet.

Please read the CLA, then sign by posting the following comment on this PR:

I have read the Contributor License Agreement (CLA) and hereby sign the CLA.

After signing, comment @cla-bot check to re-verify.

@cla-bot

cla-bot Bot commented Mar 27, 2026

Copy link
Copy Markdown

The cla-bot has been summoned, and re-checked this pull request!

@yiliush

yiliush commented Mar 27, 2026

Copy link
Copy Markdown
Contributor

@cla-bot check

@cla-bot cla-bot Bot added the cla-signed label Mar 27, 2026
@cla-bot

cla-bot Bot commented Mar 27, 2026

Copy link
Copy Markdown

The cla-bot has been summoned, and re-checked this pull request!

@theblondealex

Copy link
Copy Markdown
Contributor

Would be nice to have photos in the description of what the pane looks like :)) excited for this PR

enesteve0 added 5 commits June 1, 2026 00:58
- Added ChangeSectionHeader component for displaying section headers in the source control panel.
- Introduced CommitBox component for handling commit messages and actions.
- Created FileChangeRow component to represent individual file changes with actions for staging, unstaging, and discarding.
- Developed SourceControlView component to manage the overall source control interface, including file status and commit actions.
- Implemented git source control logic with functions for staging, unstaging, committing, and discarding changes.
- Integrated AI commit message generation functionality with API interaction for generating commit messages based on diffs.
- Added CSS styles for the new components and overall layout of the source control panel.
- Defined GitChangeStatus and related types for managing file change states.
- Introduced GitBranch, GitRemote, and GitStash interfaces in git-types.ts.
- Expanded CollabApi interface in window-api.d.ts to include methods for Git operations: push, pull, fetch, branch management, and stash operations.
- Implemented gitPush, gitPull, gitFetch, gitBranches, gitCheckout, gitCreateBranch, gitDeleteBranch, gitStashSave, gitStashList, gitStashPop, gitStashApply, gitStashDrop, and gitShowFile functions in git-source-control.ts.
- Registered IPC handlers for new Git operations in ipc.ts.
- Exposed Git API methods in preload script for renderer access.
- Created BranchPicker component for branch selection and management.
- Developed DiffView component for displaying file diffs.
- Added StashSection component for managing stashes.
- Implemented SyncBar component for synchronizing branches with remote.
@enesteve0 enesteve0 force-pushed the dev branch 2 times, most recently from 2eb884f to 69ddf3e Compare May 31, 2026 22:13
enesteve0 added a commit to enesteve0/collab-public that referenced this pull request Jun 1, 2026
Capture VS Code-style Source Control UI via Playwright harness and real git
fixtures; include regen scripts and dirty-worktree fixture for overview states.

Co-authored-by: Cursor <cursoragent@cursor.com>
…ag management

- Updated BranchPicker to support Git tags alongside branches.
- Modified CommitBox to include options for amending and signing commits.
- Enhanced SyncBar to manage multiple remotes and streamline push/pull operations.
- Refactored various components to utilize workspacePath for Git operations.
- Improved styling and layout for better user experience in the source control panel.
@enesteve0

Copy link
Copy Markdown
Author

@theblondealex — thanks for the suggestion!

Would be nice to have photos in the description of what the pane looks like :)) excited for this PR

@theblondealex

Here are dark-mode screenshots of the Source Control panel (also in the PR description). Captured from production SCM components with real fixtures/git/ repos via our screenshot harness.

SCM overview & commit

SCM overview Commit box (amend, commit & push/sync)
01 SCM overview 02 Commit box

Branches, remotes & conflicts

Branch picker & tags Manage remotes
03 Branch picker 04 Sync remotes
Merge conflicts History
05 Merge conflicts 06 History

Rebase, stash, diff & settings

Interactive rebase Stashes
07 Interactive rebase 08 Stash
Viewer Monaco diff Settings → Git
09 Viewer diff 10 Settings Git

@enesteve0

Copy link
Copy Markdown
Author

Hey @yiliush I’d love to keep contributing more consistently to the SCM/Git area in this repo.

I’ll first finish addressing the feedback on this PR and make sure it’s aligned with the project’s direction. After that, I’d be happy to help with follow-up fixes, testing/fixtures, issue triage, and reviewing SCM-related PRs where useful.

If you’re open to it, what would be the most helpful next area for me to take on after this PR?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants