FredrikNoren/ungit
41.6
Weak · 2 October 2026
9.5k
lines of production code
JavaScript
primary language
2
measurements over time
What this system is
Ungit is a web-based Git client that provides a graphical interface for managing repositories, branches, commits, and stashes. It supports visual diffing for text and images, interactive graph manipulation via drag-and-drop, and submodule management. The system runs as a Node.js server with an Electron desktop shell, featuring modular components for authentication, error handling, and repository navigation.
How it got here
2013 — modular architecture and UI overhaul
10 changes.
The project underwent a significant structural transformation, reorganizing both server-side and client-side code into modular components with improved separation of concerns. This period also saw a major visual refresh of the interface, migrating to Bootstrap 3 with a dark theme, alongside the introduction of an Electron shell and expanded test coverage for core Git operations.
2014 — Component-based architecture migration
15 changes.
The project underwent a comprehensive refactoring to decompose the monolithic application into a modular system of standalone Knockout.js components. This period focused on extracting distinct UI features—such as the git graph, staging area, and repository views—into self-contained modules with dedicated view models and templates. The work also introduced new capabilities for visualizing diffs, managing stashes and submodules, and enhancing the overall navigation and error handling interfaces.
2015–2022 — Componentization and build automation
8 changes.
The project refactored its UI into reusable Knockout.js components for core features like commits, branches, and modals, while introducing a base class for API caching to optimize rendering. Concurrently, the development workflow was modernized by migrating end-to-end tests to Puppeteer and establishing comprehensive build, packaging, and publishing scripts for Electron distribution.
Features
Add submodule management UI and controls
A new Submodules component has been added to the repository view, providing a dropdown menu to manage Git submodules. Users can now view a list of submodules, navigate to their local paths or external URLs, remove them (with a confirmation dialog), and update all submodules. The component fetches submodule data from the server and integrates with the existing modal system for adding and removing operations.
components/submodules · high confidence
Extracted Refresh Button into Reusable Component
The refresh button functionality has been refactored into a dedicated, reusable component located in the components/refreshbutton directory. This change introduces a new UI element that uses Octicons for the refresh icon, supports a large button variant, and displays a 'Refresh changes' tooltip on hover. The component is registered within the application's plugin system, exposing its Knockout template, JavaScript logic, and CSS styles for use across the interface.
components/refreshbutton · high confidence
Initial public frontend and Electron shell
The public directory now contains the core application shell, including the main HTML entry point that loads the UI, styles, and error-tracking client (Raven/Sentry), alongside the Electron main process script that manages the native window, application menu, and server launch logic. This change also introduces the Animate.css library to support UI animations within the interface.
public · high confidence
Introduce dedicated Repository component for unified view and submodule handling
The repository view is now rendered by a new \repository\ component that consolidates the display of submodules, stash, staging, branches, and the commit graph. This component introduces specific handling for submodules, displaying a warning with a link to the parent repository when inside a submodule, and adds a button to edit the \.gitignore\ file directly. It also conditionally disables the stash and staging components for bare repositories and supports configurable tab sizes via CSS variables.
components/repository · high confidence
Introduce dedicated Stash UI component
A new, self-contained Stash component has been added to the application, providing a dedicated interface for managing stashed changes. Users can now view a list of stashed items with their titles and messages, apply specific stashes, or drop them (with a confirmation dialog). The component includes a toggle to show or hide the stash panel, persists the visibility state across client refreshes using local storage, and allows users to expand individual stash items to view their commit diffs inline. It also displays the count of stashed changes and uses Octicons for action buttons.
components/stash · high confidence
Introduce dedicated path component for repository navigation and initialization
The application now uses a new \path\ component to manage the current directory context. This component handles displaying the current path, detecting whether a directory is a valid Git repository, and providing UI for initializing new repositories or cloning existing ones into subdirectories. It also supports navigating into sub-repositories within a directory and handles invalid or non-existent paths with appropriate error states and options to create directories.
components/path · high confidence
Introduce dedicated text diff component with incremental loading and view options
A new \textdiff\ component has been added to handle file diff rendering, replacing previous inline implementations. It supports switching between inline and side-by-side views, toggling whitespace visibility, and enabling word wrap. To improve performance on large files, the component implements incremental loading (loading the first 100 lines by default with a 'Load more' button) and integrates with the \diff2html\ library for rendering. It also supports patching specific lines within the diff view.
components/textdiff · high confidence
Introduction of core utility modules for caching, logging, and file type detection
This change introduces three new utility modules in the source/utils directory. The new cache module provides a function-result caching mechanism with TTL support, allowing functions to be registered and their results cached or invalidated. A logger module has been added, configuring Winston to output to both console and optional file transports based on configuration settings. Additionally, a file-type utility has been created to distinguish between image and text files based on file extensions.
source/utils · high confidence
New branch management dropdown with filtering and deletion
A new Branches component has been added to the UI, providing a dropdown menu to view, switch, and delete Git branches, tags, and remote references. Users can toggle the visibility of Remotes, Branches, and Tags via checkboxes, with preferences persisted in local storage. The list automatically sorts the current branch to the top and includes proper Octicons for visual identification. The component supports checking out branches directly from the list and offers a confirmation dialog before deleting any branch (including remote branches), ensuring users are aware that deletion cannot be undone.
components/branches · high confidence
New build, packaging, and publishing scripts
The project introduces a new set of build automation scripts in the \scripts/\ directory. \build.js\ now handles compiling Less stylesheets and bundling JavaScript via Browserify with source map generation. \electronpackage.js\ manages creating Electron binaries for various platforms and architectures, while \electronzip.js\ packages these builds into distribution archives. Additionally, \npmpublish.js\ automates publishing to npm and creating GitHub releases with assets, and \teststabilitytester.js\ provides a utility for running stability tests. These changes streamline the development and release workflow.
scripts · high confidence
New commit node component with parent links and copy button
The commit graph now uses a dedicated component to display individual commits, featuring a truncated title (limited to 72 characters) with the full message visible on hover or selection. Users can now click on parent commit IDs directly within the node to navigate to them, and a new clipboard button allows copying the commit SHA-1 to the clipboard. The component also displays the author's gravatar, PGP verification status, and line change statistics, while rendering the commit body in a monospace font for better readability.
components/commit · high confidence
New crash page with troubleshooting tips and adblock detection guidance
A new crash component has been added to display user-friendly error messages when ungit encounters an unexpected failure. The page dynamically shows the specific error cause and provides categorized troubleshooting steps for general issues, connection losses, ad blockers/privacy extensions, Git permission problems, and other errors. This improves the user experience by giving clear, actionable advice instead of a generic error screen.
components/crash · high confidence
New image diff component for visualizing file changes
A new Knockout-based UI component has been added to render image diffs, allowing users to visually compare added, removed, and modified image files. The component displays side-by-side views for changed images, distinct views for new or removed files, and uses Octicons for directional indicators. It constructs image sources via the server-side image diff API, handling path encoding and versioning (HEAD vs. current) to ensure correct display of file states.
components/imagediff · high confidence
New modal components for forms and prompts
This change introduces a new modal system in the \components/modals\ directory, providing reusable UI components for user interactions. It adds a \FormModal\ for collecting user input (used for credentials, adding remotes, and adding submodules) and a \PromptModal\ for decision-based dialogs (such as Yes/No confirmations, muting options, handling too many files, and text editing). These components are registered as Knockout.js components and exported via the plugin manifest, enabling consistent modal behavior across the application.
components/modals · high confidence
New standalone credentials helper and refactored launcher script
The \bin/credentials-helper\ script is introduced as a standalone executable that retrieves Git credentials by querying the running Ungit server via HTTP, replacing the previous inline or different mechanism. The main \bin/ungit\ launcher script is rewritten to use Node's \child\_process.fork\ to start the server, ensuring proper process management and allowing the launcher to cleanly exit when the server stops. It also adds support for a \launchCommand\ configuration option, allowing users to specify a custom command to open the Ungit UI instead of the default browser behavior.
bin · high confidence
Architecture
Remotes component extracted into a standalone plugin
The remote management UI has been refactored into a self-contained component located in the \components/remotes\ directory. This change introduces a new Knockout-based view model (\remotes.js\) and template (\remotes.html\) that handle fetching from, adding, and removing Git remotes. The component now exposes its own plugin manifest (\ungit-plugin.json\) to register its Knockout templates and JavaScript bundle, decoupling the remote-specific logic from the broader application structure while maintaining existing functionality for remote selection and fetch operations.
components/remotes · high confidence
Ungit source code restructured into modular components
The application's source code has been reorganized into distinct, single-responsibility modules. The server entry point (server.js) now explicitly wires together configuration, authentication (via Passport), and the Git API, while introducing a new BugTracker module that integrates with Sentry for error reporting. Git operations are now handled by a dedicated git-promise module that manages command execution, concurrency limits, and timeouts, supported by a new address-parser for remote URL handling and a refactored git-parser for status and log data. File system watching has been moved into the git-api module using chokidar, and plugin loading is managed by a new ungit-plugin module, creating a cleaner separation of concerns across the codebase.
source · high confidence
Behavioural changes
5 commits (0 fixes) modifying public/images
A change to existing behaviour in public/images — 5 commits, 4 files.
public/images · medium confidence · unverified
Client application restructured into modular components with improved error handling
The client-side application has been reorganized into a modular architecture, introducing a component system (public/source/components.js) that manages UI elements like the app, login, and crash screens. A new bootstrap entry point (public/source/bootstrap.js) and main initialization logic (public/source/main.js) now handle dependency loading, including specific Bootstrap modules and jQuery UI autocomplete. The Server module (public/source/server.js) has been enhanced to support configurable root paths, optional progress bars, and more robust socket.io connection and disconnection handling. Additionally, a new storage wrapper (public/source/storage.js) protects against LocalStorage errors, and navigation is now managed via a dedicated module (public/source/navigation.js) using hash-based routing.
public/source · high confidence
Extracted git error handling into a dedicated component
Git error notifications are now managed by a new, isolated \gitErrors\ component. This change introduces a dedicated UI for displaying unhandled git command errors, distinguishing between standard errors and warnings via visual styling. Users will see detailed information about the failed command, including the specific error message, standard output, and standard error streams. The component also handles automatic bug reporting when enabled and provides a dismissible alert interface.
components/gitErrors · high confidence
Header component refactored into a standalone module with improved navigation and styling
The application header has been extracted into a dedicated component (components/header) with its own template, view model, and styles. This change introduces a visible back button that appears when navigating away from the home page, allowing users to return to the root view. The repository path input now properly encodes slashes in URLs to prevent navigation errors. Additionally, the header's visual design has been updated with a fixed top position, a new CSS triangle arrow indicator, adjusted padding for the version number, and the use of Octicons for icons like the back arrow and add button.
components/header · high confidence
Introduce dedicated Home component for repository list management
The home view is now implemented as a standalone component (components/home) that renders a list of repositories using Knockout.js bindings. This component displays repository titles and remote URLs, with remote credentials masked in the UI. It handles repository removal via a dedicated remove action and visually indicates when a repository's path no longer exists on the filesystem. The component also integrates Octicons for UI icons and respects the rootPath setting for link generation.
components/home · high confidence
Introduce dedicated Login component
The login interface is now implemented as a standalone component (components/login) with its own Knockout.js view model and HTML template. Users will see a standard login form with username and password fields, error handling for failed attempts, and status updates for loading and logged-in states, replacing the previous inline or less-structured login implementation.
components/login · high confidence
Introduce modular App component with version and bugtracking UI
The application shell is now implemented as a dedicated \app\ component (located in \components/app\), replacing the previous monolithic structure. This change introduces a user-facing interface that displays alerts for outdated ungit versions (with links to the changelog and installation commands) and invalid Git versions, both of which can be dismissed by the user. It also adds a 'bugtracking nagscreen' that prompts users to enable automatic bug reports, with the option to dismiss it. The component manages the main layout, including a conditional header (hidden if \noheader=true\ is in the URL), content area, and modal dialogs, while handling repository list persistence and program events like credential requests.
components/app · high confidence
Introduction of ComponentRoot base class for API caching
A new ComponentRoot base class has been added to the components directory, providing a mechanism to cache API payloads and prevent redundant UI redraws. This class includes an isSamePayload method that compares incoming data against a stored JSON string to determine if a component needs to re-render, along with a clearApiCache method to reset this state.
components · high confidence
Migrate click tests from Nightmare to Puppeteer
The end-to-end click tests have been rewritten to use Puppeteer instead of the previous Nightmare library. This change updates the test environment setup, browser automation logic, and all test specifications (authentication, branches, remotes, submodules, etc.) to rely on Puppeteer APIs, resulting in a more stable and modern testing foundation for the application.
clicktests · high confidence
New commit diff component with view options
The commit diff view has been refactored into a dedicated component that provides users with controls to toggle whitespace visibility, switch between side-by-side and unified diff views, and enable word wrapping. It also displays file statistics (additions and deletions) and handles the rendering of individual file diffs within a commit.
components/commitdiff · high confidence
Rebuilt git graph component with animated SVG rendering and drag-and-drop actions
The git graph visualization has been completely rewritten to use a pure SVG rendering engine (via mina) instead of the previous D3-based approach, enabling smooth, animated transitions for node and edge movements. This update introduces a new drag-and-drop interface for graph actions, allowing users to drag branch and tag references onto nodes to perform operations like rebase, merge, reset, push, checkout, delete, cherry-pick, uncommit, revert, and squash. The new component also features improved ref management with distinct visual styling for local and remote branches/tags, hover previews for upcoming operations, and a more responsive layout for displaying commit details and file diffs.
components/graph · high confidence
Repository configuration and documentation overhaul
The repository has been restructured with new configuration files to standardize development workflows and improve packaging. A \.gitattributes\ file enforces LF line endings for all text files and specifically for the \bin/\ scripts. Prettier is now configured via \.prettierrc\ and \.prettierignore\ to handle code formatting, while ESLint has been migrated to a flat configuration (\eslint.config.mjs\) with specific rules for different source directories. Test execution is now managed via dedicated Mocha configuration files (\.mochatest.json\ and \.mochaclicktest.json\). The \.npmignore\ file has been completely rewritten to exclude development artifacts, tests, and documentation from the published package. Additionally, the project documentation has been significantly expanded: \README.md\ now includes installation requirements (Node ≥ 20.19, Git ≥ 2.34), configuration examples, and links to integrations; \CONTRIBUTING.md\ provides detailed setup and architecture guides; \MERGETOOL.md\ documents external merge tool integration; \PLUGINS.md\ explains the plugin API; and \LICENSE.md\ explicitly states the MIT license.
(repo-wide) · high confidence
Staging area refactored into a standalone component with enhanced diff controls
The staging area has been restructured as a dedicated component (staging.js, staging.html, staging.less) that is now independent of the repository and graph models. This change introduces several user-facing improvements: users can now toggle between unified and side-by-side diff views, enable word wrapping, and hide whitespace changes directly in the staging panel. The interface also displays addition and deletion counts for files, supports patching individual lines, and provides specific conflict resolution buttons (Continue/Abort) for merge, rebase, and cherry-pick operations. Additionally, the commit message title now includes a character counter, and the UI prevents patching when side-by-side view is active to ensure consistency.
components/staging · high confidence
UI overhaul with Bootstrap 3 and custom dark theme
The application's visual design has been completely refreshed by migrating to Bootstrap 3, which introduces new styling for core components like the navbar, modals, panels, and list groups. A new dark color scheme has been applied across the interface, featuring a dark background (\#252833), light text, and specific styling for inputs, tooltips, and list items. The diff viewer (diff2html) has been restyled to match this theme, using Source Code Pro for code and custom colors for additions and deletions. Additionally, custom fonts (Open Sans and Source Code Pro) are now embedded, and jQuery UI autocomplete styling has been aligned with the new Bootstrap dropdowns.
public/less · high confidence
Test coverage
Expanded test coverage for Git API and utility modules
Added comprehensive unit tests for the Git API and supporting utilities, including branching, conflict resolution (with and without auto-stash), diff generation (text and image), file discard operations, .gitignore management, patch application, and remote handling. Also added tests for the address parser, caching mechanism, credentials helper, and file type detection to ensure reliability across core functionality.
test · high confidence
Dependencies
Ungit 1.5.30 dependency update and Node.js 20+ requirement
This release updates the ungit package to version 1.5.30 and enforces a minimum Node.js version of 20.19.0 (or 22.12.0/23+). The dependency list has been refreshed to include Express 5.2.1, Socket.io 4.8.3, and diff2html 3.4.56, while dev dependencies such as Electron 42.5.0, Mocha 11.7.6, and ESLint 10.5.0 have been upgraded. An override for serialize-javascript is also included in the manifest.
(dependencies) · high confidence
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
How this codebase got here
Score
- CAI 41 → 42 (+0.7)
- Rubric changed (rubric-2026.09.12 → rubric-2026.09.18) — scores are not directly comparable.
Lenses
- Code Health 39 → 38 (-0.6)
- Architecture 97 → 87 (-10.1)
- Maturity 60 → 60 (+0.0)
- Readiness 40 → 40 (+0.2)
- Security 57 → 63 (+6.2)
- Accessibility 35 → 35 (+0.0)
- Performance 100 (new)
Resolved (11)
- Concentrated knowledge decay
- Dependency hygiene PARTLY measured — npm pinning read, dependency currency not (no pnpm-resolved versions to grade)
- Documentation: no installation or build instructions (README.md)
- High CVE: [GHSA redacted] (package-lock.json)
- High CVE: [GHSA redacted] (package-lock.json)
- High CVE: [GHSA redacted] (package-lock.json)
- High CVE: [GHSA redacted] (package-lock.json)
- Medium CVE: [GHSA redacted] (package-lock.json)
- parseGitLog (cyclomatic 24) (source/git-parser.js)
- parsePatchDiffResult (cognitive 20) (source/git-parser.js)
- queryPromise (cognitive 25) (public/source/server.js)
New (23)
- Documentation: no usage examples (README.md)
- Dormant codebase
- High CVE: [GHSA redacted] (package-lock.json)
- High CVE: [GHSA redacted] (package-lock.json)
- High CVE: [GHSA redacted] (package-lock.json)
- High CVE: [GHSA redacted] (package-lock.json)
- High CVE: [GHSA redacted] (package-lock.json)
- Low cohesion: AppViewModel (LCOM4 6) (components/app/app.js)
- Medium CVE: [GHSA redacted] (package-lock.json)
- Outdated (npm): @primer/octicons
- Outdated (npm): bootstrap
- Outdated (npm): ignore
- Outdated (npm): jquery
- Outdated (npm): moment
- Outdated (npm): open
- Outdated (npm): p-limit
- Outdated (npm): socket.io
- Outdated (npm): typescript
- Outdated (npm): yargs
- Projects may be oversized for their cohesion
- …and 3 more
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
Survey your own repository
FredrikNoren/ungit was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.
About this page
- The score is its most recent published measurement, taken on 2 October 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
- Measured at commit b1df1a168b9208766342070ebd42782036dfd18d — the exact code this score is about.
- Scored under rubric-2026.09.18 — the same rubric and the same method as every other entry in this index.
- Measured by watchdog.canine.dev using codehealth-analyzer preprod-e569280dd5e2.