Skip to main content

Overview

Gitlantis integrates with VSCode’s Git API to provide seamless branch management from within the 3D ocean world. You can view all branches and switch between them without leaving the immersive interface.

Git Commands

The extension defines two core Git commands:
export const GIT_COMMANDS = {
  list_branches: "list_branches",
  checkout_branch: "checkout_branch",
};
These commands facilitate communication between the webview (3D world) and the extension backend. Source: src/extension/config/index.ts:23-26

Branch Listing

Frontend Hook

The useBranches hook manages branch state and listens for updates:
type TBranchesResponse = {
  all: string[];        // All available branches
  current: null | string;  // Currently checked out branch
};

const [branches, setBranches] = useState<TBranchesResponse>({
  all: [],
  current: null,
});
Source: src/browser/hooks/useGit/useBranch/index.ts:6-16

Backend Handler

The extension backend uses VSCode’s Git API to retrieve branches:
const getBranches = async (panel: vscode.WebviewPanel, repo: Repository) => {
  const branches = await repo.getBranches({ remote: true });
  const allBranches = branches
    .map((b) => b.name)
    .filter((name) => name !== "HEAD" && name !== "origin/HEAD");
  const currentBranch = repo.state.HEAD?.name || "unknown";

  panel.webview.postMessage({
    type: GIT_COMMANDS.list_branches,
    all: allBranches,
    current: currentBranch,
  });
};
Key behaviors:
  • Fetches both local and remote branches
  • Filters out HEAD and origin/HEAD
  • Returns the current branch from repo state
Source: src/extension/handlers/git/branches/list.ts:7-19

Branch Change Listener

The extension listens for branch changes and updates the webview:
const listenForBranchChanges = (
  panel: vscode.WebviewPanel,
  repo: Repository
) => {
  repo.state.onDidChange(() => {
    panel.webview.postMessage({
      type: GIT_COMMANDS.checkout_branch,
      current: repo.state.HEAD?.name,
    });
  });
};
This ensures the UI stays in sync even if branches are changed outside the extension. Source: src/extension/handlers/git/branches/list.ts:21-31

Branch Checkout

Branch Picker UI

The branch breadcrumb displays a clickable picker:
const [isPickerOpen, setPickerOpen] = useState(false);

const toggleBranchPicker = () => setPickerOpen((prev) => !prev);

const handleBranchSelection = (branch: string) => {
  setPickerOpen(false);
  if (!vscodeApi) return;
  vscodeApi.postMessage({
    type: GIT_COMMANDS.checkout_branch,
    branch,
  });
};
When a branch is selected:
  1. The picker closes
  2. A message is sent to the extension
  3. The extension performs the checkout
Source: src/browser/components/ui/breadcrumbs/branch/index.tsx:14-25

Picker Dropdown

{isPickerOpen && (
  <div className="absolute left-0 z-10 mt-1 max-h-64 min-w-max overflow-y-auto rounded-md border border-[#2d302f] bg-white shadow-lg">
    {branches.map((branch) => (
      <div
        key={branch}
        className="cursor-pointer whitespace-nowrap px-3 py-1 text-black hover:bg-gray-100"
        onClick={() => handleBranchSelection(branch)}
      >
        {branch}
      </div>
    ))}
  </div>
)}
Features:
  • Max height: 64 units with scroll
  • Hover effect: Light gray background
  • Auto-sizing: Width adapts to longest branch name
Source: src/browser/components/ui/breadcrumbs/branch/index.tsx:39-51

Checkout Logic

The backend handles branch checkout with support for both local and remote branches:
const checkoutBranch = async (branch: string = "", inputPath: string) => {
  const repo = getCurrentRepo(inputPath);
  if (!repo) throw new Error("Repository not found");

  const normalizedBranch = branch.replace(/^origin\//, "");
  const branches = await repo.getBranches({ remote: true });

  const filteredBranch = branches.find((b) => b.name === normalizedBranch);

  if (filteredBranch?.remote) {
    await repo.createBranch(normalizedBranch, true, filteredBranch.name);
    return;
  }

  if (!filteredBranch?.remote) {
    await repo.checkout(normalizedBranch);
    return;
  }

  throw new Error(
    `Could not checkout to inexistent branch: ${normalizedBranch}`
  );
};
The checkout logic handles two scenarios:
  1. Remote branches: Creates a local tracking branch
  2. Local branches: Checks out directly
Source: src/extension/handlers/git/branches/checkout.ts:6-28

Success Response

After a successful checkout, the extension notifies the webview:
export const handleCheckoutBranch = async (
  panel: vscode.WebviewPanel,
  message: THandlerMessage
) => {
  try {
    await checkoutBranch(message.branch, message.path);

    panel.webview.postMessage({
      type: GIT_COMMANDS.checkout_branch,
      current: message.branch,
    });
  } catch (_error: unknown) {
    vscode.window.showErrorMessage((_error as Error).message);
  }
};
Source: src/extension/handlers/git/branches/checkout.ts:30-44

Error Handling

The extension defines specific error types for Git operations:
export const GIT_ERRORS = {
  listing_error: "listing_error",
  checkout_error: "checkout_error",
  generic: "generic",
};
Source: src/extension/config/index.ts:28-32

Repository Validation

Before performing Git operations, the extension validates the repository:
const repo = getCurrentRepo(message.path);

if (!repo) {
  vscode.window.showErrorMessage(
    `Could not find a valid git repository for your current project`
  );
  return;
}
Source: src/extension/handlers/git/branches/list.ts:38-45
If no Git repository is found, Git features will be unavailable and the branch breadcrumb will show “none found”.

Integration with Breadcrumbs

The Git integration seamlessly works with the breadcrumb system:
const {
  git: {
    branches: { all: branches, current },
  },
} = useGameContext();
The useGameContext hook provides Git state throughout the application, making it available to all components. Source: src/browser/components/ui/breadcrumbs/branch/index.tsx:8-12

Real-time Synchronization

The extension maintains real-time synchronization between the 3D world and VSCode’s Git state:
  1. Initial load: Fetches all branches when path changes
  2. Change listener: Updates UI when branches change externally
  3. Checkout response: Updates current branch immediately after checkout
This ensures the branch display is always accurate, even when Git operations are performed outside the extension.

Build docs developers (and LLMs) love