Skip to content

fix(git): support git worktrees and harden plumbing operations - #76

Merged
JacksonFergusonDev merged 1 commit into
mainfrom
fix/git-worktrees-and-plumbing
Aug 22, 2026
Merged

fix(git): support git worktrees and harden plumbing operations#76
JacksonFergusonDev merged 1 commit into
mainfrom
fix/git-worktrees-and-plumbing

Conversation

@JacksonFergusonDev

Copy link
Copy Markdown
Owner

Summary

This PR addresses Git plumbing issues, worktree/submodule support, and edge-case reliability improvements (P1):

  1. Git Worktrees & Submodules Support: Added dynamic git_dir resolution via GitRepo.git_dir (resolving git rev-parse --git-dir) and helper functions. Previously, code assumed .git was always a directory, which broke when operating inside Git linked worktrees or submodules where .git is a pointer file.
  2. Synthetic Merge Parent Deduplication: In daemon.py, ensured commit_tree deduplicates parent SHAs so duplicate -p flags are not passed when HEAD matches local_backup_ref.
  3. Deterministic Push Change Detection: Replaced unix timestamp comparisons (current_local_ts > last_push_ts) with commit OID comparisons (local_oid != remote_oid) in daemon.py to reliably detect new commits regardless of timestamp collisions or clock skew.
  4. Finalize Conflict Exit Code: Updated finalize_work in ops.py to exit with status 1 instead of 0 when merge_squash fails due to merge conflicts.
  5. Pathspec Hardening: Added -- pathspec separator to GitRepo.status_porcelain to prevent option injection on paths starting with dashes.
  6. Documentation: Added worktree compatibility note under Zero-Interference in README.md.

Changes

  • src/git_pulsar/git_wrapper.py: Added git_dir property to GitRepo; added -- to status_porcelain.
  • src/git_pulsar/daemon.py: Added _get_git_dir helper; used it in temporary_index, is_repo_busy, _should_skip; deduplicated parents in run_backup; updated push phase to compare commit OIDs.
  • src/git_pulsar/ops.py: Added _get_git_dir helper for drift state paths; changed conflict exit code to 1 in finalize_work.
  • src/git_pulsar/cli.py: Added _get_git_dir helper for status, list, doctor, and pause checks.
  • README.md: Updated features list.
  • tests/test_git_wrapper.py: Added tests for worktree gitdir resolution and status_porcelain -- pathspec.
  • tests/test_daemon.py: Added tests for parent deduplication, OID push detection, and temporary index in worktrees.
  • tests/test_ops.py: Added test for finalize conflict exit code.

Verification

  • uv run pytest --cov passed (96 tests, 65.5% coverage).
  • bash scripts/test_distributed.sh passed.
  • uv run ruff check ., uv run ruff format --check ., and uv run mypy . passed cleanly.

- Add dynamic git_dir resolution via GitRepo.git_dir and helpers to support Git worktrees and submodules
- Prevent duplicate parent hashes from being passed to git commit-tree during synthetic merges
- Switch push change detection to deterministic commit OID comparisons (local_oid != remote_oid)
- Abort with exit code 1 when git pulsar finalize encounters merge conflicts
- Add '--' pathspec separator in GitRepo.status_porcelain to prevent flag injection
- Document worktree compatibility in README
- Add regression tests covering worktrees, parent deduplication, push triggers, and conflict aborts
@JacksonFergusonDev
JacksonFergusonDev merged commit c760560 into main Aug 22, 2026
7 checks passed
@JacksonFergusonDev
JacksonFergusonDev deleted the fix/git-worktrees-and-plumbing branch August 22, 2026 01:22
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