Skip to content

Latest commit

 

History

5 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Git Workspace Manager

A minimalist desktop app for managing multiple Git repositories across branches. Switch an entire group of repos to the right branches and pull updates with one click.

Built with Electron and vanilla HTML/CSS/JS. No frameworks, no build tools, no complexity.

Preview

Screenshot 2026-03-24 172439 image

Table of Contents


Installation

Option A: Portable Executable (recommended for daily use)

  1. Download Git Workspace Manager 1.0.0.exe from the dist/ folder.
  2. Place it anywhere (Desktop, USB drive, etc.).
  3. Double-click to run. No installation needed.

Prerequisite: Git must be installed and available on your system PATH.

Option B: Run from Source (for development)

Prerequisites: Node.js (v18+) and Git.

cd git-workspace
npm install
npm start

Getting Started

1. Register your repositories

Before you can create workspaces, the app needs to know where your repos live on disk.

  • Click Manage Registry in the sidebar.
  • Click Add Repository to pick a single repo folder, or Scan Folder to automatically find all repos inside a parent directory (e.g. C:\Repositories).
  • The app reads each repo's git remote origin URL and extracts an identifier like myorg/my-repo.

2. Create a workspace

A workspace is a named group of repositories, each with an optional target branch.

  • Click + New Workspace in the sidebar.
  • Give it a name (e.g. "Development", "Staging").
  • Check the repos you want to include.
  • For each repo, type a branch name (e.g. development) or leave blank to stay on whatever branch it's currently on.
  • Click Save.

3. Sync

  • Select a workspace from the sidebar.
  • Click Sync All.
  • The app will check each repo for uncommitted changes. If any are dirty, you'll see a warning and can choose to skip them.
  • For each clean repo, it will: fetch all remotes, checkout the target branch (if specified), and pull latest changes.
  • Progress and results are shown per-repo in the table.

Features

Feature Description
Workspace management Create, edit, and delete named groups of repos with target branches.
Sync All Fetch + checkout + pull for every repo in a workspace, with per-repo progress.
Dirty repo warnings Repos with uncommitted changes are flagged and skipped during sync.
Repository registry Central list mapping org/repo identifiers to local paths.
Scan Folder Batch-add all repos from a parent directory.
Import / Export Move workspace configs between machines without sharing local paths.
Status indicators Green = clean, Red = dirty, Yellow = error/missing.

Import / Export

Exporting a workspace

  1. Select a workspace and click Export.
  2. Choose where to save the .json file.
  3. The exported file contains only repo identifiers (org/repo) and branch names. No local paths are included.

Example export file:

{
  "name": "Development",
  "exportedAt": "2026-03-18T12:00:00Z",
  "repos": [
    { "id": "myorg/api-server", "branch": "development" },
    { "id": "myorg/web-client", "branch": "development" },
    { "id": "myorg/shared-lib", "branch": null }
  ]
}

Importing a workspace

  1. Click Import Workspace in the sidebar and select a .json file.
  2. The app checks that every repo in the file exists in your local registry.
  3. If all repos are found: The workspace is created.
  4. If any repos are missing: The import is blocked and you'll see a list of missing repos. Add them to your registry first, then try again.

This lets you share workspace configs between machines where the same repos may live at different paths.


Git Safety

This app is designed to be accident-proof. It only runs safe, read-or-pull git operations:

Allowed NOT allowed (not in the app at all)
git fetch --all git merge
git checkout <branch> git rebase
git pull git reset
git status --porcelain git push
git rev-parse --abbrev-ref HEAD git clean
git remote get-url origin git stash
git branch -a Any --force flag

All git commands are executed via Node.js execFile with arguments passed as arrays (not shell strings), preventing command injection. There is no generic "run any git command" function.


Developer Guide

Project structure

git-workspace/
  package.json      # npm config, Electron version, build settings
  main.js           # Electron main process
  preload.js        # Context bridge (main <-> renderer)
  git.js            # Git command whitelist
  index.html        # UI markup
  styles.css        # Styling
  renderer.js       # UI logic
  dist/             # Built executables (after npm run build)

How the code is organized

The app follows Electron's standard architecture with three layers:

  1. Main process (main.js) - Runs in Node.js. Handles file I/O, config persistence, native dialogs, and git operations. Exposes functionality to the renderer via IPC handlers.

  2. Preload (preload.js) - The bridge. Uses Electron's contextBridge to expose a safe window.api object to the renderer. The renderer cannot access Node.js directly.

  3. Renderer (renderer.js + index.html + styles.css) - Runs in the browser window. All UI logic: DOM manipulation, event handlers, view switching. Calls window.api.* methods to talk to the main process.

Running in development

npm start

This launches Electron and loads the app. Changes to renderer.js, index.html, or styles.css take effect after reloading the window (Ctrl+R). Changes to main.js, preload.js, or git.js require restarting the app.

Building the executable

npm run build

This uses electron-builder to create a portable .exe in the dist/ folder. The executable bundles the Electron runtime and all source files - no Node.js installation needed on the target machine.

Adding a new IPC handler

To add new functionality accessible from the UI:

  1. main.js - Add a handler: ipcMain.handle('my-action', async (_e, arg) => { ... })
  2. preload.js - Expose it: add myAction: (arg) => ipcRenderer.invoke('my-action', arg) to the contextBridge object
  3. renderer.js - Call it: const result = await window.api.myAction(arg)

File Reference

git.js - Git safety boundary

The only file that runs git commands. Contains a private run() function that calls execFile('git', args, { cwd }) and 7 public functions (gitFetch, gitCheckout, gitPull, gitStatus, gitCurrentBranch, gitRemoteUrl, gitBranchList) plus a parseRepoId helper. To audit git safety, you only need to read this one file.

main.js - Electron main process

Handles:

  • Config management - reads/writes config.json from %APPDATA%/git-workspace/. Config path is lazily initialized after Electron is ready.
  • IPC handlers - get-config, save-config, pick-repo-folder, scan-folder, repo-status, repo-branches, sync-repo, export-workspace, import-workspace, check-git.
  • Window creation - single window, no menu bar, context isolation enabled.

preload.js - Context bridge

Maps each IPC channel to a method on window.api. This is the complete list of what the renderer can do - nothing more.

index.html - UI structure

Single-page app with:

  • Sidebar - workspace list, new workspace button, registry and import buttons.
  • Three views - welcome (empty state), workspace (repo table + sync), registry (repo list + add/scan).
  • Four modals - workspace create/edit, dirty repo warning, import result, git-not-found overlay.

styles.css - Styling

Dark theme with Catppuccin-inspired colors. Defines CSS variables at :root for easy theming. Covers layout, sidebar, tables, buttons, modals, status indicators, and scrollbars.

renderer.js - UI logic

All DOM manipulation and event handling. Key functions:

  • init() - checks git availability, loads config, renders sidebar.
  • renderWorkspace() / fetchRepoStatus() - builds the repo table and fetches live status.
  • syncAll() - orchestrates the sync: checks dirty repos, shows warning, syncs sequentially.
  • openWorkspaceModal() - handles create/edit with registry-based repo picker.
  • importWorkspace() / exportWorkspace() - portable workspace transfer.
  • renderRegistry() / addRepoToRegistry() / scanFolderToRegistry() - registry management.

Config File

Location: %APPDATA%/git-workspace/config.json

{
  "registry": [
    {
      "id": "myorg/my-repo",
      "localPath": "C:\\Repositories\\my-repo"
    }
  ],
  "workspaces": [
    {
      "id": "ws-1710000000000",
      "name": "Development",
      "repos": [
        { "registryId": "myorg/my-repo", "branch": "development" },
        { "registryId": "myorg/other-repo", "branch": null }
      ]
    }
  ]
}
  • registry - maps org/repo (from git remote URL) to local filesystem path.
  • workspaces - each has a unique ID, name, and list of repos referencing the registry.
  • branch: null means "stay on whatever branch is currently checked out."

If this file becomes corrupt, the app backs it up as config.json.backup and creates a fresh empty config.


Troubleshooting

Problem Solution
App shows "Git Not Found" Install Git and make sure git --version works in your terminal.
Repo shows yellow dot in registry The local path no longer exists or is not a git repo. Update or remove it.
Sync skips a repo as "dirty" That repo has uncommitted changes. Commit or stash them first.
Checkout fails during sync The target branch may not exist. Check the branch name in workspace settings.
Config lost between restarts Make sure you're on version 1.0.0+. Earlier versions had a config path bug.
Import fails with missing repos Add the listed repos to your registry first (Add Repository or Scan Folder).

About

Git Workspace Manager - manage multiple repos across branches

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages