Skip to content

Conversation

zhangfengcdt
Copy link
Owner

This PR implements comprehensive historical functionality for all storage types (InMemory, File, RocksDB) by ensuring they
save tree configuration to git commits, and adds extensive multi-branch testing for the get_commits method. A critical bug in
branch isolation was also discovered and fixed during testing.

Key Changes

  1. Universal Historical Functionality (src/git/versioned_store.rs)

Problem: Only GitNodeStorage had full historical functionality. Other storage types (InMemory, File, RocksDB) couldn't
provide historical access because they didn't save tree configuration to git commits.

Solution:

  • Created TreeConfigSaver trait for polymorphic tree config saving
  • Added specialized save_tree_config_to_git() implementations for each storage type:
    • GitNodeStorage: Saves both tree config AND hash mappings (required for git blob storage)
    • InMemory/File/RocksDB: Save tree config only (hash mappings not needed)
  • Modified generic commit() method to call save_tree_config_to_git_internal() for all storage types

Impact: All storage types now support full historical functionality:

  • get_keys_at_ref() - Get keys at any commit/branch
  • diff() - Compare between commits/branches
  • get_commits() - Track key change history
  • get_commit_history() - Access commit metadata
  1. Branch Isolation Bug Fix (src/git/versioned_store.rs)

Problem: Critical bug discovered during testing - when switching branches, data would leak between branches. Keys created on
feature branches would appear on main branch.

Solution:

  • Added Git-specific checkout() method that properly reloads tree state
  • Implemented reload_tree_from_head() to rebuild tree from target commit
  • Fixed directory creation for branch names with slashes (e.g., feature/new-keys)

Impact: Perfect branch isolation - keys are now properly scoped to their respective branches.

  1. Comprehensive Multi-Branch Testing (src/git/versioned_store.rs)

Added 4 new test suites covering complex real-world scenarios:

test_get_commits_complex_multi_branch_scenarios

  • Multi-branch development with main, feature, and hotfix branches
  • Key tracking across branches with different evolution paths
  • Verifies branch isolation and correct commit history

test_get_commits_merge_scenarios

  • Pre-merge testing with parallel development
  • Branch-specific keys and shared key modifications
  • Different evolution paths for same keys on different branches

test_get_commits_key_lifecycle_patterns

  • Complete lifecycle: create → modify → delete (5 commits tracked)
  • Delete and recreate scenarios (full history preserved)
  • Static keys that never change

test_get_commits_empty_and_edge_cases

  • Non-existent keys, empty repositories
  • Binary keys/values, very long key names (1000+ chars)
  • Empty values and edge cases

Test Results

  • Before: 60 tests passing
  • After: 64 tests passing (4 new comprehensive test suites)
  • Coverage: All storage types now have identical historical functionality
  • Branch isolation: ✅ Fixed - no data leakage between branches

Example Usage

// Now works for ALL storage types (not just Git)
let mut store = InMemoryVersionedKvStore::<32>::init(&path)?;

// Add data and commit
store.insert(b"key1".to_vec(), b"value1".to_vec()).unwrap();
let commit1 = store.commit("Add key1").unwrap();

// Create feature branch and modify key
store.create_branch("feature/enhancement").unwrap();
store.checkout("feature/enhancement").unwrap();
store.update(b"key1".to_vec(), b"new_value".to_vec()).unwrap();
let commit2 = store.commit("Update key1 on feature").unwrap();

// Historical access now works for all storage types
let commits = store.get_commits(b"key1").unwrap(); // Returns 2 commits
let diff = store.diff(&commit1.to_hex().to_string(), &commit2.to_hex().to_string()).unwrap();
let keys_at_head = store.get_keys_at_ref("HEAD").unwrap();

// Branch isolation - switching back to main
store.checkout("main").unwrap();
let main_commits = store.get_commits(b"key1").unwrap(); // Returns 1 commit (no feature changes)

@zhangfengcdt zhangfengcdt merged commit e6414bd into main Jul 30, 2025
2 checks passed
@zhangfengcdt zhangfengcdt deleted the feature/core.git.trackKeys branch August 1, 2025 23:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant