fix(git): support git worktrees and harden plumbing operations - #76
Merged
Conversation
- 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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR addresses Git plumbing issues, worktree/submodule support, and edge-case reliability improvements (P1):
git_dirresolution viaGitRepo.git_dir(resolvinggit rev-parse --git-dir) and helper functions. Previously, code assumed.gitwas always a directory, which broke when operating inside Git linked worktrees or submodules where.gitis a pointer file.daemon.py, ensuredcommit_treededuplicates parent SHAs so duplicate-pflags are not passed whenHEADmatcheslocal_backup_ref.current_local_ts > last_push_ts) with commit OID comparisons (local_oid != remote_oid) indaemon.pyto reliably detect new commits regardless of timestamp collisions or clock skew.finalize_workinops.pyto exit with status1instead of0whenmerge_squashfails due to merge conflicts.--pathspec separator toGitRepo.status_porcelainto prevent option injection on paths starting with dashes.README.md.Changes
src/git_pulsar/git_wrapper.py: Addedgit_dirproperty toGitRepo; added--tostatus_porcelain.src/git_pulsar/daemon.py: Added_get_git_dirhelper; used it intemporary_index,is_repo_busy,_should_skip; deduplicated parents inrun_backup; updated push phase to compare commit OIDs.src/git_pulsar/ops.py: Added_get_git_dirhelper for drift state paths; changed conflict exit code to 1 infinalize_work.src/git_pulsar/cli.py: Added_get_git_dirhelper for status, list, doctor, and pause checks.README.md: Updated features list.tests/test_git_wrapper.py: Added tests for worktree gitdir resolution andstatus_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 --covpassed (96 tests, 65.5% coverage).bash scripts/test_distributed.shpassed.uv run ruff check .,uv run ruff format --check ., anduv run mypy .passed cleanly.