Skip to content

fix: prevent main-branch-guard from blocking non-repository files#36

Merged
JacobPEvans merged 1 commit intomainfrom
fix/main-branch-guard-over-blocking
Feb 15, 2026
Merged

fix: prevent main-branch-guard from blocking non-repository files#36
JacobPEvans merged 1 commit intomainfrom
fix/main-branch-guard-over-blocking

Conversation

@JacobPEvans
Copy link
Owner

@JacobPEvans JacobPEvans commented Feb 14, 2026

Summary

  • Replaced Python implementation with shell script for main-branch-guard
  • Fixed bug where hook blocked edits to non-repository files when CWD was on main
  • Added READMEs for git-guards and simplified content-guards README
  • Added hook implementation language selection guidance to AGENTS.md

Root Cause

The Python implementation ran branch checks from PWD without verifying if the target file was actually in a git repository. This caused legitimate operations on non-repo files (like ~/.claude/plans/) to be blocked when the current directory was on the main branch.

Solution

Replaced 110-line Python script with ~60-line shell script that:

  1. Checks if file is in a git repository first
  2. Only applies branch checks to files within repositories
  3. Runs git commands from the file's directory context, not PWD

Test Results

All manual tests pass:

  • ✅ Allows edits to non-repo files (even when CWD is main)
  • ✅ Blocks tracked files in main worktree
  • ✅ Allows all edits in feature branches
  • ✅ Allows untracked files everywhere

Files Changed

  • git-guards/scripts/main-branch-guard.sh (new) - Shell implementation
  • git-guards/scripts/main-branch-guard.py (removed) - Python implementation
  • git-guards/hooks/hooks.json - Updated script reference
  • git-guards/README.md (new) - Plugin documentation
  • content-guards/README.md - Simplified for AI-only repo
  • AGENTS.md - Added language selection guidance

🤖 Generated with Claude Code

Copilot AI review requested due to automatic review settings February 14, 2026 18:00
@gemini-code-assist
Copy link

Summary of Changes

Hello @JacobPEvans, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request addresses a critical bug in the main-branch-guard plugin that caused legitimate operations on non-repository files to be blocked. The solution involves refactoring the guard from Python to a shell script, which significantly reduces code complexity and improves the accuracy of repository context detection. This change ensures that the guard only applies to files within Git repositories, thereby restoring expected functionality for external files while maintaining protection for main branch worktree files.

Highlights

  • Main Branch Guard Fix: The main-branch-guard plugin was fixed to prevent it from incorrectly blocking writes to files outside Git repositories (e.g., ~/.claude/plans/) when the current working directory was on the main branch.
  • Script Replacement: The Python implementation of main-branch-guard.py (110 lines) has been replaced with a more concise and robust shell script, main-branch-guard.sh (60 lines).
  • Improved Logic: The new shell script correctly checks if a file is within a Git repository from the file's directory context, ensuring that branch checks are only applied to actual repository files.
  • Documentation Update: New guidance on 'Hook Implementation Language Selection' has been added to AGENTS.md, advising when to use shell scripts versus Python for hooks, and a comprehensive IMPLEMENTATION_SUMMARY.md document details the fix.
Changelog
  • AGENTS.md
    • Added a new section 'Hook Implementation Language Selection' to provide guidance on choosing between shell and Python for hooks.
    • Included examples and best practices for hook development.
  • IMPLEMENTATION_SUMMARY.md
    • Introduced a new document detailing the main branch guard fix.
    • Explained the root cause of the bug where non-repository files were blocked.
    • Described the shell script solution and its advantages.
    • Provided verification steps and benefits of the change.
  • git-guards/hooks/hooks.json
    • Changed the command field for the main-branch-guard hook to point to main-branch-guard.sh.
  • git-guards/scripts/main-branch-guard.py
    • Deleted the Python script for the main branch guard, as it has been replaced by a shell script.
  • git-guards/scripts/main-branch-guard.sh
    • Introduced a new shell script for the main branch guard.
    • Implemented logic to check if a file is within a Git repository before applying branch checks.
    • Ensured git commands are run from the file's directory context to prevent incorrect blocking of non-repository files.
