Skip to content

Feature: Allow git to work even when in a repo subdir#87

Open
jeff-phil wants to merge 2 commits into
cjermain:mainfrom
jeff-phil:main
Open

Feature: Allow git to work even when in a repo subdir#87
jeff-phil wants to merge 2 commits into
cjermain:mainfrom
jeff-phil:main

Conversation

@jeff-phil
Copy link
Copy Markdown
Contributor

When in a sub-directory of a repo when start pi, then no git commands work for that repo. This means that pi agents cannot see the history, status, etc. to help make set better context.

The reason this happens is because the .git folder will be in a sub-directory, or for some worktrees completely different directory structure. And when pi-less-yolo starts in subdirectory the .git folder and other files not in current working directory will not be mounted.

As an example from below tree, if pi-less-yolo is kicked off from /my-project/src/somedir, then git will not work. If started from /my-project then git will work.

/my-project 
+ -- .git 
+ -- src 
++ -- somedir 

And if started from a worktree of my-project in a separate directory, the /my-project/.git is also needed because that is where the git data is stored.

This PR discovers if pi-less-yolo was started in a git repo, and discovers the common git data dir, maps that into /git-data, and sets environment variable to tell git to look there for the git data. It follows the same PI_WORKDIR_RO rules that the user selects.

Then if the user does not start in the worktree dir, then the full worktree dir is volume mapped into the container - but always READONLY. Without the rest of the repo directories, things like git status will make it look like all the files were deleted, and this solves for that by having the files visible now.

@jeff-phil jeff-phil changed the title Feat: Allow git to work even when in a repo subdir Feature: Allow git to work even when in a repo subdir May 5, 2026
@cjermain
Copy link
Copy Markdown
Owner

Thanks @jeff-phil for adding this capability. Here are a few revisions that I think will make this improvement better aligned with the pi-less-yolo approach:

  1. Opt-in guard -- making it explicit with PI_PARENT_GIT_MOUNT
  2. Avoid shadowing the GIT_DIR and GIT_WORK_TREE variables
  3. Always use read-only -- the parent git repo can be used as a working directory if writes are needed
  4. ($pwd -P) resolves symlinks before comparing
# PI_PARENT_GIT_MOUNT=1: mount the repo's common .git dir when pi is launched
# from a subdirectory or a separate worktree. Sets GIT_DIR and GIT_WORK_TREE
# inside the container so git commands work correctly. The .git dir is always
# mounted read-only. If you need the agent to commit, it should do so through
# the working-tree path.
if [[ -n "${PI_PARENT_GIT_MOUNT:-}" ]]; then
  _pi_git_common_dir="$(git rev-parse --path-format=absolute --git-common-dir 2>/dev/null || true)"
  _pi_git_work_tree="$(git rev-parse --show-toplevel 2>/dev/null || true)"
  if [[ -n "${_pi_git_common_dir}" ]]; then
    DOCKER_FLAGS+=(
      "--volume" "${_pi_git_common_dir}:/git-data:ro"
      "--env" "GIT_DIR=/git-data"
      "--env" "GIT_WORK_TREE=${_pi_git_work_tree}"
    )
    # Mount the worktree root read-only only when it isn't already covered by
    # the primary $(pwd):$(pwd) mount — i.e. launching from a subdirectory or
    # a linked worktree whose root differs from the working directory.
    if [[ "$(pwd -P)" != "${_pi_git_work_tree}" ]]; then
      DOCKER_FLAGS+=(
        "--volume" "${_pi_git_work_tree}:${_pi_git_work_tree}:ro"
      )
    fi
  fi
fi

What do you think?

@jeff-phil
Copy link
Copy Markdown
Contributor Author

This part:

If you need the agent to commit, it should do so through the working-tree path.

won't work like maybe you are thinking. When GIT_DIR is mounted read-only, the agent will not be able to commit (or add, revert, checkout, etc.) since GIT_DIR holds all the git data for any working-tree path. The git repo root always hold all the data in .git dir, and the worktree just has a pointer file back to repo root.

For example:

~/all-projects/
 ├── my-project/   # Git root
           ├── .git/     # A _directory_ that contains all repo data, branches, objects
           ├── src/
 ├── my-project-feature/   # Git worktree of ~/all-projects/my-project/ 
           ├── .git        # A _file_ that points back to ~/all-projects/my-project/.git for git data
           ├── src/

If you start pi-less-yolo in ~/all-projects/my-project-feature/ directory then you will still not be able to commit, add files, revert files, checkouts, etc. because ~/all-projects/my-project/.git/ is mounted to /git-data/ as read-only.

What i was looking to adjust was when pi-less-yolo is started in a worktree or subdirectory of a git branch or worktree, then you still have access to a working repo... unless you used the pi:readonly task.

Everything else i agree with, just this line always making GIT_DIR=/git-data read-only isn't a good change IMHO:

"--volume" "${_pi_git_common_dir}:/git-data:ro"

Please let me know if i am explaining it okay. I had to go through a dozens of test iterations to get this right in my head of what worked and what didn't work, and then implement it for this PR.

Appreciate your looking at this!

@jeff-phil
Copy link
Copy Markdown
Contributor Author

I made some changes but kept /git-data mounted r/w unless _PI_WORKDIR_RO is set, since git won't work if read-only.

Hope you agree and are good.

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.

2 participants