Java LLD: How to Design Git (Version Manager) in an Interview

java dev.to

Java LLD: How to Design Git (Version Manager) in an Interview

Designing a Version Control System (like Git) is a classic Low-Level Design (LLD) interview question that frequently trips up candidates. It tests your ability to combine clean object-oriented design with elegant data structures under pressure.

The Mistake Most Candidates Make

  • Flat List Fallacy: Modeling the commit history as a flat list, which makes branching and merging incredibly complex and inefficient to implement.
  • Violating SRP: Cramming file storage, commit history tracking, and command execution into a single, bloated Repository class.
  • Hardcoding Operations: Using massive if-else or switch blocks to handle actions like commit, checkout, and merge instead of decoupling them.

The Right Approach

  • Core mental model: A Version Tree (DAG) where each commit is an immutable node, and a branch is simply a mutable pointer to a specific node.
  • Key entities/classes: CommitNode, Branch, VersionManager, CommitCommand, MergeCommand.
  • Why it beats the naive approach: It separates the structural history graph from the user actions, allowing O(1) branch creation and elegant multi-parent merges.

The Key Insight (Code)

The core of a Git-like system is the commit node. To support merges, a commit node must be able to point to multiple parent nodes.

public class CommitNode {
    private final String hash;
    private final String message;
    private final List<CommitNode> parents; // 1 parent for normal commit, 2 for merge
    private final Map<String, String> snapshot; // File path -> Content

    public CommitNode(String hash, String message, Map<String, String> snapshot, List<CommitNode> parents) {
        this.hash = hash;
        this.message = message;
        this.snapshot = Map.copyOf(snapshot);
        this.parents = List.copyOf(parents);
    }
}
Enter fullscreen mode Exit fullscreen mode

Key Takeaways

  • Branches are just pointers: Never duplicate files or history when branching; simply create a new pointer referencing the current CommitNode.
  • Merge is a two-parent node: Merging branch B into branch A creates a new CommitNode that lists both A's and B's latest commits as its parents.
  • Command Pattern for SRP: Encapsulate operations like commit and revert into command objects to keep your VersionManager clean and extensible.

If you're prepping for interviews, I've been building javalld.com — real machine coding problems with full execution traces.

Full working implementation with execution trace available at https://javalld.com/problems/version-manager

Source: dev.to

arrow_back Back to Tutorials