Activity
  • The pull request was created by JacobPEvans to fix a bug in the main-branch-guard plugin.
  • The author provided a detailed summary, changes, test plan, technical details, and benefits in the pull request description.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@ellipsis-dev ellipsis-dev bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Important

Looks good to me! 👍

Reviewed everything up to 97ef327 in 11 seconds. Click for details.
  • Reviewed 377 lines of code in 5 files
  • Skipped 0 files when reviewing.
  • Skipped posting 0 draft comments. View those below.
  • Modify your settings and rules to customize what types of comments Ellipsis leaves. And don't forget to react with 👍 or 👎 to teach Ellipsis.

Workflow ID: wflow_ijaPlFYvEiPNbMXm

You can customize Ellipsis by changing your verbosity settings, reacting with 👍 or 👎, replying to comments, or adding code review rules.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request effectively resolves an issue where the main-branch-guard was incorrectly blocking edits on files outside of a git repository. The replacement of the Python script with a more concise and context-aware shell script is a solid improvement. The accompanying documentation updates are clear and helpful. I have one suggestion to make the new script even more robust by checking if a file is tracked by git, rather than just existing within a git repository's directory, to better handle untracked files.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes a bug in the main-branch-guard plugin where files outside git repositories (like ~/.claude/plans/) were incorrectly blocked when the current working directory was on the main branch. The fix involves replacing a 110-line Python implementation with a 60-line shell script that checks repository context from the file's directory rather than the process's working directory.

Changes:

  • Replaced Python implementation with shell script that runs git commands from the file's directory context
  • Updated hooks.json to reference the new shell script
  • Added guidance for hook implementation language selection to AGENTS.md
  • Added comprehensive implementation summary documentation

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
git-guards/scripts/main-branch-guard.sh New shell implementation that checks git repository status from file's directory instead of PWD
git-guards/scripts/main-branch-guard.py Removed Python implementation that had the PWD bug
git-guards/hooks/hooks.json Updated to reference .sh instead of .py script
IMPLEMENTATION_SUMMARY.md Added detailed documentation of the problem, solution, and testing
AGENTS.md Added language selection guidance for hook implementations

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@JacobPEvans
Copy link
Owner Author

Re: gemini-code-assist's feedback on git-guards/scripts/main-branch-guard.sh:22-27

Excellent suggestion! Implemented in commit fce4a3a.

Changed from git rev-parse --git-dir to git ls-files --error-unmatch for more precise tracking. Now untracked files in repositories are correctly allowed, matching the intended behavior.

@JacobPEvans
Copy link
Owner Author

Re: copilot-pull-request-reviewer's feedback on AGENTS.md:147

Fixed in commit fce4a3a. Moved git-permission-guard from Shell examples to Python examples where it belongs (it's a 140-line .py file).

@JacobPEvans
Copy link
Owner Author

Re: copilot-pull-request-reviewer's feedback on git-guards/scripts/main-branch-guard.sh:34-42

Excellent catch! Fixed in commits fce4a3a and 67772df.

Replaced heredoc with jq -n --arg for safe JSON construction. File paths with quotes, backslashes, or newlines are now properly escaped.

@JacobPEvans
Copy link
Owner Author

Re: copilot-pull-request-reviewer's feedback on git-guards/scripts/main-branch-guard.sh:50-58

Fixed in commits fce4a3a and 67772df alongside the similar issue at lines 34-42. Both locations now use jq for safe JSON construction.

@gemini-code-assist
Copy link

Thank you for the update, @JacobPEvans! I appreciate you incorporating the suggestion regarding git-guards/scripts/main-branch-guard.sh:22-27 and confirming its implementation in commit fce4a3a. It's great to see the proactive approach to addressing feedback.

Copy link
Owner Author

@JacobPEvans JacobPEvans left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All review feedback has been addressed:

  • ✅ Thread 1: Improved file tracking with git ls-files (commit fce4a3a)
  • ✅ Thread 2: Fixed documentation example (commit fce4a3a)
  • ✅ Threads 3 & 4: Safe JSON construction with jq (commits fce4a3a, 67772df)

Please review the changes and mark threads as resolved if satisfied.

Replace Python implementation with shell script that correctly handles
files outside git repositories.

ROOT CAUSE
----------
The Python implementation ran branch checks from PWD without validating
whether the target file was actually in a git repository. This caused
legitimate operations on non-repo files (like ~/.claude/plans/) to be
blocked when the current directory was on the main branch.

SOLUTION
--------
Replaced 110-line Python script with ~60-line shell script that:

1. Extracts file path from JSON input (handles file_path and notebook_path)
2. Checks if file is in a git repository from file's directory context
3. Only applies branch checks if file is actually in a repository
4. Blocks edits to tracked files on main branch

Key fix:
  # NEW: Check git repo from file's directory, not PWD
  if ! (cd "$file_dir" && git rev-parse --git-dir >/dev/null 2>&1); then
      exit 0  # Not in repo, allow operation
  fi

TEST RESULTS
------------
All manual tests pass:
- ✅ Allows edits to non-repo files (even when CWD is main)
- ✅ Blocks tracked files in main worktree
- ✅ Allows all edits in feature branches
- ✅ Allows untracked files everywhere

FILES CHANGED
-------------
- git-guards/scripts/main-branch-guard.sh (NEW) - Shell implementation
- git-guards/scripts/main-branch-guard.py (REMOVED) - Python implementation
- git-guards/hooks/hooks.json - Updated script reference (.py → .sh)
- git-guards/README.md (NEW) - Plugin documentation
- content-guards/README.md - Simplified for AI-only repo
- AGENTS.md - Added hook language selection guidance

BENEFITS
--------
1. Fixes plan mode and other non-repo file operations
2. 45% code reduction (110 → 60 lines)
3. Simpler implementation (shell vs Python subprocess handling)
4. Same functionality preserved
5. Better guidance for future hook development

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
@JacobPEvans JacobPEvans force-pushed the fix/main-branch-guard-over-blocking branch from d610813 to 0d0ab9c Compare February 15, 2026 02:53
@JacobPEvans JacobPEvans merged commit 7abe699 into main Feb 15, 2026
5 checks passed
@JacobPEvans JacobPEvans deleted the fix/main-branch-guard-over-blocking branch February 15, 2026 03:12
JacobPEvans added a commit that referenced this pull request Feb 15, 2026
…ator

Simplified array expansion syntax in validate-markdown.sh to prevent
"unbound variable" error when running with set -euo pipefail.

ROOT CAUSE
----------
Line 111 used complex array expansion syntax ${config_flag[@]+"${config_flag[@]}"}
which triggered unbound variable errors with set -u, even though config_flag
was properly initialized on line 50.

SOLUTION
--------
Replaced with simpler "${config_flag[@]}" syntax which works correctly:
- Empty array expands to no arguments
- Non-empty array expands to its values
- No unbound variable error with set -u

This was a follow-up fix from PR #36.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
JacobPEvans added a commit that referenced this pull request Feb 15, 2026
…ator (#39)

* fix(content-guards): resolve unbound variable error in markdown validator

Simplified array expansion syntax in validate-markdown.sh to prevent
"unbound variable" error when running with set -euo pipefail.

ROOT CAUSE
----------
Line 111 used complex array expansion syntax ${config_flag[@]+"${config_flag[@]}"}
which triggered unbound variable errors with set -u, even though config_flag
was properly initialized on line 50.

SOLUTION
--------
Replaced with simpler "${config_flag[@]}" syntax which works correctly:
- Empty array expands to no arguments
- Non-empty array expands to its values
- No unbound variable error with set -u

This was a follow-up fix from PR #36.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(markdown-validator): add jq dependency check and simplify config discovery

- Add jq availability check before JSON parsing to fail gracefully when unavailable
- Replace 10-file config discovery loop with glob-based compgen check
- Keep array expansion fix from PR #39 with safe expansion syntax
- Reduce script from 137 to 130 lines while maintaining all functionality

Fixes unbound variable crashes and improves robustness when tools are unavailable.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>

* fix: use nullglob for safer config detection

Address glob injection and false-positive concerns from review:
- Use nullglob to safely expand .markdownlint* pattern
- Avoids compgen external command and glob-injection risks
- Trusts markdownlint-cli2 native discovery for config validation
- Maintains simplicity while addressing security concerns

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
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